- Published on
ArgoCD ApplicationSet과 Progressive Rollout: GitOps 멀티클러스터 배포 실전 가이드
- Authors
- Name
- 1. ArgoCD ApplicationSet이란
- 2. ApplicationSet Generator 유형
- 3. Progressive Sync: 단계적 롤아웃
- 4. Argo Rollouts: Canary와 Blue-Green
- 5. 실전: ApplicationSet + Rollouts 통합
- 6. ArgoCD CLI 운영 명령어
- 7. 모범 사례
- 8. 퀴즈
1. ArgoCD ApplicationSet이란
ApplicationSet은 ArgoCD의 확장 리소스로, 하나의 템플릿에서 여러 Application을 자동 생성한다. 멀티클러스터, 멀티테넌트, 모노레포 환경에서 수십~수백 개의 Application을 수동으로 관리하는 대신 선언적으로 자동화할 수 있다.
1.1 왜 ApplicationSet인가?
기존 방식:
app-dev.yaml → Application (dev)
app-staging.yaml → Application (staging)
app-prod.yaml → Application (prod)
... × 50개 서비스 = 150개 YAML 수동 관리 😱
ApplicationSet:
appset.yaml → 하나의 템플릿으로 150개 자동 생성 ✅
2. ApplicationSet Generator 유형
2.1 List Generator
가장 단순한 형태. 명시적 파라미터 목록에서 Application 생성:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-envs
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: dev
url: https://dev-k8s.example.com
namespace: myapp-dev
- cluster: staging
url: https://staging-k8s.example.com
namespace: myapp-staging
- cluster: prod
url: https://prod-k8s.example.com
namespace: myapp-prod
template:
metadata:
name: 'myapp-{{cluster}}'
spec:
project: default
source:
repoURL: https://github.com/org/myapp.git
targetRevision: HEAD
path: 'k8s/overlays/{{cluster}}'
destination:
server: '{{url}}'
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: true
2.2 Git Generator (Directory)
모노레포 구조에서 디렉토리 기반 자동 검색:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/org/cluster-addons.git
revision: HEAD
directories:
- path: addons/*
- path: addons/exclude-this
exclude: true
template:
metadata:
name: '{{path.basename}}'
spec:
project: addons
source:
repoURL: https://github.com/org/cluster-addons.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
2.3 Cluster Generator
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/monitoring.git
path: helm-chart
helm:
valueFiles:
- 'values-{{metadata.labels.region}}.yaml'
destination:
server: '{{server}}'
namespace: monitoring
2.4 Matrix Generator (조합)
두 Generator를 교차 결합:
spec:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/org/apps.git
revision: HEAD
directories:
- path: apps/*
- clusters:
selector:
matchLabels:
env: production
3. Progressive Sync: 단계적 롤아웃
3.1 개념
Progressive Sync는 ApplicationSet이 생성한 Application들을 한꺼번에 배포하지 않고 단계적으로 배포하는 전략이다. QA → Staging → Production 순서로 검증하면서 진행할 수 있다.
3.2 설정
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: myapp-progressive
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: qa
url: https://qa-k8s.example.com
- cluster: staging
url: https://staging-k8s.example.com
- cluster: prod-east
url: https://prod-east-k8s.example.com
- cluster: prod-west
url: https://prod-west-k8s.example.com
strategy:
type: RollingSync
rollingSync:
steps:
- matchExpressions:
- key: cluster
operator: In
values:
- qa
# QA 먼저 배포 → 자동 Sync
- matchExpressions:
- key: cluster
operator: In
values:
- staging
maxUpdate: 100%
# QA 성공 후 staging 자동
- matchExpressions:
- key: cluster
operator: In
values:
- prod-east
- prod-west
maxUpdate: 50%
# prod는 50%씩 단계적으로
template:
metadata:
name: 'myapp-{{cluster}}'
labels:
cluster: '{{cluster}}'
spec:
project: default
source:
repoURL: https://github.com/org/myapp.git
targetRevision: HEAD
path: 'k8s/overlays/{{cluster}}'
destination:
server: '{{url}}'
namespace: myapp
syncPolicy:
automated:
prune: true
4. Argo Rollouts: Canary와 Blue-Green
4.1 Canary 배포
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 30
- pause: {duration: 5m}
- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: myapp
- setWeight: 60
- pause: {duration: 10m}
- setWeight: 100
canaryService: myapp-canary
stableService: myapp-stable
trafficRouting:
istio:
virtualServices:
- name: myapp-vsvc
routes:
- primary
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v2
ports:
- containerPort: 8080
4.2 AnalysisTemplate (자동 롤백)
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 30s
count: 10
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]))
4.3 Blue-Green 배포
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp-bluegreen
spec:
replicas: 5
strategy:
blueGreen:
activeService: myapp-active
previewService: myapp-preview
autoPromotionEnabled: false
prePromotionAnalysis:
templates:
- templateName: success-rate
scaleDownDelaySeconds: 300
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v2
5. 실전: ApplicationSet + Rollouts 통합
5.1 디렉토리 구조
repo/
├── apps/
│ ├── frontend/
│ │ ├── base/
│ │ │ ├── rollout.yaml
│ │ │ ├── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── dev/
│ │ ├── staging/
│ │ └── prod/
│ └── backend/
│ ├── base/
│ └── overlays/
└── appsets/
└── all-apps.yaml
5.2 통합 ApplicationSet
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: all-apps
namespace: argocd
spec:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/org/gitops.git
revision: HEAD
directories:
- path: apps/*
- list:
elements:
- env: dev
cluster: https://dev-k8s.example.com
- env: staging
cluster: https://staging-k8s.example.com
- env: prod
cluster: https://prod-k8s.example.com
strategy:
type: RollingSync
rollingSync:
steps:
- matchExpressions:
- key: env
operator: In
values: [dev]
- matchExpressions:
- key: env
operator: In
values: [staging]
- matchExpressions:
- key: env
operator: In
values: [prod]
template:
metadata:
name: '{{path.basename}}-{{env}}'
labels:
app: '{{path.basename}}'
env: '{{env}}'
spec:
project: default
source:
repoURL: https://github.com/org/gitops.git
targetRevision: HEAD
path: '{{path}}/overlays/{{env}}'
destination:
server: '{{cluster}}'
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
6. ArgoCD CLI 운영 명령어
# ApplicationSet 상태 확인
argocd appset list
argocd appset get myapp-progressive
# 특정 Application Sync 상태
argocd app get myapp-prod --refresh
# 수동 Sync (Progressive에서 수동 승인 필요 시)
argocd app sync myapp-staging
# Rollout 상태 확인 (Argo Rollouts kubectl plugin)
kubectl argo rollouts status myapp -n myapp
kubectl argo rollouts get rollout myapp -n myapp -w
# Canary 수동 승인
kubectl argo rollouts promote myapp -n myapp
# 롤백
kubectl argo rollouts undo myapp -n myapp
7. 모범 사례
- Progressive Sync 필수: prod 배포 시 반드시 단계적 롤아웃
- AnalysisTemplate 연동: 메트릭 기반 자동 롤백 설정
- App of Apps 대신 ApplicationSet: 관리 복잡도 대폭 감소
- Matrix Generator 활용: 앱 × 환경 조합 자동화
- Sync Wave 활용: 의존성 있는 리소스 순서 제어
- Notification 연동: Slack/Telegram으로 배포 상태 알림
8. 퀴즈
Q1. ApplicationSet의 핵심 역할은?
하나의 템플릿에서 여러 ArgoCD Application을 자동 생성. 멀티클러스터/멀티환경 배포 자동화.
Q2. Matrix Generator는 어떻게 동작하는가?
두 Generator의 결과를 **교차 결합(Cartesian product)**하여 모든 조합에 대해 Application을 생성한다.
Q3. Progressive Sync의 maxUpdate: 50%는 무엇을 의미하는가?
해당 단계의 Application 중 50%만 동시에 Sync하고, 성공 후 나머지 50%를 진행한다.
Q4. Argo Rollouts의 AnalysisTemplate 실패 시 어떻게 되는가?
자동으로 롤백된다. failureLimit을 초과하면 Rollout이 Degraded 상태가 되고 이전 버전으로 복원.
Q5. Blue-Green에서 autoPromotionEnabled: false의 의미는?
Preview 환경 검증 후 수동으로 promote해야 Active로 전환된다. kubectl argo rollouts promote 명령 필요.
Q6. Canary 배포에서 trafficRouting을 설정하는 이유는?
실제 트래픽의 비율을 정밀하게 제어하기 위함. Istio/Nginx/ALB 등과 연동하여 Pod 수가 아닌 트래픽 비율 기반 Canary를 구현.
Q7. App of Apps 패턴 대비 ApplicationSet의 장점은?
(1) 단일 리소스로 관리 (2) Generator를 통한 자동 검색 (3) Progressive Sync 지원 (4) 코드 중복 제거