Table of contents
배포가 불안한 이유
Kubernetes 클러스터를 운영하다 보면 한 가지 공포가 생긴다. “지금 클러스터에 떠 있는 것과 Git에 있는 매니페스트가 정말 같은 상태인가?”
누군가 kubectl edit으로 Deployment를 직접 고쳤을 수 있고, CI 파이프라인이 중간에 실패해서 절반만 반영됐을 수도 있다. 배포 스크립트를 돌린 사람이 퇴근한 뒤에야 장애가 터지면, 어떤 버전이 올라가 있는지 추적하는 것부터 일이 된다.
이 문제의 근본 원인은 단순하다. 실제 클러스터 상태를 추적하는 단일 기준점이 없다는 것. GitOps는 바로 이 문제를 정면으로 해결하려는 접근법이다.
GitOps — Git이 진실의 원천
GitOps의 핵심 아이디어는 놀라울 정도로 단순하다. Git 리포지토리에 있는 매니페스트가 곧 클러스터의 바람직한 상태(desired state)다. 클러스터는 항상 그 상태를 따라가야 하고, 벗어나면 자동으로 되돌린다.
이걸 좀 더 구체적으로 풀어보면 이렇다.
- 선언적 정의: 인프라와 애플리케이션 상태를 YAML 같은 선언적 형식으로 Git에 저장한다
- 단일 진실 원천(Single Source of Truth): Git 리포가 유일한 기준이므로, 클러스터에 무엇이 배포되어 있는지 알고 싶으면 Git을 보면 된다
- 자동 동기화: Git의 상태와 클러스터의 상태가 다르면, 에이전트가 자동으로 맞춰준다
- 감사 추적: 모든 변경이 Git 커밋으로 남으니, 누가 언제 무엇을 바꿨는지 자연스럽게 기록된다
결국 Git이 이미 제공하는 버전 관리, 코드 리뷰, 롤백 같은 기능을 인프라 운영에도 그대로 쓰겠다는 발상이다.
Push 배포 vs Pull 배포
전통적인 CI/CD 파이프라인은 Push 방식으로 동작한다.
flowchart LR
A[개발자] -->|git push| B[CI 서버]
B -->|빌드 & 테스트| C[컨테이너 이미지]
B -->|kubectl apply| D[K8s 클러스터]
style B fill:#f97316,color:#fff
CI 서버가 빌드를 마친 뒤, kubectl apply나 helm upgrade로 클러스터에 직접 밀어넣는 구조다. 이 방식은 직관적이지만 몇 가지 문제가 있다.
- CI 서버에 클러스터 접근 권한(
kubeconfig)을 줘야 한다. 보안 관점에서 부담이 크다 - 배포 중간에 CI가 죽으면 상태가 꼬인다
- 누군가
kubectl로 직접 수정하면 Git과 클러스터가 어긋나는데, 그걸 감지할 방법이 마땅찮다
GitOps는 Pull 방식을 쓴다.
flowchart LR
A[개발자] -->|git push| B[Git 리포]
C[ArgoCD] -->|감시 & 동기화| B
C -->|적용| D[K8s 클러스터]
C -.-|클러스터 내부에서 동작| D
style C fill:#3b82f6,color:#fff
클러스터 안에서 동작하는 에이전트가 Git 리포를 주기적으로 바라보다가, 변경이 생기면 스스로 가져와서 적용한다. 핵심적인 차이는 배포 주체가 외부(CI)가 아니라 클러스터 내부라는 점이다.
이렇게 하면 CI 서버에 클러스터 접근 권한을 줄 필요가 없어지고, 누군가 직접 수정해도 에이전트가 Git 상태로 되돌려놓기 때문에 drift(상태 불일치)를 방지할 수 있다.
ArgoCD가 하는 일
ArgoCD는 이 Pull 방식 GitOps를 Kubernetes 환경에서 구현한 도구다. CNCF(Cloud Native Computing Foundation) 졸업 프로젝트이기도 해서, 커뮤니티 규모나 안정성 면에서 검증이 되어 있다.
ArgoCD의 동작을 한 문장으로 요약하면 이렇다. Git에 정의된 desired state와 클러스터의 live state를 지속적으로 비교하고, 차이가 나면 동기화한다.
좀 더 구체적으로 보면 ArgoCD는 이런 일들을 해준다.
- 상태 모니터링: Git 리포의 매니페스트와 클러스터의 실제 상태를 실시간 비교
- 자동/수동 싱크: 차이가 발견되면 자동으로 맞추거나, 사용자가 버튼 하나로 싱크
- 헬스 체크: Deployment, Service 등 리소스가 정상인지 확인하고 상태를 보여줌
- 롤백: 이전 Git 커밋 상태로 클러스터를 되돌리는 게 커밋 해시 하나면 가능
- 멀티 클러스터: 하나의 ArgoCD로 여러 클러스터를 관리할 수 있음
- 웹 UI: 애플리케이션별 상태, 리소스 트리, 로그를 브라우저에서 확인
특히 웹 UI가 잘 되어 있어서, 어떤 리소스가 어떤 상태인지 한눈에 파악하기 좋다. 커맨드라인에서 kubectl get 을 반복하던 것에 비하면 운영 편의성이 확 올라간다.
왜 ArgoCD인가
GitOps 도구가 ArgoCD만 있는 건 아니다. Flux도 있고, Jenkins X도 있다. 그런데 실무에서 ArgoCD를 선택하는 이유는 대체로 이런 것들이다.
첫째, UI가 직관적이다. 리소스 간 관계를 트리로 보여주고, 싱크 상태를 색상으로 구분해준다. 신규 팀원이 와도 현재 배포 상태를 금방 파악할 수 있다.
ArgoCD 공식 리포 — Apache 2.0 License
둘째, Application CRD로 선언적 관리가 가능하다. ArgoCD 자체의 설정도 Git으로 관리할 수 있으니, “ArgoCD를 ArgoCD로 관리하는” 구조가 된다. 이걸 App of Apps 패턴이라고 부른다.
셋째, Kustomize, Helm, Jsonnet 등 다양한 매니페스트 도구를 지원한다. 프로젝트마다 다른 도구를 쓰더라도 ArgoCD 하나로 통합 관리가 가능하다.
넷째, RBAC과 SSO를 기본 지원한다. 팀 규모가 커지면 누가 어떤 앱을 배포할 수 있는지 권한 관리가 필수인데, ArgoCD는 이걸 자체적으로 제공한다.
전체 흐름 정리
ArgoCD를 도입했을 때의 전형적인 워크플로우를 정리해보자.
1. 개발자가 애플리케이션 코드를 수정하고 PR을 올린다
2. CI가 빌드 & 테스트를 돌리고, 컨테이너 이미지를 레지스트리에 푸시한다
3. 매니페스트 리포의 이미지 태그를 새 버전으로 업데이트한다 (수동 또는 자동)
4. ArgoCD가 매니페스트 리포의 변경을 감지한다
5. Git의 desired state와 클러스터의 live state를 비교한다
6. 차이가 있으면 싱크하여 클러스터를 Git 상태로 맞춘다
7. 헬스 체크를 통해 배포가 정상인지 확인한다
여기서 주목할 점은 CI와 CD가 완전히 분리된다는 것이다. CI는 이미지를 만드는 데까지만 책임지고, 실제 배포는 ArgoCD가 담당한다. 각자의 역할이 명확하니 파이프라인이 단순해지고, 문제가 생겼을 때 원인을 찾기도 쉬워진다.
다음 편에서는 ArgoCD를 Kubernetes 클러스터에 직접 설치하고, 초기 설정과 UI 접속까지 진행해본다.
Loading comments...