ArgoCD

ArgoCD는 이름 그대로 CD(continuous delivery) tool 입니다. ArgoCD가 무엇이고 왜 필요할까요?


CD workflow without ArgoCD

어떤 마이크로서비스 어플리케이션(MSA)이 쿠버네티스에서 돌아가고 있습니다. 만약 버그가 수정되거나 새로운 기능이 추가되어 github 코드를 업데이트 하게되면 CI tool로 잘 알려진 Jenkins가 자동으로 트리거되어 테스트, 이미지 빌드, 이미지 푸시를 수행하게 됩니다.

이렇게 만들어진 새로운 버전의 이미지를 쿠버네티스에 어떻게 배포할까요? 쿠버네티스 deployment yaml 파일에서 이미지 태그를 업데이트하고 쿠버네티스에 apply 하게 됩니다.

Jenkins에는 CD 기능도 있기 때문에 쿠버네티스 manifest 파일을 업데이트하고 kubectl 명령어로 apply할 수 있습니다.

하지만 이런 CD 접근 방식은 몇가지 제한사항이 있습니다.

먼저 kubectl, helm과 같은 툴을 설치하고 setup 해야합니다. 또한 kubectl은 클라이언트에서 사용하는 명령어이기 때문에 쿠버네티스 클러스터에 접속하기 위한 자격이 필요합니다.

또 다른 포인트는 Jenkins를 통해 CD를 구축하면 deployment 상태를 시각적으로 모니터링 할 수 없다는 단점이 있습니다. 이 말은 성공적으로 클러스터에 배포 되었는지 확인하려면 CLI 환경에서 확인해야 한다는 뜻입니다.


CD workflow with ArgoCD

이러한 문제를 해결하기 위해 ArgoCD를 사용할 수 있습니다. ArgoCD로 CD 프로세스를 어떻게 효율적으로 바꿀 수 있을까요?

ArgoCD는 다음과 같은 workflow를 가지게 됩니다.

  1. ArgoCD를 쿠버네티스 클러스터에 배포
  2. ArgoCD에 특정 git 저장소를 연결시켜 놓고 감시 시작
  3. git 저장소에 변화가 감지되면 pull 하여 쿠버네티스에 배포

여기서 말하는 git 저장소에는 어플리케이션 코드가 아닌 쿠버네티스 manifest 파일이 담겨있습니다.

어플리케이션 코드 저장소에 쿠버네티스 manifest 파일을 담지 않고 따로 저장소로서 관리하는 이유가 무엇일까요?

쿠버네티스 manifest는 단순히 deployment.yaml만 존재하는 것이 아니라 configmap, secret, ingress, service 등 상황에따라 다양한 리소스가 필요하기 때문에 많은 파일을 관리해야 합니다.

또한 쿠버네티스 manifest는 소스코드로부터 독립적입니다. 예를들어 DevOps 엔지니어가 service.yaml 파일에서 포트번호를 바꾸는 일은 소스코드와는 관계가 없는 것이죠.

만약 하나의 repository에서 소스코드와 manifest를 다루게 된다면 소스코드가 변경되지 않았는데 CI 파이프라인이 트리거 해야하거나 더 복잡한 로직으로 CI 파이프라인을 구성해야 합니다.

ArgoCD를 포함한 전체 프로세스를 다시 정리하면 다음과 같습니다.

  1. 개발자가 애플리케이션 코드(소스코드)를 수정하여 git repository에 commit 합니다.
  2. Jenkins CI 파이프라인이 트리거되어 코드 테스트, 이미지 빌드 및 푸시, 그리고 쿠버네티스 manifest 파일을 업데이트합니다.
  3. 쿠버네티스 App Configuration(manifest 저장소)의 업데이트를 감지한 ArgoCD가 manifest를 pull하여 쿠버네티스에 배포합니다.

이렇게 ArgoCD를 사용하면 CI/CD 파이프라인을 자동화하고 저장소 분리를 통해 개발자와 엔지니어의 역할을 분리할 수 있게 됩니다.


