Search
📚

Argo CD App of apps 패턴

Argo CD를 활용해서 많은 배포를 한 번에 관리할 수는 없을까?
배포된 서비스의 변경은 Git에 기록되지만, 어떤 배포를 누가 추가했는지는 어떻게 알 수 있을까?
위 문제들을 해결해주는, Argo CD의 App of apps패턴을 소개합니다.

들어가기 전에

이 포스트의 내용은 Argo CD의 조금은 심화적인 사용법이며, Argo CD에 대한 지식이 어느정도 있다는 전제 하에 읽는 것이 좋습니다.
만약 Argo CD의 기본적인 내용에 대해서 다시 한 번 살펴보고 싶다면 공식 문서 또는 제가 쓴 다른 포스트를 참고해주세요.

지금까지 알던 Argo CD, 그리고 몇 가지 문제점

Argo CD를 사용해보셨다면, 아마도 대부분은 Argo CD에서 제공하는 Web UI에서 대부분의 작업을 하셨을 것이라고 생각합니다.
실제로 위에서 참고하는 문서들도 모두 Web UI를 통해 기본적인 배포를 가이드 및 테스트하고 있습니다.
간단히 되짚어보면, 위 UI에서 +NEW APP을 통해서 App을 만들고 어떤 repository를 source로, 어느 클러스터의 어느 namespace에 배포할지 설정하면 쉽고 간편하게 쿠버네티스에 배포를 진행할 수 있었습니다.
그런데 Argo CD의 기본적인 사용 범주를 조금 벗어나면, 이 Web UI를 통해 Argo CD를 이용하는 것에 많은 제약이 있는 것을 알게됩니다.
실제로 저는 Web UI를 통한 Argo CD에서 다음과 같은 어려움을 느끼기 시작했습니다.
Argo CD의 사용자 관리가 불가능
User 생성
RBAC
Argo CD가 설치되지 않은 외부 클러스터 추가 불가능
Custom Argo CD Plugins 설정 불가능
Web UI에서의 Application의 생성/삭제는 Git으로 관리되지 않음
etc
위에 나열한 내용들은 실제로 Web UI에서 설정/확인이 어려운 항목들이며, 특히 이 포스트에서는 "Application의 배포는 Git으로 관리되지 않음" 에 대해서 좀 더 이야기해보려고합니다.

Application의 배포는 Git으로 관리되지 않음

Argo CD에 대해 기본적인 내용을 파악했다면, 당연히 GitOps에 대해서도 들어보셨을 것입니다.
GitOps는 Argo CD를 움직이게 하는 핵심 개념으로, Argo CD가 관리하는 쿠버네티스의 배포에 관한 모든 사항이 Git에 기록된다는 것이 핵심입니다.
그런데 위 처럼 Web UI에서 Application을 생성하고 삭제하게되면, 이에 관련된 기록은 어디에도 남지 않게 됩니다. 열심히 GitOps기반의 배포를 했으나 정작 Application의 배포는 GitOps로 관리할 수 없다는 의미인 것이죠.
이로 인해 발생될 수 있는 문제 몇가지는 다음을 들 수 있습니다.
Application의 생성/삭제 등의 기록이 없음
누가, 어떤 클러스터에 무슨 Application을 생성했는지 알 수 없음
Application이 삭제되면, Application 생성시 사용한 설정(Sync Policy, Source, Destination 등)도 함께 삭제됨
물론, 이게 모든 상황에서 문제점이라고는 할 수 없을 것입니다. 규모가 적은 쿠버네티스 클러스터를 운영 중이라면 기본적인 것만으로도 충분합니다.
저의 경우를 예로 들면, Argo CD를 본격적으로 사용하면서 쿠버네티스 클러스터만 7개를 관리하고 클러스터마다 약 20+개의 application이 배포되었습니다. 당연히 배포에 관련된 개발자도 점점 늘어났습니다.
처음에 5개 정도의 application을 바라볼 땐 평화롭기 그지없었지만, 복잡성이 점점 증가하고 있었죠.
이처럼 [1]배포(App)가 많아지고, [2]배포자가 여러명이되면서, [3]많은 리소스가 하나의 App에 관리되기 시작하면서 위에 언급한 문제들이 실제로 다가왔고, 이를 개선하기 위한 방법을 찾게되었습니다.
위를 참고하면, 하나의 Application 안에 많은 쿠버네티스 리소스가 있는 것을 볼 수 있고, 상단을 보면 Git commit message로 저자는 알 수 있지만 누가 이 Application을 만들고, Application의 설정을 바꿨을지는 도저히 알 방법이 없습니다.

Application (CRD)

