Argo CD를 쓰다 보면 “GitOps니까 Git만 보면 된다”는 말이 실제로 어떤 컴포넌트와 흐름으로 성립하는지 궁금해집니다. 이 글에서는 Argo CD의 핵심 아키텍처(Repository Server, Application Controller, Sync/Hook)를 중심으로 드리프트가 어떻게 감지·복구되는지, 그리고 CI/CD 경계 설계를 어떻게 가져가면 좋은지를 정리합니다.
Argo CD를 이해하는 핵심 키워드: SSOT, Pull 기반, 지속적 동기화
Argo CD는 Git을 배포의 Single Source of Truth(SSOT) 로 삼습니다. 즉 “원하는 상태(Desired state)”는 Git에 있고, Kubernetes 클러스터는 그 상태를 따라가도록 운영합니다.
여기서 중요한 특징이 세 가지입니다.
- Pull 기반 배포: CI/CD 파이프라인이 클러스터에 “밀어 넣는(push)” 방식이 아니라, 클러스터 내부(Argo CD)가 Git을 “당겨와(pull)” 동기화합니다.
- 지속적 비교(Desired vs Live): Git에 있는 선언과 실제 클러스터 상태를 계속 비교합니다.
- 드리프트(drift) 감지 및 자가치유(self-heal): 누군가 kubectl로 수동 변경을 하거나, 운영 중 리소스가 변형되면 이를 감지하고(드리프트) 다시 Git 상태로 맞춥니다.
이 구조 덕분에 “배포”가 단발성 이벤트가 아니라, 상태를 유지하는 지속적 제어 루프(control loop) 로 바뀝니다.
Argo CD 아키텍처 흐름: 누가 무엇을 책임지나?
Argo CD는 크게 아래 역할들이 맞물려 돌아갑니다.
1) Repository Server: “Git → 렌더링된 매니페스트” 변환 담당
Repository Server는 Git 저장소에서 설정을 가져와 실제로 클러스터에 적용 가능한 형태로 매니페스트를 렌더링(render) 합니다.
- Helm 차트 렌더링
- Kustomize 빌드
- 플러그인 기반 렌더링
- Plain YAML 처리
즉, Git에 있는 “소스(Helm/Kustomize 등)”를 쿠버네티스가 먹을 수 있는 YAML로 바꿔주는 변환 엔진에 가깝습니다.
2) Application Controller: 드리프트 감지 및 동기화의 주체
Application Controller는 “현재 클러스터 상태(Live)”와 “Git에서 렌더링한 원하는 상태(Desired)”를 비교합니다. 그리고 차이가 나면 아래 중 하나를 수행합니다.
- Manual Sync: 사람이 승인/버튼으로 동기화 실행
- Auto Sync: 조건이 맞으면 자동으로 동기화(적용) 실행
- 이때 핵심 이슈가 “운영 안정성과 변경 통제(승인/검증)의 균형”입니다(뒤에서 다시 다룹니다).
3) 지속적 동기화가 만드는 운영 효과: 드리프트가 “숨을 곳이 없다”
Push 기반 배포(예: GitHub Actions가 kubectl apply 실행)만으로는 배포 이후의 수동 변경을 상시 추적하기 어렵습니다. 반면 Argo CD는 계속 감시하고 계속 맞추기 때문에 다음이 강해집니다.
- 클러스터에 남는 “수동 핫픽스”가 장기적으로 누적되는 문제 감소
- 운영 변경 이력이 Git에 남아 감사/재현이 쉬움
- 멀티클러스터 환경에서 일관된 상태 유지에 유리
Sync Hooks: 배포를 “리소스 적용” 이상으로 확장하는 장치
Argo CD의 Sync Hooks는 동기화 과정의 특정 단계에 작업을 끼워 넣는 메커니즘입니다. 요약하면 배포 전·중·후에 필요한 작업을 선언적으로 붙이는 방법입니다.
대표적인 사용 예시는 다음과 같습니다.
- 배포 전(pre-sync): DB 마이그레이션, 스키마 체크
- 배포 중(sync): 특정 순서 강제, 데이터 준비 작업
- 배포 후(post-sync): 스모크 테스트, 알림 발송, 임시 리소스 정리
운영 관점에서 Sync Hooks의 포인트는 “편의”를 넘어서 신뢰성과 감사 가능성입니다. 배포에 필요한 절차(마이그레이션/검증/정리)가 파이프라인 스크립트 어딘가에 흩어지는 대신, 배포 정의와 함께 버전관리되기 때문입니다.
(대화에서 자주 나오는 질문) Argo CD는 CI/CD 통합이 “좋은” 편일까?
여기서 “통합이 좋다”는 의미를 먼저 분리해야 합니다.
1) “한 파이프라인/한 UI에서 끝나는 통합” 관점
- GitLab 내장 CD, Spinnaker 같은 도구들은 승인→배포→검증→롤백을 한 파이프라인/한 화면으로 강하게 묶는 경험이 강합니다.
- Argo CD는 이런 의미에서는 상대적으로 느슨한 결합에 가깝습니다. (Argo CD가 CI를 오케스트레이션하기보다, Git을 계약 지점으로 삼는 구조)
2) “감사/재현/변경 통제까지 포함한 통합” 관점
- Argo CD는 Git을 SSOT로 삼기 때문에, CI가 만든 결과(이미지/차트/매니페스트 변경)를 Git에 남기면 CD가 pull로 따라옵니다.
- 이 방식은 웹훅/버튼 연동보다 변경 이력의 추적성과 재현성이 강해지는 장점이 있습니다.
정리하면, Argo CD는 “CI와 버튼으로 촘촘히 묶인 통합”보다는 CI는 빌드·테스트·스캔·아티팩트 생성, CD(Argo CD)는 Git 상태를 지속 동기화로 가져가는 역할 분리가 자연스러운 도구입니다.
Auto Sync + Sync Hooks를 켤 때의 균형점: 안정성 vs 변경 통제
마지막으로 운영에서 가장 현실적인 고민은 이겁니다.
자동 동기화를 켜면 편해지지만, 그만큼 “승인/검증”을 어디에 둘지 애매해집니다.
제가 추천하는 설계 방향(일반론)은 다음처럼 “게이트를 Git 쪽으로 올리는” 패턴입니다.
- 승인(Approval)은 Git(PR/MR)에서:
- Auto Sync가 켜져 있어도, Git에 머지되기 전까지는 배포가 일어나지 않게 만들기 쉽습니다.
- 검증(Verification)은 CI에서 최대한 선행:
- 테스트/정적분석/보안 스캔을 통과한 변경만 머지되게 합니다.
- 클러스터 안전장치는 별도로:
- “무조건 자동 적용”이 부담이라면, 환경별로 정책을 나눕니다.
- dev/stage: Auto Sync + self-heal 적극 사용
- prod: Auto Sync 조건 제한(예: 특정 브랜치/경로만), 혹은 수동 Sync + 엄격한 PR 룰
- “무조건 자동 적용”이 부담이라면, 환경별로 정책을 나눕니다.
- Hooks는 ‘필수 절차’만 최소로:
- Hooks가 많아질수록 배포 경로가 복잡해지고, 실패 시 복구 전략도 어려워집니다.
- DB 마이그레이션/스모크 테스트처럼 “없으면 사고 나는 것” 위주로 시작하고 점진 확장하는 편이 안전합니다.
Argo CD 아키텍처는 복잡해 보이지만, 핵심은 단순합니다. Git을 SSOT로 두고, Repository Server가 렌더링하며, Application Controller가 드리프트를 지속적으로 감지·동기화한다는 흐름입니다. 여기에 Sync Hooks를 더하면 배포가 “리소스 적용”을 넘어 운영 절차까지 포함하는 선언적 체계가 됩니다.
