๐ŸŒฑ ์ธํ”„๋Ÿฐ/โš“ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์–ด๋‚˜๋” ํด๋ž˜์Šค (์ง€์ƒํŽธ)

(14) Helm๊ณผ Kustomize ๋น„๊ตํ•˜๋ฉฐ ์‚ฌ์šฉ-2

mallin 2025. 6. 24. 02:19

โš“ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์–ด๋‚˜๋” ํด๋ž˜์Šค (์ง€์ƒํŽธ) - Spring 1, 2 ์„ ๋“ฃ๊ณ  ์ž‘์„ฑํ•˜๋Š” ๋ณต์Šต ๋ธ”๋กœ๊ทธ ์ž…๋‹ˆ๋‹ค.

 

ํŒจํ‚ค์ง€ ๊ตฌ์กฐ ๋น„๊ต ๋ฐ ๋ฐฐํฌํ•˜๊ธฐ

1. ๋‹ค์–‘ํ•œ ๋ฐฐํฌ ํ™˜๊ฒฝ์„ ์œ„ํ•œ Kustomize ๋ฐฐํฌํ•˜๊ธฐ

 

1-1. ์•„์ดํ…œ ์ƒ์„ฑ

  • name : 2222-deploy-kustomize
  • copy from 2221-deploy-helm

1-2. ์˜ต์…˜ ์ˆ˜์ •

  • Spare Checkout paths > Path : 2222
  • Script Path : 2222/Jekinsfile

1-3. ๋ฐฐํฌ ์‹œ์ž‘์—์„œ Abort ๋ˆ„๋ฅด๊ธฐ

  • ์ตœ์ดˆ ์‹คํ–‰์‹œ์—” ๋งค๊ฐœ๋ณ€์ˆ˜ ์ž…๋ ฅ ๋ฒ„ํŠผ์ด ์•ˆ๋‚˜์˜ค๊ณ , [dev / qa / prod] ์ค‘ dev๊ฐ€ ์ ์šฉ๋œ๋‹ค
  • ์Šคํฌ๋ฆฝํŠธ์— ์žˆ๋Š”๋ฐ ์ฒ˜์Œ์— ์‹คํ–‰ํ•  ๋•Œ๋Š” ์  ํ‚จ์Šค ํŒŒ์ดํ”„๋ผ์ธ์ด ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ƒฅ dev๋กœ ์ ์šฉ

1-3-2. ๋‹ค์‹œ ๋นŒ๋“œํ•˜๋ฉด PROFILE ์„ ์„ ํƒํ•ด์„œ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค

 

  • ๊ตฌ์„ฑ์— ๋“ค์–ด๊ฐ€์„œ ๋ณด๋ฉด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ง€์ •๋˜์–ด ์žˆ๋‹ค

1-3-3. Stage View

 

1-4. ๋””๋ ‰ํ† ๋ฆฌ ์„ค๋ช…

 

2. ๋‹ค์–‘ํ•œ ๋ฐฐํฌ ํ™˜๊ฒฝ์„ ์œ„ํ•œ Helm ๋ฐฐํฌํ•˜๊ธฐ

1-1. ์•„์ดํ…œ ์ƒ์„ฑ

  • name : 2223-deploy-helm
  • copy from 2222-deploy-kustomize

1-2. ์˜ต์…˜ ์ˆ˜์ •

  • Spare Checkout paths > Path : 2223
  • Script Path : 2223/Jekinsfile

2. ๋ฐฐํฌํ•˜๊ธฐ

  • ์ด์ „ ์•„์ดํ…œ์„ ๋ณต์‚ฌํ•ด์™”๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐํฌ ํ™˜๊ฒฝ์ด ๋ฏธ๋ฆฌ ๋“ค์–ด์žˆ๋‹ค

 

3. ์ฝ”๋“œ ํ™•์ธ

stage('ํ—ฌ๋ฆ„ ํ…œํ”Œ๋ฆฟ ํ™•์ธ') {
    steps {
        // K8S ๋ฐฐํฌ
        sh "helm template api-tester-${CLASS_NUM} ./${CLASS_NUM}/deploy/helm/api-tester" +
           " -f ./${CLASS_NUM}/deploy/helm/api-tester/values-${params.PROFILE}.yaml -n anotherclass-222-${params.PROFILE}"
        // --set replicaCount='3' --set port='80' --set profile='dev' --set nodeport='32223'
    }
}