Benefits of using ArgoCD

Benefit1. Single Interface

ArgoCD의 장점은 쿠버네티스의 모든 configuration 정의를 git 저장소에서 코드로 관리할 수 있다는 것입니다.

ArgoCD가 없다면 클라이언트가 수정한 configuration에 대해 로컬 환경에서 각자 다른 명령어(kubectl apply…, helm install…)를 사용해야 합니다.

하지만 ArgoCD가 있으면 모든 클라이언트는 동일하게 git commit 명령어로 App Configuration 저장소에 업데이트만하면 ArgoCD가 알아서 변동사항을 추적하여 배포를 해주기 때문에 편리합니다.


Benefit2. Full cluster transparency

또한 쿠버네티스 클러스터의 변경 사항도 감시할 수 있다는 장점이 있습니다. 만약 누군가 CLI 환경에서 쿠버네티스 클러스터에 직접적으로 업데이트를 수행하면 어떻게 될까요?

ArgoCD는 git 저장소의 변동뿐만 아니라 클러스터의 변동사항도 감지할 수 있습니다. 만약 클러스터 상태(Actual State)와 저장소 상태(Desired State)가 다르다면 이를 감지하여 경고를 날리고 Actual State를 Desired State에 맞춰서 오버라이팅 시킵니다.

이 의미는 쿠버네티스 state는 항상 App Configuration 저장소의 manifest를 따른다는 true single source 즉 투명성을 보장한다는 뜻입니다.

하지만 급하게 업데이트가 필요한 경우 CLI에서 직접적으로 업데이트를 해야할 수도 있습니다. 이러한 경우에는 클러스터 변화에 대한 sync 를 수행하는 대신 알람만 울리도록 설정할 수 있습니다.


Easy Rollback & Disaster Recovery

Git 저장소를 활용한다는 측면에서도 이점이 있습니다.

만약 업데이트에 문제가 발생한 경우 ArgoCD가 없다면 kubectl delete .. 혹은 helm uninstall .. 을 통해 리소스를 지우고 이전 버전을 배포해야 합니다.

하지만 ArgoCD에서는 git revert .. 명령어를 통해 이전 state로 돌아가기가 쉽습니다. 특히 많은 클러스터가 하나의 저장소를 바라보는 상황이라면 아주 효율적인 운영을 할 수 있을 것 입니다.

비슷한 관점에서 재난등의 이유로 운용중인 서버를 사용할 수 없게 되었을때 새로운 서버에 App Configuration 저장소를 그대로 배포시키기만 하면 되기 때문에 복구를 빠르게 할 수 있습니다.


K8s Access Control with Git & ArgoCD

사실 지금까지의 장점들은 GitOps의 일반적인 이점입니다. ArgoCD는 GitOps를 기반으로 두기 때문에 GitOps의 장점들을 모두 흡수할 수 있습니다.

그럼 ArgoCD만의 장점은 무엇일까요?

일반적으로 쿠버네티스 환경을 구축할때 클라이언트마다 클러스터에 대한 접근권한을 다르게 설정합니다. 이런 보안설정을 하기 위해서는 많은 번거로움이 있습니다. 하지만 Git에서 이를 대체할수가 있습니다.

만약 Junior Engineer와 Senior Engineer가 있을 때 Merge Requst에 대한 권한을 둘 다 가져가고 Merge를 Senior Engineer만 할 수 있다면 이것이 바로 Access Control 이라고 볼 수 있기 때문입니다.

이렇게 되면 쿠버네티스의 ClusterRole이나 User resource를 생성하지 않아도 Git을 통해 간접적으로 클러스터 Access 관리를 할 수 있게됩니다.

또한 쿠버네티스 클러스터 외부에 있는 Jenkins와 같은 non human user에게 접근권한을 줄 필요가 없습니다. 왜냐하면 ArgoCD가 이미 쿠버네티스 클러스터에서 동작하므로 클러스터 외부로 자격증명을 할 필요가 없기 때문입니다. 즉 AcgoCD는 보안 측면에서 관리하기가 쉽습니다.


