
Intro
안녕하세요. 환이s입니다 👋
지난 글에서는 데이터 레이크하우스 플랫폼의
여덟 번째 스택으로 ArgoCD를 Kubernetes 위에 구축하고
Harbor private registry와 연동하는 과정을 정리해 봤습니다.
이번 글에서는
ArgoCD의 App of Apps 패턴을 활용해서
Kafka, Airflow, Spark 등 플랫폼 전체 스택을 GitOps로 관리하는 방법을 정리해보려고 합니다.

ArgoCD를 설치했다고 해서 GitOps가 완성된 것은 아닙니다.
어떤 패턴으로 앱을 관리할지 설계하는 것이 핵심입니다.
이번 글에서는
- App of Apps 패턴의 개념과 왜 사용하는지
- Git 저장소의 디렉토리 구조 설계 방법
- Root Application 설정 방법
- 실제 앱 추가/삭제 워크플로우
- Web UI에서 배포 상태를 확인하는 방법
까지 순서대로 확인해 보겠습니다.
1. App of Apps 패턴이란?
일반적인 ArgoCD 사용 방식은
앱마다 Application 리소스를 하나씩 직접 만드는 것입니다.
App of Apps는 "Application들을 관리하는 Application"을 두는 패턴입니다.
platform-root (Root Application)
└── gitops/apps/platform/ 디렉토리를 감시
├── airflow.yaml → platform-airflow (Application)
├── kafka.yaml → platform-kafka (Application)
├── spark.yaml → platform-spark (Application)
├── prometheus.yaml → platform-prometheus (Application)
└── ...
앱을 추가하려면 gitops/apps/platform/ 에 yaml 파일 하나만 추가하면 됩니다.
ArgoCD가 자동으로 감지하고 배포합니다.
즉, 여기서 확인할 수 있는 핵심은
App of Apps 패턴에서는 Root Application 하나만 수동으로 배포하면,
이후 모든 앱은 Git에 파일을 추가하는 것만으로 자동 배포된다는 점입니다.
2. 디렉토리 구조
이번 구축에서 사용하는 디렉토리 구조는 아래와 같습니다.
data-platform/
├── bootstrap/ # 수동으로 한 번만 배포하는 리소스
│ └── 03_argocd/
│ └── manifests/
│ ├── 30_root_app.yaml # platform-root Application
│ └── 35_webapps_root.yaml # webapps-root Application
│
└── gitops/ # ArgoCD가 지속적으로 감시하는 영역
└── apps/
├── platform/ # platform-root가 감시하는 디렉토리
│ ├── airflow.yaml
│ ├── prometheus.yaml
│ ├── spark.yaml
│ ├── kafka.yaml
│ ├── ...
│
├── airflow/ # 각 앱의 실제 배포 리소스
├── prometheus/
├── spark/
├── kafka/
└── ...
Root Application은 bootstrap/ 에서 한 번만 배포합니다.
이후 앱 추가/수정은 gitops/apps/platform/ 을 Git으로 관리합니다.
즉, 여기서 확인할 수 있는 핵심은
bootstrap/ 은 사람이 직접 한 번 실행하는 영역이고,
gitops/ 는 ArgoCD가 자동으로 감시하고 동기화하는 영역이라는 점입니다.
3. Root Application 설정
✔️ platform-root
# bootstrap/03_argocd/manifests/30_root_app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: platform-root
namespace: argocd
spec:
project: default
source:
repoURL: http://<GIT_SERVER>/<ORG>/<REPO>.git
targetRevision: main
path: gitops/apps/platform
directory:
recurse: true # 하위 디렉토리까지 재귀 탐색
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true # Git에서 삭제된 리소스를 클러스터에서도 삭제
selfHeal: true # 클러스터 상태가 Git과 달라지면 자동 복원
syncOptions:
- CreateNamespace=true
핵심 설정 설명은 아래와 같습니다.
| 설정 | 설명 |
| directory.recurse: true | 디렉토리 내 모든 yaml을 재귀적으로 읽음 |
| automated.prune: true | Git에서 yaml 삭제 시 클러스터 리소스도 삭제 |
| automated.selfHeal: true | 누군가 kubectl로 직접 수정해도 Git 상태로 자동 복원 |
| CreateNamespace=true | 네임스페이스가 없으면 자동 생성 |
⚠️ prune: true와 selfHeal: true는 강력한 설정입니다.
Git이 항상 올바른 상태여야 하며, 실수로 파일을 삭제하면 클러스터에서도 리소스가 삭제됩니다.
4. 각 앱 Application 설정
gitops/apps/platform/ 아래의 각 yaml은 개별 앱의 ArgoCD Application을 정의합니다.
✔️ kafka.yaml 예시
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: platform-kafka
namespace: argocd
spec:
project: default
source:
repoURL: http://<GIT_SERVER>/<ORG>/<REPO>.git
targetRevision: main
path: gitops/apps/kafka # 실제 kafka 배포 yaml이 있는 경로
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
모든 앱 yaml이 동일한 구조를 가집니다.
name과 path만 앱마다 다릅니다.
💡참고 : destination.namespace: argocd는 Applino 리소스 자체가 생성되는 네임스페이스입니다.
실제 앱(Kafka, Airflow 등)이 배포되는 네임스페이스는 각 앱의 배포 yaml 내부에서 별도로 정의됩니다.
CreateNamespace=true 옵션으로 해당 네임스페이스가 없으면 자동 생성됩니다.
5. 실제 배포 흐름
✔️ 새 앱 추가하기
- gitops/apps/platform/ 에 새 yaml 파일 작성
- Git commit & push
- ArgoCD가 변경 감지(기본 polling 3분)
- 자동으로 새 Application 생성 및 배포
# 예시: OpenSearch 추가
vim gitops/apps/platform/opensearch.yaml
git add .
git commit -m "feat: add opensearch application"
git push origin main
✔️ 앱 삭제하기
# yaml 파일 삭제
git rm gitops/apps/platform/opensearch.yaml
git commit -m "chore: remove opensearch application"
git push origin main
# prune: true 설정으로 ArgoCD가 자동으로 클러스터에서도 삭제
✔️ 롤백하기
# 이전 커밋으로 되돌리기
git revert HEAD
git push origin main
# ArgoCD가 자동으로 이전 상태로 복원
즉, 여기서 확인할 수 있는 핵심은
모든 배포/삭제/롤백이 git push 하나로 완결된다는 점입니다.
kubectl로 직접 수정하더라도 ArgoCD가 Git 상태로 자동 복원합니다.
6. Web UI에서 확인하기
Ingress 설정 URL로 접속 후 Applications 화면에서 상태를 확인합니다.
platform-root를 클릭하면 하위 Application 목록이 트리 형태로 표시됩니다.
✔️ Sync Status
| 상태 | 의미 |
| Synced | Git과 클러스터 상태 일치 |
| OutOfSync | Git과 클러스터 상태 불일치 |
✔️ Health Status
| 상태 | 의미 |
| Healthy | 모든 리소스 정상 |
| Progressing | 배포 진행 중 |
| Degraded | 이상 상태(Pod CrashLoop 등) |
| Missing | 리소스가 클러스터에 없음 |

