[Kubernetes] Deploy Tool 2(Feat.ArgoCD)

[Kubernetes] Deploy Tool 2(Feat.ArgoCD)

안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 필자가 속한 프로젝트에서 ArgoCD를 도입한 이후에 어떠한 방식으로 배포를 진행하려 하는지 정리해보는 시간을 갖도록 하겠습니다.

우선 필자의 프로젝트에서는 Apache, Nginx, WAS 로 이어지는 서비스 흐름이 있습니다.

여기서 Apache, Nginx를 Image로 만들고, POD로 감싸서 배포를 진행하고 있습니다.

지난 글들은 아래를 참고 해주시면 됩니다.

1. 배포 구성

필자의 프로젝트에서는 gitlab을 원격 저장소로 사용하고 있습니다. gitlab에는 helmchart/dockerimage를 위한 소스들이 구성되어있습니다.

jenkins는 source를 pull받아 빌드를 수행합니다. 위의 이야기했던 dockerfile을 통해서 docker image build를 수행합니다. 결과물을 ECR로 업로드 합니다.

slack은 중간에서 명령을 수행하고 결과에 대한 noti를 받을 수 있는 채널입니다.

구성은 다음과 같습니다.

gitlab에서 관리되는 2가지 파일들에 의해서 관리됩니다.

  • apache/nginx dockerfile + configfile
  • helmchart

docker image를 위한 dockerfile 이 있을 것이고, k8s 배포를 위한 helmchart가 있을 것입니다.

2. jenkins 빌드 시, gitlab commit/push

먼저 CI에 대해서 정리를 해보도록 하겠습니다. argoCD자체가 gitOps라는 개념을 통해서 git과의 sync를 지속적으로 보장합니다. 그렇기 때문에 helmchart를 git에 잘 commit에두고 갖고 있으면, argoCD에서는 synchronizing을 통해서 배포가 가능합니다.

필자가 속한 프로젝트에서는 k8s cluster를 AP/EU/US 지역에 각각 셋팅해 두었습니다. 글로벌 지역으로 서비스를 하다보니 어쩔수 없이 3개의 region을 사용합니다.

그러면 자연스럽게 argoCD를 3개를 띄워야 하고, HelmChart도 3개를 쪼개서 나눠 놨습니다.

만약 CI/CD가 나뉘어있다면, CI에서는 각 리전별로 이미지를 생성했어야했습니다.

  • ap/eu/us image 제각각 빌드 수행
  • helmchart values.yml 파일에서 image 변경
  • ap/eu/us argocd 제각각 sync

그런데, 문득 드는 생각이 사실 region만 나뉘어져있는 것이지, 사실 안의 내용물은 크게 다른바가 없습니다.

다른 부분을 짚어 보자면, apache에서 사용하는 내부 config파일에서 ALB 방향만 다르게 셋팅되어있었습니다.

그래서 이부분을 helm의 configmap으로 빼두기로 했습니다.

  • configmap 작성
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-dev-web
  namespace: dev-web
data:
  ALB_HOSTNAME: internal-ALB-P6-DEV-AEM-AUTHOR-internal-1602711296.ap-northeast-2.elb.amazonaws.com
  • apache dispatcher.any 파일
    /renders
      {
      /rend01
        {
        # Hostname or IP of the render
        /hostname "${ALB_HOSTNAME}"
        # Port of the render
        /port "80"
        # Connect timeout in milliseconds, 0 to wait indefinitely
        # /timeout "0"
        }
      }

configmap으로 빼두게 되면, 이미지는 1개를 공통으로 생성하면 되고, helm chart에서는 각기 다른 configmap이 생성이 됩니다.

즉, 공통의 이미지 안에 변경되는 부분만 configmap을 써서 배포를 하는 내용입니다.

  • jenkins 빌드 수행 시 각 region별 helmchart 수정
#1. 이동 
cd /home/jenkins/agent/workspace

#2. clone
git clone 'http://root:!tmdRl11@a5bab061231bb11ea80df0ac4e7df95d-290368675.ap-northeast-2.elb.amazonaws.com/root/helmcharts.git'

sleep 10

#3. 치환
sed -i "s/^  httpd:.*/  httpd: DEV_AP_AUTHOR_Httpd_${BUILD_TIMESTAMP}/g" /home/jenkins/agent/workspace/helmcharts/DEV_AUTHOR_Web/values.yaml
sed -i "s/^  httpd:.*/  httpd: DEV_US_AUTHOR_Httpd_${BUILD_TIMESTAMP}/g" /home/jenkins/agent/workspace/helmcharts/DEV_AUTHOR_US_Web/values.yaml

sleep 5

#4. commit
cd /home/jenkins/agent/workspace/helmcharts
git add .