stage('ํ—ฌ๋ฆ„ ๋ฐฐํฌ') {
    steps {
        input message: '๋ฐฐํฌ ์‹œ์ž‘', ok: "Yes"
        sh "kubectl apply -f ./${CLASS_NUM}/deploy/kubectl/namespace-${params.PROFILE}.yaml"
        sh "helm upgrade api-tester-${CLASS_NUM} ./${CLASS_NUM}/deploy/helm/api-tester" +
           " -f ./${CLASS_NUM}/deploy/helm/api-tester/values-${params.PROFILE}.yaml" +
           " -n anotherclass-222-${params.PROFILE} --install"  //  --create-namespace
    }
}
  • values ํŒŒ์ผ์— dev ๋ฅผ ๋ถ™์—ฌ์„œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ค€๋‹ค
  • ํ…œํ”Œ๋ฆฟ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜๋“ค์€ values ํŒŒ์ผ์— ์ €์žฅํ•˜๊ณ , ๊ฐ’์„ ๋’ค์ง‘์–ด ์“ด๋‹ค
  • set ์˜ต์…˜์„ ์ฃผ๋ฉด ์ตœ์ข…์ ์œผ๋กœ ๋ฐ˜์˜๋˜๋Š” ๋ณ€์ˆ˜
  • helm ๋ฐฐํฌ์—๋Š” namespace ๋ฅผ ๋ฐ˜์˜์‹œํ‚ค๋Š”๊ฒŒ ์ข‹์ง€ ์•Š์•„์„œ ๋”ฐ๋กœ ๋ถ„๋ฆฌ

 

๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ• ํ›„ ๋งˆ์ฃผํ•˜๊ฒŒ ๋˜๋Š” ๊ณ ๋ฏผ๋“ค

์ค‘์š” ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” ๊ด€๋ฆฌ

  • ์  ํ‚จ์Šค๊ฐ€ ์ปจํ…Œ์ด๋„ˆ ๋นŒ๋“œ๋ฅผ ํ†ตํ•ด์„œ dockerhub๋กœ ์—…๋กœ๋“œ๋„ ํ•˜๊ณ  helm ๋ฐฐํฌ๋„ ํ•œ๋‹ค
  • dockerhub ์— ์—…๋กœ๋“œ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ config.json ํŒŒ์ผ์ด ์ƒ์„ฑ
    • ์•”ํ˜ธํ™”๊ฐ€ ์•ˆ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค

Jenkins ์— Credential ๋กœ ๋“ฑ๋ก

  • ์ธ์ฆ์„œ๋ฅผ ์•”ํ˜ธํ™”ํ•œ ์ƒํƒœ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋ฐฐํฌ์‹œ๋งˆ๋‹ค ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค
  • ๋กœ๊ทธ์•„์›ƒ์‹œ ์ ‘์† ์ •๋ณด ์‚ญ์ œ
  • docker-credential-helpers : ์•”ํ˜ธํ™” ์ œ๊ณต
  • Dashboard > Jenkins ๊ด€๋ฆฌ > Credentials > System > Global credentials (unrestricted) ์—์„œ [Add Credentials]
  • kind : Username with password (๋„์ปค ํ—ˆ๋ธŒ ๋กœ๊ทธ์ธ ํŒจ์Šค์›Œ๋“œ ์ž…๋ ฅ)
  • Kind : Secret file (์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ ์ ‘๊ทผ ์ธ์ฆ์„œ)

 

์—…๋กœ๋“œ ํ›„ CI/CD Server ์— ๋งŒ๋“ค์–ด์ง„ ์ด๋ฏธ์ง€ ์‚ญ์ œ

  • ์ปจํ…Œ์ด๋„ˆ ๋นŒ๋“œ๋ฅผ ํ•˜๋‹ค๋ณด๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ๊ณ„์† ์ƒ๊ธด๋‹ค
  • ์šฉ๋Ÿ‰์„ ๋งŽ์ด ์ฐจ์ง€ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ์‚ญ์ œํ•ด์ค˜์•ผ ํ•œ๋‹ค
  • ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ ์‚ฌ์šฉ ์•ˆํ•˜๋Š” ์ด๋ฏธ์ง€๋Š” ์ž๋™ ์‚ญ์ œํ•ด์ค€๋‹ค
