2026. 6. 8. 16:18ㆍDevOps
Terraform으로 인프라를 코드로 관리하는 건 익숙해졌는데, Kubernetes 배포는 여전히 CI 파이프라인에서
kubectl apply를 실행합니다. 어느 날 누군가 클러스터에 직접kubectl edit으로 설정을 바꿨고, 다음 배포에서 그 변경이 덮어씌워져 장애가 발생합니다. GitOps는 이 문제를 구조적으로 해결하는 운영 모델입니다.
핵심 요약
- GitOps는 Git을 Single Source of Truth로 사용하여, 선언적으로 정의된 상태를 클러스터에 지속적으로 동기화하는 운영 모델입니다.
- 전통적인 CI/CD의 Push 방식과 달리, GitOps는 Pull 방식으로 동작합니다. 클러스터 내부의 Agent가 Git 상태를 감시하고 자동으로 조정합니다.
- Argo CD는 Web UI와 멀티 클러스터 관리에 강점이 있어 플랫폼 팀에 적합합니다.
- Flux는 컨트롤러 조합 방식의 경량 아키텍처로, Kustomize 기반 워크플로우와 이미지 자동 업데이트에 강점이 있습니다.
- 두 도구 모두 CNCF Graduated 프로젝트이며, 선택 기준은 팀 규모, UI 필요 여부, 매니페스트 관리 방식에 따라 달라집니다.
1. 왜 GitOps가 필요한가
팀에서 Kubernetes 기반 서비스를 운영하고 있다고 가정합니다. CI/CD 파이프라인은 GitHub Actions로 구축되어 있고, 배포 단계에서 kubectl apply나 helm upgrade를 실행합니다.
이 구조에서 흔히 발생하는 문제들:
| 문제 | 상황 |
|---|---|
| Configuration Drift | 운영자가 긴급 대응으로 클러스터에 직접 변경을 적용했지만, Git에는 반영하지 않음 |
| 배포 추적 어려움 | "현재 클러스터에 어떤 버전이 떠 있는지"를 확인하려면 클러스터에 직접 접속해야 함 |
| 롤백 복잡성 | 이전 상태로 돌아가려면 어떤 커밋, 어떤 Helm values가 적용됐는지 추적해야 함 |
| 보안 리스크 | CI 파이프라인에 클러스터 admin 권한 kubeconfig를 넣어야 배포가 가능함 |
| 멀티 클러스터 일관성 | dev, staging, prod 환경 간 설정 차이가 누적되어 "staging에서 되는데 prod에서 안 됨" 발생 |
GitOps는 이 문제들을 하나의 원칙으로 해결합니다. Git에 있는 상태가 곧 클러스터의 상태여야 한다.
2. GitOps의 4대 원칙 (OpenGitOps)
CNCF OpenGitOps Working Group이 정의한 GitOps의 핵심 원칙은 4가지입니다.
| 원칙 | 설명 | 실무 의미 |
|---|---|---|
| Declarative | 시스템의 원하는 상태를 선언적으로 정의 | Kubernetes YAML, Helm values, Kustomize overlay |
| Versioned & Immutable | 선언된 상태를 버전 관리 시스템에 저장 | Git 커밋 = 배포 이력. 모든 변경이 추적됨 |
| Pulled Automatically | Agent가 원하는 상태를 자동으로 가져옴 | 클러스터 내부에서 Git을 polling하거나 webhook으로 감지 |
| Continuously Reconciled | Agent가 실제 상태를 원하는 상태와 지속적으로 비교하고 조정 | Drift 자동 감지 + 자동 복구 또는 알림 |
이 4가지 원칙의 조합이 만드는 핵심 가치는 자동 복구(Self-healing)입니다. 누군가 클러스터에서 직접 설정을 변경하더라도, Agent가 Git 상태로 되돌립니다.
3. Push 기반 vs Pull 기반 배포
GitOps를 이해하려면 기존 CI/CD와의 구조적 차이를 먼저 파악해야 합니다.
Push 기반 (전통적 CI/CD)
# GitHub Actions 배포 단계 예시
- name: Deploy to EKS
run: |
aws eks update-kubeconfig --name my-cluster
kubectl apply -f k8s/
CI 파이프라인이 클러스터에 직접 명령을 보냅니다.
- 장점: 구현이 단순하고, 기존 파이프라인에 배포 단계만 추가하면 됨
- 단점: CI 서버에 클러스터 접근 권한 필요, Drift 감지 불가, 배포 실패 시 상태 불확실
Pull 기반 (GitOps)
# Argo CD Application 정의 예시
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
source:
repoURL: https://github.com/team/k8s-manifests
targetRevision: main
path: apps/my-app/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
클러스터 내부의 Agent가 Git을 감시하고, 변경이 감지되면 스스로 동기화합니다.
- 장점: 클러스터 자격 증명이 외부에 노출되지 않음, Drift 자동 감지/복구, Git 이력이 곧 배포 이력
- 단점: 별도 Agent 설치/운영 필요, 초기 학습 곡선 존재
실무에서의 조합 패턴
대부분의 팀은 순수한 Push 또는 Pull 중 하나만 사용하지 않습니다.
CI (Push 영역): 코드 빌드 → 테스트 → 이미지 빌드 → 레지스트리 Push → 매니페스트 업데이트
CD (Pull 영역): GitOps Agent가 매니페스트 변경 감지 → 클러스터 동기화
CI는 여전히 GitHub Actions/Jenkins가 담당하고, CD 부분만 GitOps 도구가 담당하는 구조가 일반적입니다.
4. Argo CD 아키텍처
Argo CD는 2022년 12월 CNCF Graduated 프로젝트가 되었으며, 현재 v3.3이 최신 안정 버전입니다. GitOps 도구 중 가장 높은 채택률을 보이며, CNCF 2025 End User Survey 기준 Kubernetes 클러스터의 약 60%에서 사용되고 있습니다.
핵심 컴포넌트
| 컴포넌트 | 역할 |
|---|---|
| API Server | Web UI, CLI, gRPC API를 제공. 사용자 인터페이스의 진입점 |
| Repo Server | Git 리포지토리를 클론하고, Helm/Kustomize/Jsonnet 등을 렌더링하여 최종 매니페스트 생성 |
| Application Controller | 실제 클러스터 상태를 원하는 상태와 비교하고, Sync를 실행하는 핵심 컨트롤러 |
| Redis | 캐시 레이어. 매니페스트 캐싱, 세션 관리 등에 활용 |
Argo CD의 강점
1. Web UI / 토폴로지 뷰
Argo CD의 가장 눈에 띄는 차별점은 Web UI입니다. Application 단위로 리소스 트리를 시각화하고, 각 리소스의 상태(Healthy/Degraded/Progressing)를 실시간으로 확인할 수 있습니다.
운영 중 장애 대응 시 "어떤 리소스가 문제인지"를 빠르게 파악할 수 있어, 특히 온콜 엔지니어에게 유용합니다.
2. 멀티 클러스터 중앙 관리
하나의 Argo CD 인스턴스에서 여러 클러스터를 관리할 수 있습니다. 관리 클러스터에 Argo CD를 설치하고, 대상 클러스터를 등록하는 방식입니다.
# 외부 클러스터 등록
argocd cluster add my-prod-cluster --kubeconfig ~/.kube/prod-config
3. ApplicationSet으로 대규모 배포 관리
수십 개의 Application을 개별 정의하는 대신, 템플릿 기반으로 대량 생성할 수 있습니다.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-app-set
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
template:
metadata:
name: "my-app-#"
spec:
source:
repoURL: https://github.com/team/k8s-manifests
path: "apps/my-app/{{metadata.labels.region}}"
destination:
server: "#"
namespace: production
4. Sync Waves & Hooks
배포 순서를 제어할 수 있습니다. 예를 들어 "DB 마이그레이션 → 앱 배포 → 테스트 실행" 순서를 보장합니다.
Argo CD의 운영 고려사항
- 리소스 사용량: API Server + Repo Server + Application Controller + Redis로 구성되어, 소규모 클러스터에서도 기본적으로 상당한 리소스를 소비합니다.
- Repo Server 병목: 관리하는 Application 수가 많아지면 Repo Server의 Git 클론과 매니페스트 렌더링이 병목이 될 수 있습니다. sharding이나 수평 확장이 필요할 수 있습니다.
- RBAC 설계: Argo CD 자체의 RBAC(프로젝트 기반)과 Kubernetes RBAC을 별도로 관리해야 합니다.
5. Flux 아키텍처
Flux는 2022년 11월 CNCF Graduated 프로젝트가 되었으며, 현재 v2.8이 최신 안정 버전입니다. Argo CD와 달리 단일 모놀리식 서비스가 아니라, 독립적인 컨트롤러의 조합으로 구성됩니다.
핵심 컨트롤러
| 컨트롤러 | 역할 |
|---|---|
| Source Controller | Git, Helm, OCI 등 소스 리포지토리를 관리하고, 아티팩트를 다운로드 |
| Kustomize Controller | Kustomize 빌드를 실행하고 결과를 클러스터에 적용 |
| Helm Controller | HelmRelease CR을 관리하며 Helm 차트를 설치/업그레이드 |
| Notification Controller | 이벤트를 외부 시스템(Slack, Teams, webhook)으로 전달 |
| Image Automation Controller | 컨테이너 레지스트리에서 새 이미지 태그를 감지하고, Git에 자동 커밋 |
Flux의 강점
1. 경량 아키텍처
필요한 컨트롤러만 선택적으로 설치할 수 있습니다. Helm을 사용하지 않는 팀은 Helm Controller를 설치하지 않아도 됩니다.
# 기본 설치 (Source + Kustomize + Notification)
flux bootstrap github \
--owner=my-org \
--repository=fleet-infra \
--branch=main \
--path=clusters/production
2. 네이티브 이미지 자동 업데이트
CI에서 새 이미지를 빌드하면, Flux가 자동으로 감지하여 Git 리포지토리의 매니페스트를 업데이트합니다.
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: my-app
spec:
imageRepositoryRef:
name: my-app
policy:
semver:
range: ">=1.0.0"
이 기능은 "CI가 이미지를 빌드하면, Flux가 Git에 커밋하고, 다시 Flux가 그 커밋을 감지해서 배포"하는 완전 자동화 루프를 만듭니다.
3. Kustomize 네이티브 통합
Flux는 Kustomize를 1등 시민(first-class citizen)으로 지원합니다. 복잡한 오버레이 구조를 그대로 활용할 수 있습니다.
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: fleet-infra
path: ./apps/production
prune: true
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: my-app
namespace: production
4. 멀티 테넌시 설계
Flux는 각 대상 클러스터에 직접 설치되는 구조입니다. 팀별로 별도의 GitRepository와 Kustomization을 정의하여 테넌트 격리가 자연스럽습니다.
Flux의 운영 고려사항
- UI 부재: 네이티브 Web UI가 없습니다. 상태 확인은
flux getCLI 또는 Grafana 대시보드로 해야 합니다. Weave GitOps(현 Flux Subsystem for Argo)를 추가 설치하면 UI를 사용할 수 있지만 별도 구성이 필요합니다. - 디버깅 복잡도: 여러 컨트롤러가 독립적으로 동작하므로, 문제 발생 시 어떤 컨트롤러에서 이슈가 발생했는지 파악해야 합니다.
- 멀티 클러스터 관리: Argo CD처럼 중앙 집중식이 아니라, 각 클러스터에 Flux를 설치해야 합니다. 관리 오버헤드가 클러스터 수에 비례합니다.
6. Argo CD vs Flux: 선택 기준
| 기준 | Argo CD | Flux |
|---|---|---|
| 아키텍처 | 모놀리식 (API Server + Controller + Repo Server) | 마이크로서비스 (독립 컨트롤러 조합) |
| UI | 내장 Web UI (토폴로지 뷰, 실시간 상태) | 없음 (CLI + Grafana 또는 별도 UI 설치) |
| 멀티 클러스터 | 중앙 집중식 (한 곳에서 여러 클러스터 관리) | 분산형 (각 클러스터에 설치) |
| 매니페스트 렌더링 | Helm, Kustomize, Jsonnet, 커스텀 플러그인 | Helm, Kustomize (Jsonnet 미지원) |
| 이미지 자동 업데이트 | 별도 프로젝트(Argo CD Image Updater) | 네이티브 지원 (Image Automation Controller) |
| 대규모 배포 | ApplicationSet으로 템플릿 기반 대량 생성 | Kustomization 계층 구조로 관리 |
| CNCF 상태 | Graduated (2022.12) | Graduated (2022.11) |
| 리소스 소비 | 상대적으로 높음 (Redis, Repo Server 등) | 상대적으로 낮음 (필요한 컨트롤러만 설치) |
| 학습 곡선 | UI가 있어 초기 진입이 쉬움 | CLI 기반으로 Kubernetes 개념에 익숙해야 함 |
| 커뮤니티 규모 | 더 큼 (GitHub Stars 18k+, 채택률 약 60%) | 상대적으로 작음 (채택률 약 11%) |
이런 상황이면 Argo CD
- 팀에 Kubernetes 경험이 적은 멤버가 있어 UI 기반 관리가 필요할 때
- 하나의 플랫폼 팀이 여러 클러스터를 중앙에서 관리해야 할 때
- 배포 상태를 비개발자(PM, QA)에게도 가시적으로 보여줘야 할 때
- ApplicationSet으로 수십 개 서비스를 템플릿화해야 할 때
이런 상황이면 Flux
- Kustomize 기반 매니페스트 관리를 이미 하고 있을 때
- 이미지 태그 변경 시 자동으로 Git 커밋 → 배포까지 완전 자동화하고 싶을 때
- 클러스터별 독립적인 GitOps 운영이 필요할 때 (팀 자율성 우선)
- 리소스 소비를 최소화하고 싶은 소규모 클러스터일 때
실무 시나리오: 스타트업 vs 엔터프라이즈
스타트업 (클러스터 2~3개, 엔지니어 5명)
Argo CD를 하나의 관리 클러스터에 설치하고, dev/staging/prod 클러스터를 등록합니다. 전체 팀이 Web UI에서 배포 상태를 확인하고, PR 머지만으로 배포가 진행됩니다.
이 규모에서 Flux를 선택하면 각 클러스터에 별도 설치해야 하므로 관리 포인트가 늘어납니다. 다만 리소스가 제한적이라면 Flux의 경량 구조가 유리할 수 있습니다.
엔터프라이즈 (클러스터 50개+, 팀 20개+)
각 팀이 자체 클러스터와 GitOps 리포지토리를 관리합니다. 플랫폼 팀은 Flux bootstrap 구성을 표준화하고, 각 팀이 자율적으로 배포합니다. 중앙 집중식 Argo CD가 수백 개 Application을 관리하면 Repo Server와 Application Controller에 상당한 부하가 발생할 수 있습니다.
다만 엔터프라이즈에서도 Argo CD를 선택하는 경우가 많습니다. 이 경우 Argo CD를 팀별로 분리(sharding) 하거나, Application Controller를 수평 확장하는 전략을 적용합니다.
7. GitOps 도입 시 고려할 점
Git 리포지토리 구조 설계
GitOps를 도입할 때 가장 먼저 결정해야 하는 것은 리포지토리 구조입니다.
| 패턴 | 구조 | 장점 | 단점 |
|---|---|---|---|
| Monorepo | 앱 코드 + 매니페스트를 한 리포에 | 변경 추적이 단순 | 권한 분리 어려움 |
| Polyrepo (App + Config 분리) | 앱 리포 + 배포 매니페스트 리포 분리 | 명확한 관심사 분리 | 이미지 태그 업데이트 자동화 필요 |
| Multi-tenant | 환경/팀별 디렉토리 분리 | 멀티 테넌시 지원 | 디렉토리 구조가 복잡해질 수 있음 |
실무에서는 App 리포와 Config 리포를 분리하는 패턴이 보편적입니다. CI는 App 리포에서 이미지를 빌드하고, Config 리포의 이미지 태그를 업데이트합니다.
Secret 관리
Git에 Secret을 평문으로 저장할 수 없으므로, 별도 전략이 필요합니다.
| 도구 | 방식 | 연동 |
|---|---|---|
| Sealed Secrets | 암호화된 Secret을 Git에 저장, 클러스터에서 복호화 | Argo CD / Flux 모두 지원 |
| External Secrets Operator | AWS Secrets Manager/Vault 등 외부 저장소 참조 | Argo CD / Flux 모두 지원 |
| SOPS | 파일 단위 암호화, KMS/PGP 기반 | Flux 네이티브 지원, Argo CD는 플러그인 |
Flux는 SOPS(Mozilla)를 네이티브로 지원합니다. Argo CD를 사용한다면 External Secrets Operator 또는 Sealed Secrets를 조합하는 것이 일반적입니다.
Drift 감지 정책
GitOps Agent가 Drift를 감지했을 때 어떻게 대응할지 정책을 결정해야 합니다.
- Auto-sync (자동 복구): Drift 발생 시 즉시 Git 상태로 되돌림. 운영 안정성이 높지만, 긴급 대응 시 불편할 수 있음.
- Manual sync (알림만): Drift 감지 시 알림만 보내고, 수동으로 Sync 실행. 유연하지만 Drift가 방치될 수 있음.
운영 환경에서는 Auto-sync를 기본으로 하되, 특정 리소스(ConfigMap, HPA 등)는 제외하는 방식이 일반적입니다.
8. 관련 글
- CI/CD 파이프라인 기본 구조
- GitHub Actions와 Jenkins 차이
- Blue-Green Deployment와 Rolling Update 차이
- Kubernetes 아키텍처 기본 구조
- DevSecOps란 무엇인가
마무리
GitOps는 "배포를 어떻게 할 것인가"보다 "클러스터의 상태를 어떻게 관리할 것인가"에 초점을 맞춘 운영 모델입니다. Git을 중심으로 변경 이력 추적, 코드 리뷰 기반 배포, 자동 Drift 감지/복구가 가능해지며, 이는 특히 Kubernetes 환경에서 운영 안정성과 보안 수준을 높입니다.
Argo CD와 Flux 모두 성숙한 도구입니다. "어떤 것이 더 좋은가"보다 팀의 워크플로우, 기존 매니페스트 관리 방식, 멀티 클러스터 전략에 맞는 도구를 선택하는 것이 중요합니다.
'DevOps' 카테고리의 다른 글
| GitHub Actions와 Jenkins 차이: CI/CD 도구 선택 기준 (0) | 2026.06.08 |
|---|---|
| Blue-Green Deployment와 Rolling Update 차이: 배포 전략 선택 기준 (0) | 2026.06.07 |
| GitHub Actions로 Docker 이미지를 빌드하고 배포하기: CI/CD 파이프라인 실습 (0) | 2026.06.06 |
| Terraform S3 Backend와 State Lock 구성하기: 팀 협업을 위한 원격 상태 관리 (0) | 2026.05.31 |
| CI/CD 파이프라인 기본 구조: 코드 커밋부터 프로덕션 배포까지 (0) | 2026.05.29 |