Skip to content
hseop.com
Go back

우리 ArgoCD는 이렇게 자리 잡았다 — App of Apps와 ApplicationSet, 그리고 kustomize

약 5분

ArgoCD를 깔고 나면, 진짜 일은 그다음에 시작된다 — “앱을 어떻게 구조화할까.”

gitops

GitOps로 클러스터 상태를 Git에 묶는 것까지는 금방이었다. 정작 시간이 걸린 건 앱이 수십 개로 늘었을 때였다. 무엇을 묶고, 무엇을 따로 둘지. 정답이 하나가 아니라 더 그랬다. 이 글은 우리 환경에서 그 구조가 이 방향으로 자리 잡기까지의 기록이다.

두 패턴을 이렇게 나눴다

ArgoCD로 여러 앱을 다루는 길은 크게 둘이었고, 우리는 둘을 섞어 쓰기로 했다. 하나로 통일하기보다, 앱 성격에 맞게 갈랐다.

App of Apps — “같이 사는” 묶음

의미적으로 묶이는 여러 서비스를 함께 굴리는 도메인에 썼다. Root Application 하나가 child들을 sources로 묶고, Root를 sync하면 child가 함께 따라온다.

사실 App of Apps로 갈 수밖에 없던 더 큰 이유는 혼합이었다. 특히 인프라 도메인은 한 묶음 안에 helm 차트와 kustomize 워크로드, 그리고 CRD가 뒤섞여 있었다. child마다 mode: helm 또는 mode: kustomize를 자유롭게 지정할 수 있는 App of Apps라야, 이 이질성을 한 그룹으로 묶어 다룰 수 있었다.

ApplicationSet은 혼합 소스(helm + kustomize)를 깔끔하게 다루기 어렵다 — generator·템플릿이 동질적인 앱을 전제로 설계됐기 때문이다. 그래서 이질적 묶음은 App of Apps, 동질적 독립 앱은 ApplicationSet으로 갈렸다.

gitops/
├── app-of-apps/
│ ├── root-app/ # Root Application (도메인 묶음)
│ └── child-app/ # Child Application (argo-app 차트로 정의)
├── applicationset/
│ └── standalone/ # apps/<name>/config.yaml 자동 발견
├── kustomize/ # 실제 워크로드 매니페스트 (base + overlays)
└── helm/charts/argo-app # Application 생성용 공통 차트

ApplicationSet — “혼자 도는” 앱

도메인 그룹이 없는 standalone 앱에 썼다. 디렉터리에 설정 파일 하나만 떨어뜨리면 ApplicationSet generator가 알아서 등록한다.

# applicationset/standalone/apps/<app>/config.yaml — 이 파일 하나면 끝
name: my-app
app_namespace: my-app
project: default
source_path: kustomize/my-app/overlays/staging

이게 결정적이었다. 독립 앱·batch성 job은 Root App을 건드릴 필요 없이 config 한 장이면 끝나서, 새 앱이 들어오는 마찰이 거의 사라졌다.

ApplicationSet은 흔히 “같은 앱을 여러 클러스터·환경에 뿌리는” 용도로 알려져 있다. 우리는 그게 아니라 files generatorapps/*/config.yaml을 읽어 독립 앱을 디렉터리마다 자동 등록하는 쪽으로 활용했다. (ArgoCD도 App of Apps보다 ApplicationSet을 점점 더 권장하는 흐름이다.)

그래서 기준은 이렇게 굳었다

상황패턴
같은 도메인에 여러 서비스(마이크로서비스)App of Apps
helm 차트·kustomize·CRD가 섞인 묶음App of Apps
독립적인 1개 앱, 그룹화 가능성 낮음ApplicationSet
batch / 단발성 jobApplicationSet

한 문장으로 정리됐다. “같이 죽고 같이 사는 묶음”이면 App of Apps, “혼자 도는 앱”이면 ApplicationSet. 그리고 애매할 땐 ApplicationSet으로 시작했다 — 설정 파일 하나라, 나중에 묶음으로 옮기는 비용도 작았다.

매니페스트는 kustomize로 — helm은 Application 정의에만

워크로드 매니페스트는 helm 차트가 아니라 kustomize로 관리한다. helm은 ArgoCD Application을 찍어내는 공통 차트(argo-app) 하나에만 남겼다.

helm 대신 kustomize를 택한 건 두 가지 때문이었다.

helm을 아예 버린 건 아니다. 서드파티 앱이나 Application 정의처럼 템플릿·패키징이 이득인 곳엔 helm, 우리가 직접 관리하는 워크로드엔 kustomize — 그렇게 갈랐다.

마치며

자리를 잡고 보니, 결국 세 가지로 정리됐다.

  1. 묶음이면 App of Apps, 독립이면 ApplicationSet. 둘 중 하나로 통일하기보다 성격에 맞게 갈랐고, 애매하면 가벼운 ApplicationSet으로 시작했다.
  2. 워크로드는 kustomize로. plain YAML이라 GitOps diff가 깔끔하고 overlay로 환경 차이가 드러난다. helm은 패키징·서드파티 앱에만 남겼다.

처음부터 이 그림을 그리고 시작한 건 아니었다. 앱이 늘고, 몇 번 깨지고, 그때마다 “이건 Git에 어긋나는데”를 되뇌면서 하나씩 굳어졌다. GitOps의 힘은 결국 “지금 상태가 Git에 적힌 그대로” 라는 한 문장에 있고, 우리 구조도 그 문장을 깨지 않으려다 이 모양으로 자리 잡았다.


GitOps 운영에 정답은 없다. 이 구조도 결국 우리 환경에서 자리 잡은 답일 뿐, 팀마다 더 맞는 모양이 따로 있을 것이다. 중요한 건 “지금 상태가 Git에 적힌 그대로”라는 원칙을 깨지 않는 선에서, 자기 팀이 가장 덜 깨지는 구조를 찾는 일이다.


이 글이 마음에 들었다면