ArgoCD의 내부 아키텍처, Application CRD, 동기화 정책, ApplicationSet을 활용한 멀티클러스터 배포, Argo Rollouts 연동, RBAC과 SSO 설정까지 심층적으로 살펴봅니다.
1장에서 GitOps의 핵심 원칙과 도구 생태계를 살펴보았습니다. 이번 장에서는 가장 널리 사용되는 GitOps 도구인 ArgoCD를 심층적으로 분석합니다. 단순한 설치와 사용법을 넘어, 내부 아키텍처의 동작 원리를 이해하고 프로덕션 환경에서 필요한 고급 설정을 다루겠습니다.
ArgoCD는 Kubernetes 네이티브로 설계된 지속적 배포(Continuous Delivery) 도구입니다. 내부적으로 네 가지 핵심 컴포넌트가 협력하여 Git 저장소와 클러스터 상태를 동기화합니다.
API 서버는 ArgoCD의 진입점입니다. 웹 UI, CLI, gRPC/REST API를 통한 모든 요청을 처리합니다. 주요 역할은 다음과 같습니다.
Repo 서버는 Git 저장소와의 통신을 전담합니다. 저장소를 클론하고, Helm 차트 렌더링, Kustomize 빌드, 일반 YAML 매니페스트 생성 등을 수행합니다. 보안을 위해 별도의 네트워크 정책으로 격리하는 것이 권장됩니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-repo-server
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
- podSelector:
matchLabels:
app.kubernetes.io/name: argocd-application-controller
egress:
- to: [] # Git 저장소 접근만 허용
ports:
- port: 443
protocol: TCP
- port: 22
protocol: TCP컨트롤러는 ArgoCD의 핵심 엔진입니다. 조정 루프(Reconciliation Loop)를 통해 Git에 선언된 원하는 상태와 클러스터의 실제 상태를 지속적으로 비교합니다. 차이가 감지되면 상태를 OutOfSync로 표시하고, 동기화 정책에 따라 자동 또는 수동으로 클러스터를 업데이트합니다.
Redis는 애플리케이션 상태 캐시, Git 저장소 캐시, 매니페스트 캐시를 저장합니다. 프로덕션 환경에서는 Redis HA 모드를 권장합니다.
ArgoCD 2.x 이후 Redis는 선택적 컴포넌트가 되었지만, 대규모 환경에서는 성능을 위해 반드시 사용해야 합니다. 수백 개의 Application을 관리하는 경우 Redis 없이는 API 서버와 컨트롤러의 응답 시간이 크게 증가합니다.
ArgoCD에서 배포의 기본 단위는 Application CRD(Custom Resource Definition)입니다. 소스(Git 저장소)와 대상(Kubernetes 클러스터/네임스페이스)을 연결하는 선언적 리소스입니다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: apps/my-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m동기화 정책은 ArgoCD가 Git과 클러스터 간의 차이를 어떻게 처리할지 결정합니다.
syncPolicy:
automated:
prune: true # Git에서 제거된 리소스를 클러스터에서도 삭제
selfHeal: true # 수동 변경(드리프트)을 자동 복원
allowEmpty: false # 모든 리소스가 제거되는 동기화 방지prune: true와 allowEmpty: false를 함께 설정하는 것을 강력히 권장합니다. Git 저장소의 경로가 잘못 설정되어 빈 매니페스트가 생성되는 경우, 프로덕션 리소스가 모두 삭제되는 사고를 방지할 수 있습니다.
프로덕션 환경에서는 자동 동기화 대신 수동 동기화를 선호하는 조직도 있습니다. 이 경우 ArgoCD가 OutOfSync 상태를 감지하면 알림만 보내고, 운영자가 검토 후 수동으로 동기화합니다.
syncPolicy:
syncOptions:
- Validate=true
- PrunePropagationPolicy=foreground
- PruneLast=true
# automated 섹션을 생략하면 수동 동기화복잡한 애플리케이션에서는 리소스 배포 순서가 중요합니다. ArgoCD는 동기화 웨이브(Sync Wave)와 리소스 훅(Resource Hook)을 통해 이를 제어합니다.
# Wave 0: 네임스페이스와 ConfigMap 먼저 생성
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
annotations:
argocd.argoproj.io/sync-wave: "0"
---
# Wave 1: 데이터베이스 마이그레이션 Job 실행
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
annotations:
argocd.argoproj.io/sync-wave: "1"
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
---
# Wave 2: 애플리케이션 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
annotations:
argocd.argoproj.io/sync-wave: "2"ApplicationSet 컨트롤러는 ArgoCD의 확장 기능으로, 하나의 템플릿에서 여러 Application을 자동 생성합니다. 멀티클러스터 또는 멀티테넌트 환경에서 특히 유용합니다.
ArgoCD에 등록된 모든 클러스터에 동일한 애플리케이션을 배포합니다.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: monitoring-stack
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
template:
metadata:
name: 'monitoring-{{name}}'
spec:
project: infrastructure
source:
repoURL: https://github.com/org/infra-manifests.git
targetRevision: main
path: 'monitoring/overlays/{{metadata.labels.region}}'
destination:
server: '{{server}}'
namespace: monitoringGit 저장소의 디렉토리 구조를 기반으로 Application을 자동 생성합니다.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: team-apps
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/org/k8s-manifests.git
revision: main
directories:
- path: 'teams/*/apps/*'
template:
metadata:
name: '{{path[1]}}-{{path[3]}}'
spec:
project: '{{path[1]}}'
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path[1]}}'여러 제너레이터를 조합하여 카르테시안 곱을 생성합니다. 예를 들어, "모든 클러스터 x 모든 앱" 조합을 생성할 수 있습니다.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cross-cluster-apps
namespace: argocd
spec:
generators:
- matrix:
generators:
- clusters:
selector:
matchLabels:
env: production
- git:
repoURL: https://github.com/org/k8s-manifests.git
revision: main
directories:
- path: 'platform-apps/*'
template:
metadata:
name: '{{path.basename}}-{{name}}'
spec:
project: platform
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: '{{path}}'
destination:
server: '{{server}}'
namespace: '{{path.basename}}'ApplicationSet의 goTemplate: true 옵션을 활성화하면 Go 템플릿 문법을 사용할 수 있습니다. 조건 분기, 루프, 문자열 처리 등 더 복잡한 로직을 구현할 때 유용합니다.
ArgoCD는 기본적으로 Kubernetes의 롤링 업데이트만 지원합니다. 프로그레시브 딜리버리(Progressive Delivery) 전략인 카나리(Canary)와 블루-그린(Blue-Green) 배포를 위해서는 Argo Rollouts와 통합해야 합니다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-server
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 30
- pause: { duration: 5m }
- setWeight: 60
- pause: { duration: 10m }
- setWeight: 100
analysis:
templates:
- templateName: success-rate
startingStep: 2
args:
- name: service-name
value: api-server
canaryService: api-canary
stableService: api-stable
trafficRouting:
istio:
virtualService:
name: api-vsvc
routes:
- primary
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: myapp:v2카나리 배포 중 자동으로 메트릭을 검증하여 배포 진행 여부를 결정합니다.
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 60s
successCondition: result[0] >= 0.95
failureLimit: 3
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(
http_requests_total{service="{{args.service-name}}", status=~"2.."}[5m]
)) /
sum(rate(
http_requests_total{service="{{args.service-name}}"}[5m]
))프로덕션 환경에서는 세밀한 접근 제어가 필수입니다. ArgoCD는 자체 RBAC 시스템과 다양한 SSO 프로바이더를 지원합니다.
# 역할 정의
p, role:dev-team, applications, get, */*, allow
p, role:dev-team, applications, sync, dev-project/*, allow
p, role:dev-team, applications, action/*, dev-project/*, allow
p, role:ops-team, applications, *, */*, allow
p, role:ops-team, clusters, get, *, allow
p, role:ops-team, repositories, *, *, allow
# 그룹 매핑
g, dev-team-group, role:dev-team
g, ops-team-group, role:ops-teamapiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Okta
issuer: https://org.okta.com/oauth2/default
clientID: $oidc.clientID
clientSecret: $oidc.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
requestedIDTokenClaims:
groups:
essential: trueOIDC 클라이언트 시크릿은 절대 ConfigMap에 평문으로 저장하지 마십시오. ArgoCD는 argocd-secret Secret에서 $ 접두사로 참조할 수 있는 기능을 제공합니다. External Secrets Operator와 연동하면 더욱 안전합니다.
controller:
replicas: 2
env:
- name: ARGOCD_CONTROLLER_REPLICAS
value: "2"
server:
replicas: 3
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
repoServer:
replicas: 3
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
redis-ha:
enabled: true
replicas: 3ArgoCD Notifications를 활용하여 동기화 상태 변화를 Slack, Teams 등으로 알림을 받을 수 있습니다.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
data:
trigger.on-sync-failed: |
- when: app.status.operationState.phase in ['Error', 'Failed']
send: [app-sync-failed]
template.app-sync-failed: |
message: |
Application {{.app.metadata.name}} sync failed.
Revision: {{.app.status.sync.revision}}
Error: {{.app.status.operationState.message}}
service.slack: |
token: $slack-token
username: ArgoCD
icon: ":argocd:"이번 장에서는 ArgoCD의 내부 아키텍처부터 Application CRD, 동기화 정책, ApplicationSet을 통한 멀티클러스터 배포, Argo Rollouts 통합, RBAC과 SSO 설정까지 살펴보았습니다. ArgoCD는 풍부한 웹 UI와 직관적인 관리 인터페이스 덕분에 GitOps 입문 도구로 적합하면서도, ApplicationSet과 Argo Rollouts 같은 고급 기능으로 대규모 프로덕션 환경까지 확장할 수 있습니다.
다음 장에서는 ArgoCD의 대안이자 CNCF GitOps 생태계의 또 다른 축인 Flux를 살펴보겠습니다. Flux의 독특한 아키텍처와 이미지 자동 업데이트 기능, 그리고 ArgoCD와의 비교를 통해 프로젝트에 적합한 도구를 선택하는 기준을 제시하겠습니다.
이 글이 도움이 되셨나요?
Flux의 멀티컨트롤러 아키텍처, 다양한 소스 관리, Kustomization 리소스, 이미지 자동 업데이트 기능을 분석하고 ArgoCD와 비교합니다.
Kubernetes 운영이 어떻게 성숙해 왔는지, 그리고 GitOps가 왜 현대 Kubernetes 운영의 핵심 패러다임이 되었는지 살펴봅니다.
허브-스포크, 메시 등 멀티클러스터 패턴과 ArgoCD ApplicationSet, Flux Kustomize 오버레이를 활용한 클러스터 플릿 관리 전략을 다룹니다.