ArgoCD 활용예시

ArgoCD 설치방법은 공식문서 에 자세히 나와있습니다. 여기서는 생략하고 바로 Application을 생성해 보겠습니다.

Application은 ArgoCD를 설치할때 생성되는 CRD(Custom Resource Definition) 입니다. Application 리소스를 생성하게되면 GitHub repository와 쿠버네티스 클러스터를 연결하여 CD 를 수행할 수 있습니다.

Application을 생성하는 방법은 크게 UI, CLI(명령형), manifest(선언형) 이렇게 세가지 방법이 있습니다. 저는 manifest 파일을 생성하여 Application을 생성해 보겠습니다.


application.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-argo-application
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/visionhong/argocd-config.git  # GitHub repository 주소
    targetRevision: HEAD
    path: dev  # Argocd가 바라보는 repository 폴더
  destination:
    server: https://kubernetes.default.svc  # 현재 작동중인 K8s 주소
    namespace: myapp  # 배포될 네임스페이스

  syncPolicy:
    syncOptions:
    - CreateNamespace=true  # 배포 네임스페이스 자동 생성(default=false)
    automated:
      selfHeal: true  # 클러스터 환경(Actual live state)에서 변경이 있을때 Desired State로 복구(default=false)
      prune: true  # 새로운 버전이 배포되면 이전 리소스를 자동으로 삭제(default=false)

저는 미리 깃허브 repository를 생성하고 ArgoCD가 Pulling하기 위한 dev 폴더 안에deployment.yaml, service.yaml 을 담아두었습니다.

manifest를 보면 특이한점이 대부분의 기능들이 기본적으로 False로 되어있다는 점 입니다. 그 이유는 안전성 때문입니다. 일부로 K8s 클러스터(live state)를 수정하거나 automated sync를 원하지 않을 수 있기 때문에 기본 설정이 False로 되어있고 Automated sync, self healing, prunin이 필요한 경우 위 manifest 처럼 true 설정을 할 수 있습니다.

이제 Application.yaml을 쿠버네티스 클러스터에 배포하겠습니다.


kubectl apply -f application.yaml

Application을 생성 하자마자 연결된 GitHub repository의 deployment(replicas=2)와 service가 잘 배포되는 것을 볼 수 있습니다.

이제 Automated sync, Self healing, Pruning이 제대로 작동하는지 테스트해보겠습니다. ArgoCD는 UI상에서 매우 빠르게 적용이 되기 때문에 눈으로 확인하기 위해서 영상으로 녹화하였습니다.


Automated sync + Pruning


깃허브 저장소(desired) 상태가 변경되면 영상처럼 ArgoCD에서 Automated sync가 일어나게 됩니다. 저는 간단하게 refresh 버튼을 눌렀지만 automatic sync는 default로 3분마다 작동합니다. argocd-cm configmap을 수정하거나 github webhook을 통해 동기화 주기를 바꿀 수 있습니다.

영상에 보이는 것 처럼 새로운 버전의 deployment가 생성되고 기존 버전의 deployment가 삭제되면서 automated sync와 pruning을 모두 확인할 수 있습니다.


Self healing


replicas를 5로 변경했지만 desired state인 2로 돌아가는 것을 볼 수 있습니다.


END

이번 포스팅에서는 ArgoCD에 대해 가볍게 알아보았습니다. ArgoCD는 IaaS(Infrastructure as a Code) 인 GitOps를 기반으로 설계된 툴 입니다.

이런 ArgoCD의 성격으로 인해 DevOps 쪽에서 많이 사용되고 있지만 ArgoCD가 꼭 DevOps에서만 사용할 수 있는것은 아니라고 생각합니다.

만약 쿠버네티스 환경에서 머신러닝 모델을 서비스 해야 한다면 ArgoCD를 모델 배포 자동화에 충분히 활용할 수 있을것 같습니다. 추후 시간이 된다면 MLOps에서 ArgoCD를 다루는 내용을 포스팅해보겠습니다.

Reference

업데이트:

댓글남기기