위에서 계속 App이라는 용어를 사용했는데, 이는 Argo CD를 설치할 때 생성되는 Application 이라는 CRD(Custom Resource Definition) 입니다.
Application은 Argo CD가 관리하는 배포의 가장 작은 단위이며, Web UI에서 생성했던 App과 같은 리소스에 해당합니다.
Argo CD를 설치하고 CRD를 확인해보면, 아래처럼 application이라는 커스텀 리소스를 확인할 수 있습니다.
이제 위처럼 mysql-test 라는 App을 생성해보겠습니다. mysql-tet App에 관한 정보, Source, Destination 정보 등을 작성하고 App을 생성하면 mysql이 클러스터에 쉽게 배포된 것을 확인할 수 있습니다.
쿠버네티스에 Argo CD의 커스텀 리소스로 application이 있는 것을 확인했으니, kubectl을 통해 배포된 application을 확인해보겠습니다.
Web UI에서 생성한 mysql-test application 리소스를 확인할 수 있습니다.
이제 mysql-test application 리소스 내부 구조를 조금 더 자세히 살펴보도록 하겠습니다.
$ kubectl get applications -n argocd mysql-test -o yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: finalizers: - resources-finalizer.argocd.argoproj.io name: mysql-test namespace: argocd spec: destination: namespace: default server: https://kubernetes.default.svc project: default source: helm: valueFiles: - values.yaml path: mysql repoURL: https://github.com/gomgomshrimp/helm-charts targetRevision: main syncPolicy: automated: {} status: {...}
YAML
복사
여기서 눈여겨볼 값들은 destination, source이며, 알고보면 mysql-test application을 콘솔에서 생성할 때 작성했던 값과 동일한 것을 알 수 있습니다.
destination: 배포할 타겟 클러스터를 설정
server: 배포할 쿠버네티스 클러스터 api-server 주소
지금은 Argo CD가 배포된 클러스터에 배포하므로 https://kubernetes.default.svc 를 사용합니다.
namespace: 배포 타겟 네임스페이스
source: 배포할 소스 repository를 설정
repoURL: 소스 repository 주소
path: repository 내 path
targetRevision: 브랜치 이름
syncPolicy: 배포 Sync 옵션 설정
결론적으로, Argo CD로 배포한다는 것의 의미는 application이라는 argoproj.io의 커스텀 리소스를 쿠버네티스에 생성하고, Argo CD는 application 리소스를 통해 배포를 관리하는 것으로 볼 수 있습니다.
또한 당연하게도 이를 yaml로 표현할 수 있습니다. 그 의미는 곧 Argo CD의 배포 최소 단위인 application 역시 GitOps로 관리할 수 있다는 뜻이 됩니다.

App of apps 패턴

App of apps?

Application을 설명했으니, 이제 이 글의 목적이었던 App of apps 패턴에 대한 설명을 할 수 있습니다.
App of apps, 말 그대로 앱들의 앱이라는 의미로 여러개의 application을 하나의 application으로 관리하는 패턴을 말합니다.
App of apps 패턴은 단순합니다.
하나의 application안에 다시 여러개의 하위 application 들로 구성하는 것이 전부입니다.
각각의 하위 application들은 각자 자신이 필요로하는 Source, Destination, Sync Option 등이 설정되어 있습니다.
그렇다면 위처럼 App of apps 패턴으로 구성하고 Argo CD에 배포하면 어떻게 될지 생각해보겠습니다.
Argo CD는 하위 application들을 포함하는 상위 application 리소스를 생성하게되고, 상위 application으로부터 생성된 하위 application들은 개별적으로 Source, Destination, Sync Option을 갖고 Argo CD에 생성됩니다.
즉, App of apps 패턴을 사용하면 하나의 application을 통해 여러개의 application을 생성할 수 있습니다.
쉽게 표현하자면 "배포를 배포한다" 고 할 수 있겠습니다.
이제 이 패턴을 직접 테스트해보겠습니다.

App of apps 패턴 사용해보기