💡참고: OutOfSync 상태가 지속된다면 Git에 변경이 있는지, 또는 클러스터에 수동 변경이 있었는지 확인해 보세요. selfHeal: true 설정이 있다면 수 분 내로 자동 복원됩니다.
📝 마무리
이번 글에서는 App of Apps 패턴으로 데이터 플랫폼 전체를 GitOps 방식으로 관리하는 과정을 정리해 봤습니다.
정리하면,
- App of Apps 패턴 → Root Application 하나가 나머지 모든 앱을 자동 관리
- 디렉토리 구조 → bootstrap/(수동 1회) vs gitops/(ArgoCD 자동 감시) 영역 분리
- prune + selfHeal → Git 삭제 시 클러스터 자동 삭제, kubectl 수정 시 자동 복원
- 앱 추가 → yaml 파일 하나를 Git에 push 하는 것으로 완료
- 롤백 → git revert 하나로 이전 상태로 복원
라고 볼 수 있습니다.
특히 이번 구축에서 주의해야 할 포인트는
- prune: true는 Git에서 파일을 실수로 삭제하면 클러스터 리소스도 삭제되므로 주의
- Root Application은 bootstrap/에서 수동으로 한 번만 배포하고, 이후는 Git으로만 관리
- 앱별 yaml의 path는 실제 배포 리소스가 있는 경로를 정확히 지정해야 함
이 3가지였습니다.
이것으로 데이터 레이크하우스 플랫폼의 핵심 스택 구축 시리즈를 마무리합니다. 🙌
다음 포스팅부터는 플랫폼의 완성도를 높여주는 OSS들을 다뤄보려고 합니다.
Kafka, Spark, Trino 같은 핵심 스택을 더 안정적이고
효율적으로 운영하기 위한 오토스케일링, 시크릿 관리, 모니터링 고도화 등
플랫폼 운영 디테일을 잡아주는 도구들을 하나씩 정리해 나갈 예정입니다.
궁금한 점이나 추가로 다뤄줬으면 하는 내용이 있다면 언제든지 편하게 말씀해 주세요! 😊
'[ Infra ] > Data Platform' 카테고리의 다른 글
| [Data Platform] KEDA 오토스케일링 가이드 (멀티 트리거 설계 feat. Airflow·Spark) (1) | 2026.07.13 |
|---|---|
| [Data Platform] KEDA 구축 가이드(Operator 설치부터 API 연동용 RBAC까지) (0) | 2026.07.10 |
| [Data Platform] ArgoCD 구축 가이드 (Helm + Private Registry + Ingress 구성) (0) | 2026.07.06 |
| [Data Platform] Superset 구축 가이드 (feat. Trino 연동) (0) | 2026.06.10 |
| [Data Platform] Prometheus + Grafana 구축 가이드 (feat. kube-prometheus-stack) (0) | 2026.06.09 |