1. 들어가기 앞서
금융권 환경에서는 서비스 안정성과 규제 준수가 필요하다. 기존 ArgoCD Manual Sync 기반 배포에는 다음과 같은 문제가 존재한다. 수동 Sync 과정에서 휴먼 에러가 있을 수 있으며 트래픽 전환 과정에서 예상치 못한 장애가 발생할 수 있다.
- 롤백 부재
- 배포 실패 시 자동 롤백 기능 없음
- 장애 발생 시 전체 트래픽에 영향을 주어 서비스 중단 가능
- 기본 RollingUpdate 전략 한계
- Kubernetes Deployment의 RollingUpdate는 최소한의 안전 보장(readiness probe)만 제공
- 배포 속도 조절 불가, 외부 메트릭 검증 불가
- 트래픽 흐름 제어 불가, 단계별 중단/검증 불가
대규모 금융권 환경에서는 RollingUpdate 단독 사용이 위험하며, 점진적 배포와 안전한 롤백 전략이 필수적이다. 9월에 있는 EKS 업그레이드 이후 argo rollout + istio 를 활용한 canary 배포 전략을 도입하였다.
2. Argo Rollouts 이란?
Argo Rollouts는 Kubernetes Controller와 CRD(Custom Resource Definition)를 기반으로, 고급 배포 전략을 제공하는 도구이다. 단순 Deployment의 RollingUpdate가 제공하는 최소한의 안전성(readiness probe)만으로는 부족한, 금융권과 같이 안정성이 중요한 환경에서 유용하다.
- 배포 전략
- Blue-Green: 신규 버전을 별도의 서비스로 배포 후 검증 → 트래픽 전환
- Canary: 소량 트래픽을 신규 버전으로 점진적 전환 → KPI 분석 후 전체 배포
- 자동화 기능
- 단계별 트래픽 가중치 설정 및 자동 증감
- KPI 기반 Canary Analysis → 실패 시 자동 롤백
- Manual Judgment: 사용자가 Pause 상태에서 수동 결정 가능
- 외부 Metric 연동
- Prometheus, Datadog, New Relic, Wavefront 등 KPI 조회
3. Argo Rollouts 작동 원리
3.1 기본 구조
- Rollout CRD 생성 → Controller가 관리
- Rollout spec
- replicas: Pod 수
- strategy: Canary / Blue-Green / RollingUpdate
- steps: 트래픽 가중치, Pause, Analysis 정의
- spec.template: Pod template 변경 시 신규 ReplicaSet 생성
3.2 Rollout 동작 흐름
- 신규 ReplicaSet 생성
- spec.template 변경 감지 → 신규 ReplicaSet 생성
- 기존 ReplicaSet은 stable 상태 유지
- 트래픽 점진적 전환
- Canary: setWeight 단계별 트래픽 일부 신규 ReplicaSet으로 전환
- Blue-Green: Preview 서비스로 신규 버전 배포 후 Active 서비스로 전환
- KPI 기반 분석
- AnalysisRun 템플릿 통해 Metric Provider 조회
- 실패 시 자동 롤백
- Rollout 상태 관리
- 신규 ReplicaSet stable 도달 → Rollout 완료
- Manual Promotion 및 Abort 가능
- 실패 시 Degraded → stable로 복귀
4. 설치 및 환경 구성
apiVersion: v1
kind: Namespace
metadata:
name: argo-rollouts
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: argo-rollouts-controller
namespace: argo-rollouts
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: argo-rollouts
template:
spec:
containers:
- name: argo-rollouts
image: quay.io/argoproj/argo-rollouts:v1.6.0
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CONTROLLER_INSTANCEID
valueFrom:
fieldRef:
fieldPath: metadata.name
혹은 Public 접근에 대해 가능한 환경이라면 아래와 같이 쉽게 설치할 수 있다.
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
5. Istio와 통합된 Canary 배포 예제
5.1 Destination Rule 및 VirtualSerice 생성
# ==========================================
# 요약: 서비스 myapp-api에 대한 stable/canary 서브셋을 정의하며,
# Argo Rollout이 canary 트래픽 분배 시 참조
# ==========================================
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: myapp-api-dr
namespace: myapp
spec:
host: myapp-api
subsets:
- name: stable
labels:
version: stable
- name: canary
labels:
version: canary
# ==========================================
# 요약: myapp-api 서비스의 트래픽을 stable/canary로 분배
# Argo Rollout의 setWeight 단계에서 weight 값에 따라 트래픽 조절
# ==========================================
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-api-vs
namespace: myapp
spec:
hosts:
- myapp-api
http:
- route:
- destination:
host: myapp-api
subset: stable
weight: 100
- destination:
host: myapp-api
subset: canary
weight: 0
5.2 Rollout 리소스 생성
# ==========================================
# Argo Rollout: Canary 배포 정의
# 요약: myapp-api를 Canary 전략으로 배포하며, Istio VS/DR과 연동
# 단계별 트래픽 분배 및 AnalysisTemplate 참조 가능
# ==========================================
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp-api
namespace: myapp
spec:
replicas: 10
strategy:
canary:
# Rollout이 생성하는 서비스 이름
canaryService: myapp-api-canary
stableService: myapp-api-stable
trafficRouting:
istio:
virtualService:
name: myapp-api-vs # 반드시 위에서 생성한 VS 이름과 동일
routes:
- primary
destinationRule:
name: myapp-api-dr # 반드시 위에서 생성한 DR 이름과 동일
canarySubsetName: canary
stableSubsetName: stable
steps:
- setWeight: 10
- pause: {duration: 2m}
- analysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: myapp-api
- setWeight: 30
- pause: {duration: 5m}
- analysis:
templates:
- templateName: success-rate
- templateName: latency
args:
- name: service-name
value: myapp-api
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100
selector:
matchLabels:
app: myapp-api
template:
metadata:
labels:
app: myapp-api
version: canary # 신규 배포 시 Canary 서브셋 라벨
spec:
containers:
- name: myapp-api
image: myapp/api:latest
ports:
- containerPort: 8080
resources:
requests:
memory: 1Gi
cpu: 500m
limits:
memory: 2Gi
cpu: 1000m
- DR과 VS는 수동 생성 필요
- Rollout은 CanaryService/StableService를 생성하며, VS/DR을 참조하여 트래픽을 조절
- 각 단계별 setWeight로 Canary 트래픽 비율을 조절하며, pause와 analysis 단계로 검증 가능
5.3 최종 형태
┌─────────────┐
│ ALB/Ingress │
└─────┬───────┘
│
▼
┌─────────────────────┐
│ Istio IngressGateway │
└─────┬───────────────┘
Stable / Canary
│
┌────────┴─────────┐
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ Stable │ │ Canary │
│ Pods │ │ Pods │
└─────────┘ └─────────┘
6. 분석 템플릿 정의 (AMP 통합)
6.1 성공률 분석
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: i-booja
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 1m
count: 3
successCondition: result[0] >= 0.95
failureLimit: 2
provider:
prometheus:
address: https://aps-workspaces.ap-northeast-2.amazonaws.com/workspaces/ws-xxx
query: |
sum(rate(i_booja_requests_total{destination_service_name="{{args.service-name}}", response_code!~"5.*"}[2m])) /
sum(rate(i_booja_requests_total{destination_service_name="{{args.service-name}}"}[2m]))
authentication:
sigv4:
region: ap-northeast-2
roleArn: arn:aws:iam::ACCOUNT_ID:role/AMPQueryRole-i-booja
- 목적: 서비스 요청 중 성공률(success rate)을 측정하고, Canary 배포 중 안정성을 검증.
- args.service-name: 템플릿 실행 시 대상 서비스 이름을 전달.
- metrics 설정
- interval: 1m → 1분마다 쿼리 실행
- count: 3 → 총 3번 연속 측정
- successCondition: 성공률이 95% 이상일 경우 성공으로 간주
- failureLimit: 2 → 실패가 2회 이상 발생하면 Analysis 실패로 판단
- Prometheus 쿼리: 2분 동안 요청 수(rate) 대비 5xx가 아닌 요청 비율을 계산
6.2 지연시간 분석
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: latency
namespace: i-booja
spec:
args:
- name: service-name
metrics:
- name: latency-p95
interval: 1m
count: 3
successCondition: result[0] <= 2000
failureLimit: 2
provider:
prometheus:
address: https://aps-workspaces.ap-northeast-2.amazonaws.com/workspaces/ws-xxx
query: |
histogram_quantile(0.95,
sum(rate(istio_request_duration_milliseconds_bucket{destination_service_name="{{args.service-name}}"}[2m])) by (le))
- 목적: 서비스 응답 시간(latency)을 측정하고, Canary 배포 중 성능 저하를 검증.
- metrics 설정
- interval: 1m, count: 3 → 1분 간격으로 3번 측정
- successCondition: p95 응답 시간이 2000ms 이하이면 성공
- failureLimit: 2 → 연속 실패 2회 시 Analysis 실패
- Prometheus 쿼리: Istio에서 제공하는 istio_request_duration_milliseconds_bucket 히스토그램을 이용해 95번째 백분위(p95) 응답 시간 계산
Argo Rollout의 Canary 배포 단계에서 analysis 스텝에 이 템플릿을 연결하면, 트래픽 일부를 Canary에 보내면서 서비스 상태를 자동으로 모니터링 및 평가 가능
'CICD > argoCD 운영 특이사항' 카테고리의 다른 글
| [argocd] Origin is not allowed by Access-Control-Allow-Origin (0) | 2025.06.26 |
|---|---|
| [argocd] ArgoCD 재배포 중 장애 발생 TroubleShooting (3) | 2025.06.23 |
| [argocd] CustomResourceDefinition(CRD)가 삭제되지 않는 현상 (0) | 2025.06.23 |