App of apps 패턴형태로 미리 준비해둔 예시 저장소를 먼저 살펴보겠습니다.
App of apps 내부의 application의 Source가 될 차트를 모아둔 repository
상위 application은 helm chart 형태로 구성을 했으며, 이 차트의 내부에는 apache, mysql, wordpress를 배포할 수 있는 application(CRD)들을 모두 담고 있습니다.
이 helm chart를 Argo CD에 배포하면 다음과 같은 3개의 application이 쿠버네티스 클러스터에 생성됩니다.
# Source: chart/templates/apache-application.yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: apache namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: destination: namespace: default server: https://kubernetes.default.svc project: default source: helm: valueFiles: - values.yaml path: apache repoURL: https://github.com/gomgomshrimp/helm-charts targetRevision: HEAD syncPolicy: automated: prune: true
YAML
복사
# Source: chart/templates/mysql-application.yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: mysql namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: destination: namespace: default server: https://kubernetes.default.svc project: default source: helm: valueFiles: - values.yaml path: mysql repoURL: https://github.com/gomgomshrimp/helm-charts targetRevision: HEAD syncPolicy: automated: prune: true
YAML
복사
# Source: chart/templates/wordpress-application.yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: wordpress namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: destination: namespace: default server: https://kubernetes.default.svc project: default source: helm: valueFiles: - values.yaml path: wordpress repoURL: https://github.com/gomgomshrimp/helm-charts targetRevision: HEAD syncPolicy: automated: prune: true
YAML
복사
자세히 살펴보면, 위의 3개 application들의 Source가 각각 https://github.com/gomgomshrimp/helm-charts 의 apache, mysql, wordpress path를 지정하고 있는 것을 알 수 있습니다.
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: app-of-apps namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: destination: namespace: default server: https://kubernetes.default.svc project: default source: helm: valueFiles: - values.yaml path: . repoURL: https://github.com/gomgomshrimp/argocd-app-of-apps targetRevision: main syncPolicy: automated: prune: true
YAML
복사
이제 App of apps repo 상위 application을 위 같이 작성하여 직접 배포해보겠습니다.
배포결과로 app-of-apps라는 application과 apache, mysql, wordpress application들이 생성되어 총 4개의 application이 생성된 것을 확인할 수 있습니다.
또한, 상위 application인 app-of-apps application을 눌러서 살펴보면, 기존에는 쿠버네티스 리소스가 있던 부분에 똑같이 application 리소스로 3개가 연결되어 있는 것을 확인할 수 있습니다.
마찬가지로 kubectl 커맨드로 application들의 상태를 확인할 수 있습니다.
그리고 하위 application들을 살펴보면 각자 필요한 쿠버네티스 리소스를 생성한 것을 확인할 수 있습니다.
원래는 apache, mysql, wordpress 배포를 하나하나 생성하여 총 3번 생성작업을 해야했던 것이 한 번의 작업으로 배포/관리를 할 수 있게 되었습니다.

언제, 왜 써야할까?

Argo CD Docs에서는 App of apps 패턴을 사용하는 사례로 Cluster Bootstraping을 설명하고 있습니다.
예시대로 새로 구축한 쿠버네티스 클러스터에 많은 App을 설치하려는 관리자의 관점에서 App of apps 패턴은 매우 유용할 것이라고 생각합니다.
이는 앞서 언급한 문제점 중 [1]App이 많아지고,  [3]많은 리소스가 하나의 App에 관리되는 포인트를 해결할 수 있습니다.
하지만 개인적으로는 Application 역시 GitOps로 관리할 수 있다는 점이 핵심이라고 생각합니다.
결과적으로, 많은 App을 배포할 때, 그리고 application까지 GitOps로 관리할 수 있다는 측면에서 App of apps 패턴은 매우 유용할 것으로 생각합니다.
많은 App을 하나의 application으로 관리하고 한 번에 배포 가능
각 application의 변경은 chart repo에서 GitOps로 관리
application의 추가/생성/변경은 app of apps repo에서 GitOps로 관리
예를 들면, 다음 같은 사용 사례가 가능합니다.
mysql버전을 변경
chart repo의 mysql 의 버전을 변경
mysql application의 이를 감지하고 mysql 버전 업데이트
클러스터에 mongoDB를 새로 추가하고 싶다.
app-of-apps repo에 mongoDB application을 추가

결론

이 포스트에서는 Argo CD의 배포 단위인 Application을 심화적으로 사용하는 App of apps 패턴에 대해 알아보았습니다.
Argo CD를 통한 배포를 사용하다보면 어느 순간 Argo CD 배포 관리가 너무 복잡해지거나, Argo CD application까지 관리하고 싶은 순간이 분명히 올 것이라고 확신합니다.
그런 상황에서 App of apps 패턴은 어느정도 해결책이 될 수 있습니다.
물론, 장점만 있는 것은 아닙니다. 개인적으로 생각하는 단점으로 3가지가 있습니다.
첫 번째, 배포에 관련된 많은 사항이 Argo CD에 의존성이 강하게 생깁니다.
두 번째, 개발자가 Web UI 대신 Application CRD를 yaml로 직접 작성해야하기 때문에 부담이 될 수 있습니다.
세 번째, Auto-Sync를 사용하지 않으면 사실상 Sync는 기존과 동일하게 각각 수행해줘야하기 때문에 생성/삭제 외에는 다른 점이 없습니다. (운영환경에서는 Auto-Sync를 enable하는 것이 쉽지 않습니다.)
그럼에도 Cluster Bootstrapping 및 많은 Application 배포를 한 번에 할 수 있다는 점, Application의 생성/삭제까지 Git으로 관리할 수 있다는 점에서 App of apps 패턴은 Argo CD를 사용하는 좋은 방법이라고 생각합니다.