stage('์ปจํ…Œ์ด๋„ˆ ๋นŒ๋“œ ๋ฐ ์—…๋กœ๋“œ') {
  steps {
	script{
	  // ๋„์ปค ๋นŒ๋“œ
      sh "docker build ./${CLASS_NUM}/build/docker -t ${DOCKERHUB_USERNAME}/api-tester:${TAG}"
      sh "docker push ${DOCKERHUB_USERNAME}/api-tester:${TAG}"
      sh "docker rmi ${DOCKERHUB_USERNAME}/api-tester:${TAG}"   // ์ด๋ฏธ์ง€ ์‚ญ์ œ

 

๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ฐฐํฌ์™€ ๋ณ„๋„๋กœ ๊ด€๋ฆฌ

  • ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ์•ฑ๊ณผ ๋ณ„๋„๋กœ ๊ด€๋ฆฌ๋ฅผ ํ•ด์ฃผ๋Š”๊ฒŒ ์ข‹๋‹ค
stage('๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ƒ์„ฑ') {  // ๋ฐฐํฌ์‹œ apply๋กœ Namespace ์ƒ์„ฑ or ๋ฐฐํฌ์™€ ๋ณ„๊ฐœ๋กœ ๋ฏธ๋ฆฌ ์ƒ์„ฑ (์ถ”ํ›„ ์‚ญ์ œ์‹œ ๋ณ„๋„ ์‚ญ์ œ)
  steps {
    withCredentials([file(credentialsId: 'k8s_master_config', variable: 'KUBECONFIG')]) {
      sh "kubectl apply -f ./2224/deploy/kubectl/namespace-dev.yaml --kubeconfig " + '"${KUBECONFIG}"'
...
stage('ํ—ฌ๋ฆ„ ๋ฐฐํฌ') {
  steps {

 

Helm ๋ถ€๊ฐ€๊ธฐ๋Šฅ

  • pod ๊ฐ€ ์™„์ „ํžˆ ๊ธฐ๋™๋๋Š”์ง€ ์ฒดํฌ ํ•„์š”
    • helm command —wait
  • ๋ฐฐํฌํ•ด๋„ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ์ง„ํ–‰๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
    • metadata.annotaions : ์ƒˆ ๋ฐฐํฌ ์‹œ ๋งˆ๋‹ค ๋žœ๋ค๊ฐ’์„ ์ƒ์„ฑ
    • ๊ทธ๋ž˜์„œ ๋ฐฐํฌ์‹œ๋งˆ๋‹ค ์ƒˆ ๋žœ๋ค๊ฐ’์ด ์ƒ์„ฑ๋˜์–ด์„œ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ์ง„ํ–‰

 

์ด๋ฏธ์ง€ ํƒœ๊ทธ

  • api-tester:v1.0.1
    • ๋ฒ„์ „ ๊ทœ์น™์ƒ v๋ฅผ ๋นผ๋Š”๊ฒŒ ๋งž๋‹ค
  • ๊ฐœ๋ฐœํ™˜๊ฒฝ (์žฆ์€๋ฐฐํฌ, ๋ฒ„์ €๋‹ ๋ฌด์˜๋ฏธ)
    • image: api-tester:latest
    • pullPolicy: Always (ํ•ญ์ƒ hub์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ด)
    • ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด ์ด์ „๋ฒ„์ „์œผ๋กœ ๋Œ๋ ค๋‹ฌ๋ผ๊ณ  ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ ์œ„์ฒ˜๋Ÿผ ๋ฒ„์ €๋‹์„ ํ•˜๋ฉด ์–ด๋ ต๋‹ค
    • image: api-tester:1.0.1-202312.181512 (๋ฐฐํฌ ์‹œ๋งˆ๋‹ค ์ƒˆ ํƒœ๊ทธ ๋‹ฌ๊ธฐ, ๋‚ ์งœ / Git์ปค๋ฐ‹ No / Jenkins ๋นŒ๋“œ seq)
    • pullPolicy: ifNotPresent
  • ๊ฒ€์ฆํ™˜๊ฒฝ / ์šด์˜ํ™˜๊ฒฝ (๊ณ„ํš๋œ ๋ฐฐํฌ, ๋ฒ„์ €๋‹ ํ•„์ˆ˜)
    • image : api-tester:1.0.1
    • pullPolicy: IfNotPresent (Node์— ํ•ด๋‹น ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ๊ฑธ ๋จผ์ € ์‚ฌ์šฉํ•˜๊ณ , ์—†์œผ๋ฉด hub ํ™•์ธ)