목차
[인프라] Argo CD 멀티 클러스터 GitOps 도입 사례: 운영 노하우와 도전 과제
안녕하세요, 13년차의 서버실 운영자입니다. 오늘은 제가 직접 겪었던 경험을 바탕으로 Argo CD 멀티 클러스터 GitOps 도입 사례에 대해 이야기해볼까 합니다. 쿠버네티스(Kubernetes)를 운영하다 보면 자연스럽게 여러 클러스터를 관리해야 하는 상황에 부딪히게 되죠. 개발, 스테이징, 프로덕션 환경을 분리하거나, 재해 복구(Disaster Recovery)를 위해 지리적으로 분산된 클러스터를 운영하는 경우도 많고요. 처음엔 각각의 클러스터에 배포하는 것도 정말 힘들었는데, 이 모든 것을 효율적으로 관리하려니 골머리가 지끔했었습니다. 혹시 이런 경험 있으신가요?
저도 처음엔 수동 배포와 스크립트의 늪에서 헤맸습니다. 그러다 GitOps(깃옵스)라는 개념을 접하고, 특히 Argo CD(아르고 CD)가 이 문제를 해결해 줄 수 있다는 걸 알게 되었죠. 특히 여러 클러스터를 한 곳에서 관리할 수 있는 Argo CD 멀티 클러스터 기능은 정말 반가웠습니다. 오늘은 이 기능을 도입하면서 제가 겪었던 삽질과 노하우, 그리고 얻었던 운영 효율성에 대해 솔직하게 풀어보려 합니다.
Argo CD 멀티 클러스터 GitOps의 전체 아키텍처 다이어그램입니다. 중앙의 Argo CD 컨트롤 플레인이 여러 쿠버네티스 클러스터에 애플리케이션을 배포하고 관리하는 모습을 보여줍니다.
GitOps와 Argo CD, 그리고 멀티 클러스터 관리
먼저, GitOps(깃옵스)가 뭔지 간단히 짚고 넘어가 보겠습니다. 쉽게 말하면, Git(깃) 저장소를 진리의 원천(Source of Truth)으로 삼아 인프라와 애플리케이션 배포를 관리하는 방식이에요. 모든 변경 사항은 Git에 기록되고, Git의 상태와 실제 클러스터의 상태를 일치시키는 것이 핵심입니다. 이렇게 하면 누가 언제 무엇을 변경했는지 추적하기 쉽고, 문제가 생겼을 때 이전 상태로 되돌리기도(Rollback) 훨씬 수월하죠.
그리고 Argo CD(아르고 CD)는 이런 GitOps 원칙을 쿠버네티스 환경에서 구현하도록 도와주는 선언적(Declarative) GitOps 지속적 배포(Continuous Delivery) 도구입니다. Git 저장소에 정의된 상태를 주기적으로 감지해서 쿠버네티스 클러스터의 실제 상태와 비교하고, 다르면 Git의 상태에 맞춰 동기화(Sync)해줍니다. 정말 편리하더라고요.
그렇다면 멀티 클러스터 관리(Multi-Cluster Management)는 뭘까요? Argo CD는 한 개의 인스턴스로 여러 개의 쿠버네티스 클러스터에 배포를 관리할 수 있는 기능을 제공합니다. 메인 Argo CD가 설치된 클러스터(저는 이걸 컨트롤 플레인 클러스터(Control Plane Cluster)라고 부릅니다)에서 여러 타겟 클러스터(Target Cluster)들을 등록하고, 각각의 클러스터에 어떤 애플리케이션을 어떤 버전으로 배포할지 Git을 통해 지시하는 방식이에요. 덕분에 여러 환경에 동일한 애플리케이션을 일관성 있게 배포하고 관리하는 게 훨씬 쉬워졌습니다. 💡
실전 구현: Argo CD 멀티 클러스터 환경 구축하기
자, 이제 실제로 어떻게 구성했는지 살펴보겠습니다. 저는 세 개의 클러스터를 준비했는데, 하나는 Argo CD가 설치될 컨트롤 플레인 클러스터, 그리고 나머지 두 개는 애플리케이션이 배포될 타겟 클러스터입니다. 모든 클러스터는 kubeconfig(쿠브콘피그)를 통해 접근할 수 있도록 설정되어 있다고 가정하겠습니다.
1. Argo CD 설치 및 타겟 클러스터 등록
먼저, 컨트롤 플레인 클러스터에 Argo CD를 설치합니다. 이건 공식 문서에 잘 나와 있으니 간단하게 넘어갈 테고, 핵심은 타겟 클러스터를 Argo CD에 등록하는 것입니다. Argo CD CLI를 사용하면 정말 간단하게 등록할 수 있어요.
# Argo CD CLI 설치 (공식 문서 참고)
# brew install argocd
# Argo CD 로그인 (admin 계정 패스워드는 초기 설치 시 자동으로 생성됩니다)
argocd login <ARGOCD_SERVER_IP_OR_HOSTNAME>
# 타겟 클러스터 등록
# kubeconfig에 등록된 클러스터 이름을 사용합니다.
# 제 경우엔 dev-cluster와 prod-cluster라는 이름으로 등록되어 있었죠.
argocd cluster add dev-cluster --name dev-cluster-region-a
argocd cluster add prod-cluster --name prod-cluster-region-b
# 등록된 클러스터 목록 확인
argocd cluster list
이렇게 하면 Argo CD가 해당 클러스터에 접근해서 애플리케이션을 배포할 수 있는 권한을 가지게 됩니다. 중요한 부분은 RBAC(Role-Based Access Control, 역할 기반 접근 제어) 설정인데, Argo CD가 타겟 클러스터에서 필요한 리소스(Deployment, Service 등)를 생성/수정/삭제할 수 있도록 적절한 권한을 부여해야 합니다. 저는 처음엔 이걸 놓쳐서 "왜 배포가 안 될까?" 한참 삽질했었습니다. ⚠️
Argo CD 웹 UI에 등록된 dev-cluster-region-a와 prod-cluster-region-b 클러스터의 목록과 상태를 보여주는 화면입니다. 모든 클러스터가 Healthy 상태로 나타나 있네요.
2. Git 저장소 구조화: App of Apps 패턴
멀티 클러스터 환경에서 Git 저장소를 효율적으로 관리하는 방법 중 하나는 App of Apps 패턴(App of Apps Pattern)입니다. 하나의 최상위 Argo CD Application이 여러 하위 Application들을 관리하는 방식이에요. 저는 다음과 같이 Git 저장소를 구성했습니다.
.
├── applications/
│ ├── base/ # 공통 애플리케이션 정의 (예: Ingress Controller, Cert Manager)
│ └── microservices/ # 마이크로서비스별 애플리케이션 정의
├── clusters/
│ ├── dev-cluster-region-a/ # 개발 클러스터별 설정
│ │ └── root-app.yaml
│ └── prod-cluster-region-b/ # 프로덕션 클러스터별 설정
│ └── root-app.yaml
└── environments/
├── dev/ # 개발 환경별 값 (values.yaml for Helm)
└── prod/ # 프로덕션 환경별 값 (values.yaml for Helm)
각 클러스터 폴더 안의 `root-app.yaml`은 해당 클러스터에 배포될 모든 하위 애플리케이션을 정의하는 최상위 Argo CD Application입니다. 예를 들어 `dev-cluster-region-a/root-app.yaml`은 다음과 같이 작성할 수 있죠.
# clusters/dev-cluster-region-a/root-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dev-cluster-root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/my-org/my-gitops-repo.git # 본인의 Git 저장소 URL
targetRevision: HEAD
path: applications # 하위 애플리케이션 정의들이 있는 경로
destination:
server: https://kubernetes.default.svc # 이 Application은 Argo CD가 설치된 클러스터에 적용
namespace: argocd # Argo CD가 Application 리소스를 관리하는 네임스페이스
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
그리고 `applications/` 경로 안에는 실제 배포될 애플리케이션들의 정의가 들어갑니다. 예를 들어, `applications/microservices/my-service.yaml`은 다음과 같을 수 있어요. 여기서 ApplicationSet(애플리케이션셋)을 사용하면 여러 클러스터에 동일한 애플리케이션을 배포하는 것이 훨씬 유연해집니다.
# applications/microservices/my-service.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-service-all-clusters
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: dev-cluster-region-a # Argo CD에 등록된 클러스터 이름
url: https://kubernetes.default.svc # 타겟 클러스터의 API 서버 URL
name: dev
- cluster: prod-cluster-region-b
url: https://kubernetes.default.svc
name: prod
template:
metadata:
name: my-service-{{name}} # 클러스터 이름에 따라 Application 이름이 생성됩니다 (예: my-service-dev, my-service-prod)
namespace: default
spec:
project: default
source:
repoURL: https://github.com/my-org/my-app-helm-charts.git # 애플리케이션 Helm 차트 저장소
targetRevision: 1.0.0
path: my-service
helm:
values: |
replicaCount: 2
image:
tag: "1.0.0-{{name}}" # 환경별 이미지 태그 (예: 1.0.0-dev, 1.0.0-prod)
ingress:
host: my-service.{{name}}.example.com
destination:
server: "{{url}}" # 위에서 정의된 타겟 클러스터의 URL
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
위 `ApplicationSet` 예시는 `list` 제너레이터를 사용해서 `dev`와 `prod` 두 환경에 `my-service`를 배포하도록 정의하고 있습니다. 각 환경에 맞는 `values`를 `helm` 섹션에서 오버라이드(Override)할 수 있어서 정말 유용해요. 저는 Helm(헬름) 차트를 주로 사용하는데, Kustomize(커스터마이즈)나 일반 YAML도 물론 지원합니다.
⚠️ 삽질 경험과 운영 노하우
Argo CD 멀티 클러스터를 운영하면서 몇 가지 정말 잊지 못할 경험들이 있습니다. 독자분들은 저와 같은 실수를 반복하지 않으시길 바라며 몇 가지 중요한 팁을 공유합니다.
1. RBAC 권한 문제
가장 흔하고 고통스러운 문제예요. Argo CD가 타겟 클러스터에 배포할 때, 필요한 권한이 없어서 배포가 실패하는 경우가 정말 많습니다. Argo CD를 등록할 때 부여하는 권한은 ServiceAccount(서비스 어카운트)를 통해 부여되는데, 이 서비스 어카운트가 타겟 클러스터에서 ClusterRole(클러스터 롤)과 ClusterRoleBinding(클러스터 롤 바인딩)을 통해 적절한 권한을 가지고 있는지 반드시 확인해야 합니다. 저는 처음엔 `admin` 권한을 무심코 줬다가 보안 팀에게 한소리 듣고, 나중에는 필요한 최소한의 권한만 부여하도록 변경했습니다. 💡
# 예시: Argo CD ServiceAccount에 필요한 ClusterRoleBinding 부여 (타겟 클러스터에서 실행)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argocd-manager-role-binding
subjects:
- kind: ServiceAccount
name: argocd-manager # Argo CD가 사용하는 ServiceAccount 이름
namespace: argocd # Argo CD가 설치된 네임스페이스
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin # 임시로 전체 권한 부여. 실제 운영에서는 더 세분화된 Role을 사용하세요.
실제 운영에서는 `cluster-admin` 대신 `edit`이나 `view` 같은 기본 Role을 조합하거나, 특정 리소스에 대한 `get`, `list`, `watch`, `create`, `update`, `patch`, `delete` 권한을 명시적으로 부여하는 커스텀 ClusterRole을 만들어서 사용하는 게 훨씬 안전합니다.
2. 네트워크 연결 및 방화벽
Argo CD 컨트롤 플레인 클러스터에서 타겟 클러스터의 API 서버에 접근할 수 있어야 합니다. 만약 클러스터들이 서로 다른 네트워크에 있거나, 방화벽(Firewall) 정책이 엄격하다면 연결 문제가 발생할 수 있죠. 저는 회사 보안 정책 때문에 VPC 피어링(VPC Peering)이나 VPN(Virtual Private Network) 설정을 통해 연결을 확보해야 했어요. 핑(Ping) 테스트나 `kubectl`로 직접 연결해보면서 연결성을 확인하는 것이 정말 중요합니다.
3. 시크릿 관리(Secret Management)
여러 클러스터에 배포되는 애플리케이션들은 데이터베이스 비밀번호나 API 키 같은 민감한 정보(Secret)들을 필요로 합니다. 이걸 Git에 그대로 올릴 수는 없겠죠. 저는 External Secrets Operator(외부 시크릿 오퍼레이터)와 Vault(볼트)를 연동해서 사용하거나, Sealed Secrets(실드 시크릿)를 활용해서 시크릿을 안전하게 관리했습니다. Git에 암호화된 형태로 저장하고, 각 클러스터에서 복호화해서 사용하는 방식이에요. 이 부분은 보안상 정말 중요하니 깊이 있게 고민해야 합니다.
4. 설정 드리프트(Configuration Drift)
GitOps의 핵심은 Git 저장소의 상태와 실제 클러스터의 상태가 일치해야 한다는 거예요. 그런데 운영 중에 누군가 클러스터에서 직접 리소스를 수정해서 Git과 클러스터의 상태가 달라지는 설정 드리프트(Configuration Drift)가 발생할 수 있습니다. Argo CD는 이런 드리프트를 감지하고 자동으로 동기화(Self-Heal)하거나, 수동으로 동기화할 수 있는 기능을 제공합니다. 하지만 근본적으로는 클러스터에 직접 접근해서 변경하는 것을 정책적으로 금지하고, 모든 변경은 Git을 통해서만 이루어지도록 강제하는 게 중요합니다.
🎉 Argo CD 멀티 클러스터 도입 후기 및 성과
숱한 삽질 끝에 Argo CD 멀티 클러스터 GitOps 환경을 성공적으로 구축하고 운영하게 되었습니다. 그 결과는 정말 놀라웠어요.
- 배포 일관성 및 안정성 향상: 개발, 스테이징, 프로덕션 클러스터에 동일한 버전의 애플리케이션을 일관된 방식으로 배포할 수 있게 되었습니다. 수동 작업으로 인한 휴먼 에러(Human Error)가 정말 줄었죠.
- 배포 속도 단축: Git에 코드를 푸시(Push)만 하면 Argo CD가 자동으로 감지하고 배포를 시작합니다. CI/CD 파이프라인(Pipeline)과 연동하여 개발자들이 훨씬 빠르게 변경 사항을 적용할 수 있게 되었어요.
- 쉬운 롤백(Rollback): 문제가 발생했을 때, Git의 이전 커밋(Commit)으로 되돌리는 것만으로 애플리케이션을 이전 상태로 쉽게 롤백할 수 있습니다. 비상 상황에서 정말 큰 도움이 되더군요.
- 운영 가시성 확보: Argo CD UI를 통해 모든 클러스터의 애플리케이션 상태를 한눈에 확인할 수 있게 되었습니다. 어떤 애플리케이션이 어느 클러스터에 어떤 버전으로 배포되어 있는지 파악하기가 정말 쉬워졌어요.
Argo CD 웹 UI에서 dev-cluster와 prod-cluster에 배포된 여러 애플리케이션들의 동기화 상태와 Health 상태를 한눈에 보여주는 대시보드 화면입니다. 모든 애플리케이션이 Sync'd and Healthy 상태를 나타내고 있네요.
Argo CD 멀티 클러스터 도입 전후 비교
| 구분 | 도입 전 (수동/스크립트 기반) | 도입 후 (Argo CD 멀티 클러스터 GitOps) |
|---|---|---|
| 배포 방식 | 클러스터별 수동 `kubectl` 적용 또는 쉘 스크립트 실행 | Git 커밋 기반 자동 동기화 (선언적) |
| 배포 일관성 | 환경별 설정 차이 발생 가능성 높음, 휴먼 에러 빈번 | Git을 통한 일관된 설정 적용, 휴먼 에러 최소화 |
| 롤백 용이성 | 이전 상태 복구 어려움, 시간 소요 | Git 커밋 되돌리기로 빠르고 안정적인 롤백 |
| 운영 가시성 | 각 클러스터에 개별 접근하여 상태 확인 | 단일 Argo CD UI에서 모든 클러스터 및 애플리케이션 상태 확인 |
| 보안 및 감사 | 수동 변경 이력 추적 어려움 | Git 변경 이력을 통한 완벽한 감사 추적 |
위 표에서 보시는 것처럼, Argo CD 멀티 클러스터 GitOps는 인프라 운영 방식에 혁신적인 변화를 가져다주었습니다. 특히 여러 클러스터를 관리해야 하는 복잡한 환경에서는 그 진가가 더욱 빛을 발하더군요.
마무리하며: 배운 점과 다음 도전 과제
오늘은 제가 Argo CD 멀티 클러스터 GitOps를 도입하면서 겪었던 과정과 노하우, 그리고 얻었던 성과에 대해 이야기해봤습니다. 처음엔 낯선 개념과 복잡한 설정 때문에 막막하기도 했지만, 한번 구축하고 나니 인프라 운영의 질이 한 단계 높아지는 걸 체감할 수 있었습니다. 특히 쿠버네티스 멀티 클러스터 관리에 대한 고민이 많으셨던 분들께 저의 Argo CD GitOps 사례가 작은 도움이 되었으면 좋겠어요.
물론 아직 도전 과제는 남아있습니다. 예를 들어, 프로그레시브 딜리버리(Progressive Delivery)를 위해 Argo Rollouts(아르고 롤아웃)과 연동하거나, 더 복잡한 클러스터 간 의존성을 관리하는 방법, 그리고 비용 최적화와 같은 부분은 앞으로도 계속 고민하고 실험해봐야 할 영역입니다. 💡
저처럼 GitOps 도입 후기를 찾고 계셨던 분들이라면, Argo CD를 적극적으로 검토해보시길 추천합니다. 직접 해보면 생각보다 어렵지 않고, 얻는 이점은 훨씬 크다는 걸 느끼실 겁니다. 다음번에는 더 깊이 있는 주제로 찾아오겠습니다. 긴 글 읽어주셔서 감사합니다! 궁금한 점이 있다면 언제든지 댓글로 남겨주세요.
'IT > k8s' 카테고리의 다른 글
| [k8s] Argo CD 멀티 클러스터 동기화 문제 해결: 실제 운영 사례와 디버깅 팁 (0) | 2026.06.19 |
|---|---|
| [k8s] Kubernetes 스토리지: Longhorn vs Rook-Ceph 성능 벤치마크 (0) | 2026.06.18 |
| [k8s] Argo CD 멀티 클러스터 GitOps 베스트 프랙티스 체크리스트 (0) | 2026.06.17 |
| [k8s] Kustomize와 Helm, K8s 설정 관리 도구 실측 성능 비교 (0) | 2026.06.12 |
| [K8s] Pod Security Admission 1년 사용 후기 및 실수담 (0) | 2026.06.10 |
| [k8s] OpenTelemetry K8s 모니터링, 비용 효율적인 구축 전략 (1) | 2026.06.09 |