#5. global setting
git config --global user.email "ssdc.cloud@samsung.com"
git config --global user.name "root"
git commit -m "commit from jenkins"
sleep 5

#6. push 
git push origin master

결국에는 빌드 된 이미지를 values.yml 파일에 셋팅 후, commit push하는 내용입니다.

이렇게 되면, 1개의 이미지 빌드 수행시, 같은 이미지 버전으로 AP/EU/US 를 모두 수정한 뒤, push할 수 있습니다.

3. argocd cli를 통한 sync

위에서 1개의 이미지 빌드 수행 후, 3개의 region에 helmchart -> values.yml 파일 수정까지 완료 되었습니다.

그렇게 되면, argocd에서는 변경점을 인지하고 OutOfSync상태가 될 것입니다.

우선, cli를 통해서 배포를 진행하는것을 생각해보았습니다. 왜냐하면 나중에 slack bot하고 연계해야 하기 떄문에 명령으로 만들어두기로 했습니다.

argocd cli는 초기 설치할때, 같이 설치했는데, 생각보다 간단합니다. argocd에서 생성했던 application명만 지정해서 sync명령으로 배포가 가능합니다.

#로그인
$ argocd login a5ff9f702a0a111eab2a802eeaf2c0e1-254247137.ap-northeast-2.elb.amazonaws.com

Username: admin
Password: 
'admin' logged in successfully
Context 'a5ff9f702a0a111eab2a802eeaf2c0e1-254247137.ap-northeast-2.elb.amazonaws.com' updated

#sync 명령
$ argocd app sync dev-author-web

이렇게하면, 정상적으로 sync상태가 될 것이고, cluster내로 배포가 되었습니다.

4. notification 셋팅 방법

배포까지는 정상적으로 되었는데, 따로 noti를 받지 못하니, 정상적으로 배포가 된것인지 아닌지를 알 수가 없었습니다. 필자는 서두에 말했듯이 slack을 명령/결과에 대한수행을 할 수 있도록 배치를 한다고 했습니다.

그래서 slack 채널에서 noti를 받으면, 훨씬 편할 것이라고 생각했습니다.

4-1. slack notification 설정

#argocd-notification 설정
$kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/stable/manifests/install.yaml

#secret 설정
$kubectl apply  -n argocd  -f - << EOF 
apiVersion: v1 
kind: Secret 
metadata:   
  name: argocd-notifications-secret 
stringData:   
  notifiers.yaml: |     
    slack:       
      token: xoxp-837765922164-838230107360-853808893522-41bf4ac3d793a70a0b4cf89a6b0783d4
type: Opaque 
EOF


#configmap 설정
$kubectl apply  -n argocd  -f - << EOF 
apiVersion: v1 
kind: ConfigMap 
metadata:   
  name: argocd-notifications-cm 
data:   
  config.yaml: |     
    triggers:
      - name: my-custom-trigger
        condition: app.status.sync.status == 'Synced'
        template: my-custom-template
        enabled: true
    templates:
      - name: my-custom-template
        title: Application {{.app.metadata.name}} sync status is {{.app.status.sync.status}}
        body: |
          Application {{.app.metadata.name}} sync is {{.app.status.sync.status}}.
          Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}.
        slack:
          attachments: |
            [{
              "title": "{{.app.metadata.name}}",
              "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
              "color": "#18be52",
              "fields": [{
              "title": "Sync Status",
              "value": "{{.app.status.sync.status}}",
              "short": true
              }]
            }]
EOF


#argocd notification app목록 추출
$kubectl get app -n argocd 

#app patch
kubectl patch app dev-author-web -n argocd -p '{"metadata":{"annotations":{"recipients.argocd-notifications.argoproj.io":"slack:team-system1"}}}' --type merge

이렇게 셋팅을 한 뒤, app sync를 수행하면 다음과 같이 notification이 적용됩니다.

5. 마치며...

k8s 배포 프로세스와 툴을 도입하면서 정말 많은 것을 알게 되 것 같습니다. 이미지는 어떤식으로 빌드를 수행하는지 그리고 배포는 어떤식으로 하는지 등등을 알게 되었습니다.

특히 DevOps의 추세에 맞추어서 빌드와 배포를 자연스럽게 연결을 지었고, 결과에 대한 noti까지 slack에서 받아 볼 수 있도록 셋팅을 해두었습니다.

아직은 운영전의 구축 단계지만 운영하면서 많은 경험과 노하우를 쌓으며 완성해야겠다는 생각이 들었습니다.

멀티 리전에 대한 운영을 하면서 계속해서 사용하는 툴(deploy, monitoring 등)이 3배로 증식이 되는데 이부분을 어떻게 해결해야될지 고민입니다.

다음 이시간에는 쿠버네티스 CRD에 대해서 적용해보고 정리하는 시간을 갖도록 하겠습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다