ArgoCD GitOps 배포 전략 — Git이 배포의 단일 진실
GitOps는 종종 “Git에 YAML 넣고 자동 배포하는 방식”으로 소개됩니다. 하지만 실제 핵심은 자동화보다도 운영 변경의 출처를 Git으로 강제하고, 클러스터 상태를 선언적으로 복구 가능한 상태로 만드는 것에 있습니다.
ArgoCD는 이 모델을 Kubernetes에서 구현하는 대표적인 도구입니다. 다만 설치만 했다고 GitOps가 완성되지는 않습니다. 진짜 중요한 건 어떤 저장소 구조를 쓰고, promotion을 어떻게 하고, drift를 어떻게 다루고, 누가 무엇을 변경하는지를 운영 모델로 정하는 일입니다.
아키텍처 그림 설명
[Developer / Platform Team]
|
v
[Git Repository]
app config / env overlays
|
v
[Pull Request]
|
v
[Merge to Main]
|
v
[ArgoCD]
|
v
[Kubernetes Cluster]
GitOps에서 중요한 것은 사람이 직접 클러스터를 만지지 않고, Git이 변경의 출처가 되는 점입니다. ArgoCD는 Git에 선언된 상태와 실제 클러스터 상태를 비교하고, 차이가 나면 동기화하거나 drift를 복구합니다. 그래서 이 구조의 핵심은 배포 자동화 자체보다 변경 통제와 복구 가능성에 있습니다.
GitOps의 본질은 배포 자동화보다 변경 통제다
개발자 변경 -> Git commit/PR -> merge -> ArgoCD sync -> cluster 반영
이 흐름의 장점은 단순한 자동화가 아닙니다.
- 무엇이 언제 바뀌었는지 Git 이력으로 추적 가능
- 클러스터에 수동 변경이 들어가도 선언 상태로 되돌릴 수 있음
- 사람이 kubectl로 직접 만지는 빈도를 줄일 수 있음
- 리뷰와 승인 절차를 운영 변경에도 적용 가능
즉, GitOps는 배포 도구라기보다 운영의 변경 관리 모델에 가깝습니다.
ArgoCD 설치보다 중요한 건 어디를 truth로 둘 것인가
kubectl create namespace argocd
kubectl apply -n argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
설치는 어렵지 않지만, 진짜 설계 포인트는 그 다음입니다.
- 애플리케이션 코드 저장소와 배포 설정 저장소를 분리할 것인가
- 환경별 overlay를 어떤 구조로 둘 것인가
- 누가 어떤 브랜치를 수정할 수 있는가
- 배포 promotion을 PR로 표현할 것인가 태그로 표현할 것인가
ArgoCD는 결국 Git을 본다는 점에서, Git 구조가 곧 운영 구조가 됩니다.
Application은 리소스가 아니라 배포 경계다
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-configs
targetRevision: main
path: apps/my-app/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
이 정의는 “어디서 무엇을 읽어 어떤 클러스터/네임스페이스에 반영할 것인가”를 선언합니다. 즉, Application은 단순 앱 하나가 아니라 배포 책임 단위입니다.
좋은 경계는 보통 다음 기준에서 나옵니다.
- 팀 소유권이 명확한가
- 롤백/승인 단위로 자연스러운가
- 함께 배포되어야 할 리소스 묶음인가
저장소 구조는 장기 운영 비용을 좌우한다
k8s-configs/
└── apps/my-app/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/
├── staging/
└── prod/
이 구조가 널리 쓰이는 이유는 단순합니다. 공통 선언과 환경별 차이를 분리해주기 때문입니다. 다만 운영이 커질수록 다음도 함께 고민해야 합니다.
- 앱별 폴더 중심인가, 환경별 폴더 중심인가
- shared infra와 app config를 같은 repo에 둘 것인가
- Helm과 Kustomize 중 어떤 계층에서 변수화를 할 것인가
GitOps는 결국 repo 구조가 사람의 운영 사고방식을 강제합니다.
자동 동기화는 강력하지만 신중하게 켜야 한다
syncPolicy:
automated:
prune: true
selfHeal: true
이 옵션은 편리하지만 의미가 큽니다.
prune: Git에서 제거된 리소스를 클러스터에서도 제거selfHeal: 클러스터에서 수동 변경된 상태를 Git 기준으로 복원
즉, 이 설정을 켜는 순간 “클러스터 수동 변경은 일시적인 예외일 뿐, 결국 Git이 이긴다”는 원칙을 선언하는 셈입니다.
실무에서는 이 원칙이 매우 유용하지만, 동시에 수동 hotfix나 긴급 조치와 충돌할 수 있으므로 팀 합의가 꼭 필요합니다.
Drift 복구는 GitOps의 가장 큰 장점 중 하나다
운영 중에는 누군가가 kubectl edit를 하거나, Helm upgrade를 직접 치거나, 외부 컨트롤러가 상태를 바꿔놓는 일이 생깁니다. 이때 ArgoCD는 원하는 상태와 실제 상태의 차이를 보여주고 복구할 수 있습니다.
이것이 중요한 이유는 단순 편의가 아니라 운영 상태를 다시 예측 가능하게 만들어 준다는 데 있습니다. GitOps에서 self-heal은 자동화 기능이면서 동시에 drift 통제 전략입니다.
이미지 태그 업데이트는 GitOps에서 자주 쓰이는 promotion 지점이다
images:
- name: my-app
newTag: "1.2.3"
- name: Update image tag
run: |
cd k8s-configs
kustomize edit set image my-app=my-app:${{ github.sha }}
git config user.email "ci@github.com"
git add . && git commit -m "ci: update image to ${{ github.sha }}"
git push
이 패턴의 핵심은 CI가 클러스터를 직접 건드리지 않고, Git 상태를 변경해서 배포를 유도한다는 점입니다. 그래서 배포 이력도 Git에 남고, 롤백도 Git revert로 더 자연스러워집니다.
Promotion 전략을 명확히 정해야 한다
실무에서는 보통 아래 같은 질문이 생깁니다.
- staging에서 검증된 이미지를 prod로 어떻게 올릴 것인가
- 동일 artifact를 promotion할 것인가, 환경마다 다시 빌드할 것인가
- prod 반영은 자동 sync인가 수동 승인인가
이 질문에 대한 답이 없으면 GitOps는 단순 자동 배포 도구로만 남고, 운영 모델은 오히려 모호해집니다.
좋은 promotion은 대개 아래 특징을 가집니다.
- 변경 경로가 Git PR로 명확하게 보인다
- staging과 prod의 차이가 추적 가능하다
- 롤백 경로가 간단하다
멀티 환경, 멀티 클러스터에서는 Project와 권한 모델이 중요하다
ArgoCD를 쓰다 보면 결국 하나의 앱보다 여러 앱, 여러 팀, 여러 환경을 다루게 됩니다. 이때는 Application보다 Project와 RBAC가 더 중요해집니다.
- 어떤 팀이 어떤 namespace/cluster를 배포할 수 있는가
- 어떤 repo만 참조 가능하게 제한할 것인가
- prod는 누가 sync할 수 있는가
GitOps는 선언적이라고 해서 무조건 안전해지는 것이 아니라, 권한 경계가 명확할 때 훨씬 강해집니다.
GitOps에도 한계는 있다
GitOps가 잘 맞지 않거나 조심해야 하는 영역도 있습니다.
- 아주 짧은 핫픽스를 즉시 넣어야 하는 상황
- 비밀값(secret) 관리 전략이 미완성인 경우
- 외부 시스템 의존성이 많아 선언 상태만으로 복구가 어려운 경우
- 사람이 PR 없이 운영 조작을 자주 해야 하는 팀 문화
즉, GitOps는 도구 도입보다 운영 문화 변화가 더 큰 경우가 많습니다.
실무에서 자주 하는 실수
- 코드 repo와 배포 repo 경계를 의미 없이 섞는다
- auto-sync를 켰지만 운영 예외 처리 전략은 없다
- prod promotion 기준이 모호하다
- secret 관리와 GitOps를 분리해서 생각한다
- 결국 사람 손으로 kubectl을 계속 치면서 Git은 참고용으로만 남는다
특히 마지막 상태가 되면 GitOps의 장점이 크게 줄어듭니다. Git이 진실 원천이 되지 못하면 ArgoCD는 단순 배포 대시보드에 가까워집니다.
마무리
ArgoCD의 가치는 쿠버네티스에 YAML을 자동 적용하는 데만 있지 않습니다. 더 본질적으로는 운영 변경을 Git 중심으로 통제하고, 클러스터 상태를 선언적으로 복구 가능하게 만드는 것이 중요합니다.
잘 설계된 GitOps는 배포를 자동화할 뿐 아니라 운영을 더 예측 가능하게 만듭니다. 결국 핵심은 ArgoCD 설치 방법보다, “우리 팀은 어떤 변경을 Git으로 강제하고 어떤 배포 흐름을 표준으로 삼을 것인가”를 먼저 정하는 데 있습니다.
운영 환경에서 어려워지는 지점
- GitOps는 Git이 실제 desired state 권위가 되고 운영 예외가 최소화될 때 성공한다.
- Argo CD는 가시성과 반복성을 주지만 drift, sync 정책, 멀티 환경 구조를 노골적인 설계 문제로 만든다.
- 진짜 어려움은 대개 Argo CD UI보다 저장소 구조와 승격 흐름에 있다.
중요한 아키텍처 결정
- 많은 서비스를 올리기 전에 애플리케이션 경계, 저장소 레이아웃, 환경 승격 전략을 정한다.
- 자동 sync, 수동 승인, drift 보정 규칙을 위험 수준별로 정한다.
- secret, 생성된 manifest, 재사용 플랫폼 overlay를 일관된 정책 아래 둔다.
실무 예시
흔한 GitOps 구조는 앱 의도와 환경 overlay를 분리한다.
apps/
payments/
catalog/
environments/
staging/
production/
피해야 할 안티패턴
- Git으로 되돌리는 경로 없이 긴급 수동 클러스터 변경을 남기는 것.
- 두 번째 환경부터 누구도 설명하지 못하는 저장소 구조를 쓰는 것.
- 위험 모델 없이 모든 것을 자동 sync하는 것.
운영 체크리스트
- drift 이벤트와 수동 override 빈도를 감사한다.
- 승격과 롤백 경로를 정기적으로 테스트한다.
- sync 지연과 reconciliation 실패 원인을 모니터링한다.
- RBAC와 secret 관리 경계를 검토한다.
최종 판단
Argo CD는 GitOps를 단순 배포 도구가 아니라 운영 규율로 다룰 때 잘 작동한다. 실제 시스템은 Argo CD 자체보다 저장소 모델과 reconciliation 정책의 결합이다.
Continue Reading
다음으로 읽기 좋은 글
Kubernetes 심화 — HPA, Resource 관리, Pod Scheduling
Kubernetes 운영을 설정 모음이 아니라 자원 배치와 장애 복원력의 관점에서 정리합니다. requests/limits, HPA, affinity, taint, PDB, probe를 언제 어떻게 써야 하는지 실무적으로 설명합니다.
🚀 DevOpsKubernetes 클러스터 유형 완전 가이드
단일 노드부터 고가용성, 관리형, 멀티 클러스터까지 Kubernetes 클러스터 유형별 구조, 선택 기준, 구성 방법, 운영 트레이드오프를 실무 관점으로 정리합니다.
📚 IT 이야기컨테이너와 쿠버네티스는 어떻게 배포의 감각을 바꿨나
한때 배포는 늘 불안한 행사처럼 느껴졌지만, 컨테이너와 쿠버네티스는 그것을 더 반복 가능하고 더 자동화된 일상으로 바꾸려 했습니다.
📈 최신 동향Kubernetes v1.34 에서 플랫폼 팀이 봐야 할 것
Kubernetes v1.34 릴리스를 플랫폼 팀 관점에서 읽어내며 운영, 워크로드 설계, 클러스터 거버넌스에 중요한 변화만 추려 정리한 글입니다.
다음 탐색