Ssoon
Argo Rollouts - HPA & VPA 본문
⚙️ Horizontal Pod Autoscaling(HPA)와 Argo Rollouts 연동
- Argo Rollouts는 Kubernetes의 **Horizontal Pod Autoscaler(HPA)**와 연동하여, 애플리케이션 로드에 따라 자동으로 Pod 수를 조절할 수 있습니다.
🔧 HPA Support in Argo Rollouts
- Argo Rollouts는 autoscaling/v2beta 이상의 API 또는 Kubernetes 1.23+에서 지원되는 autoscaling/v2 API와 연동됩니다.
- 이 API를 통해 HPA는 custom resources를 대상으로 Pod 수를 조절할 수 있으며, Argo Rollout 객체도 대상이 됩니다.
- HPA는 Rollout 객체의 /scale subresource를 이용해 현재 Pod 수(status.replicas)를 읽고, 필요 시 spec.replicas 필드를 갱신하여 원하는 Pod 수를 조절합니다.
"HPA는 Rollout의 spec.replicas 값을 조절하고,
Argo Rollouts가 실제 Pod 수를 관리합니다."
⚙️ How HPA Works with Argo Rollouts
- HPA는 Pod의 CPU, 메모리, custom metrics를 모니터링하여 스케일링이 필요한지 판단합니다.
- HPA는 직접 ReplicaSet이나 Pod를 조절하지 않고, Rollout의 spec.replicas에 원하는 Pod 수를 기록합니다.
- Rollout 컨트롤러가 변경 사항을 감지하면, 실제 ReplicaSet에 Pod 생성/삭제 명령을 수행합니다.
"HPA는 스케일링 의사결정을 하고,
Rollout 컨트롤러가 배포를 실행합니다."
📝 Example Configuration
1️⃣ Rollout 설정
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollout-hpa-example
spec:
replicas: 3
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo
image: https://github.com/argoproj/rollouts-demo
ports:
- containerPort: 8080
strategy:
blueGreen: # 또는 canary
autoPromotionEnabled: false
"Rollout 객체가 HPA의 대상이며,
기본 Pod 수는 3입니다."
2️⃣ Service 설정
apiVersion: v1
kind: Service
metadata:
name: argo-rollouts-stable-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: demo
---
apiVersion: v1
kind: Service
metadata:
name: argo-rollouts-preview-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: demo
"Stable과 Preview 두 개의 Service로 트래픽을 분리합니다."
3️⃣ Horizontal Pod Autoscaler 설정
apiVersion: autoscaling/v2 # HPA 리소스가 사용하는 API 버전 (v2: 최신 기능/필드 지원)
kind: HorizontalPodAutoscaler # 생성하려는 리소스 유형: HPA(수평 자동 스케일러)
metadata:
name: demo-hpa # HPA의 이름 (클러스터 내에서 고유해야 함)
labels:
app: demo # 라벨: 리소스 분류/선택용 메타데이터
spec:
minReplicas: 1 # 최소 Pod 수 (최소 1개 유지)
maxReplicas: 10 # 최대 Pod 수 (최대 10개까지 확장)
scaleTargetRef: # 스케일링 대상(어떤 리소스를 늘리고 줄일지)
apiVersion: argoproj.io/v1alpha1 # 대상 리소스의 API 버전 (Argo Rollouts의 API 그룹/버전)
kind: Rollout # 대상 리소스 종류: Rollout(Argo Rollouts가 관리하는 배포 객체)
name: rollout-hpa-example # 대상 리소스 이름 (이 Rollout의 Pod 수를 조정)
metrics: # 스케일링 의사결정에 사용할 지표 설정들(여러 개 가능)
- type: Resource # '리소스' 타입의 메트릭 사용(CPU, 메모리 등)
resource:
name: memory # 메모리 사용량을 지표로 삼음
target:
type: AverageValue # 목표 값을 '평균 절대값'으로 지정
averageValue: 16Mi # 모든 활성 Pod의 평균 메모리 사용량 목표치(16MiB).
# 평균이 16Mi를 '넘으면' 스케일 아웃(증설), '충분히 낮아지면' 스케일 인(축소)
"HPA가 Rollout을 모니터링하고,
Pod 수를 자동으로 조절합니다."
🔵 Blue/Green Deployments with HPA
- Blue/Green 전략에서는 active(Blue)와 preview(Green) 두 ReplicaSet을 관리합니다.
- HPA가 spec.replicas를 갱신하면, Rollout 컨트롤러가 두 ReplicaSet에 동일하게 적용합니다.
- 전체 롤아웃 후, preview가 stable이 되면 이전 active ReplicaSet은 0으로 스케일되고, 이후 HPA는 stable ReplicaSet만 관리합니다.
strategy: # 배포 전략을 정의하는 섹션
blueGreen: # Blue-Green 방식 사용
previewService: argo-rollouts-preview-service
# 새 버전(그린) Pod를 연결할 프리뷰 서비스 이름
# 테스트용으로 트래픽을 일부 보내거나 확인할 때 사용
activeService: argo-rollouts-stable-service
# 현재 운영 중(블루) Pod를 연결하는 서비스 이름
# 실제 사용자 트래픽이 이 서비스로 전달됨
autoPromotionEnabled: false # 새 버전으로 자동 승격 여부
# false → 자동으로 그린을 블루로 바꾸지 않음
"Blue/Green 배포에서는 HPA가 두 버전을 동시에 스케일링하지만,
롤아웃 후에는 stable만 관리합니다."
💡 previewReplicaCount 활용
strategy: # 배포 전략을 정의하는 섹션
blueGreen: # Blue-Green 방식 사용
previewService: argo-rollouts-preview-service
# 새 버전(그린) Pod를 연결할 프리뷰 서비스 이름
# 테스트용으로 트래픽을 일부 보내거나 확인할 때 사용
activeService: argo-rollouts-stable-service
# 현재 운영 중(블루) Pod를 연결하는 서비스 이름
# 실제 사용자 트래픽이 이 서비스로 전달됨
previewReplicaCount: 1 # 프리뷰 환경에서 실행할 Pod 개수
# 새 버전 테스트용으로 최소 1개만 띄움
autoPromotionEnabled: false # 새 버전으로 자동 승격 여부
# false → 자동으로 그린을 블루로 바꾸지 않음
# 즉, 승격은 수동으로 진행해야 함
- previewReplicaCount를 지정하면, preview ReplicaSet은 고정된 Pod 수를 유지하고, HPA는 stable ReplicaSet만 조절합니다.
- 이로 인해 리소스 비용을 절약하고, 테스트 중에도 예측 가능한 환경을 유지할 수 있습니다.
"previewReplicaCount는 HPA의 영향을 받지 않고
preview Pod 수를 고정합니다."
🟡 Canary Deployments with HPA
1️⃣ Canary without Traffic Manager
- setWeight를 통해 Canary와 stable Pod 수 비율을 정의합니다.
- HPA가 총 Pod 수를 결정하고, Rollout 컨트롤러가 setWeight 기준으로 Canary/Stable Pod 수를 계산합니다.
canary_replicas = ceil(HPA_total_desired_replicas * setWeight / 100)
stable_replicas = HPA_total_desired_replicas - canary_replicas
- 예시: HPA가 10개의 Pod 필요 → setWeight 20% → Canary 2개, Stable 8개
"HPA는 전체 Pod 수를 결정하고,
Rollout 컨트롤러가 setWeight에 따라 분배합니다."
2️⃣ Canary with Traffic Manager (Traefik/ Istio 등)
- Traffic Manager가 트래픽 분배를 담당합니다.
- Rollout은 trafficRouting 설정을 통해 트래픽 비율을 Traffic Manager에 전달합니다.
- Pod 수와 트래픽 분배가 분리되어, Canary 트래픽을 안정적으로 조절할 수 있습니다.
strategy: # Rollout에서 사용할 배포 전략 정의 섹션
canary: # Canary 전략 사용
canaryService: canary-service # '새 버전(Canary) Pod'를 바라보는 Service (가중치 일부 트래픽을 이쪽으로 보냄)
stableService: stable-service # '안정판(Stable) Pod'를 바라보는 Service (기본/대부분 트래픽 대상)
trafficRouting: # 트래픽을 어떻게 분배할지에 대한 라우팅 설정
traefik: # Traefik를 사용하여 트래픽 가중치 조절
weightedTraefikServiceName: traefik-service
# Traefik에서 가중치 라우팅을 적용할 'TraefikService' 리소스 이름
# Argo Rollouts가 이 리소스의 weight를 조정해 canary/stable 비율을 바꿈
steps: # Canary 진행 단계(시나리오)를 순서대로 정의
- setWeight: 20 # 현재 릴리스 트래픽의 20%를 canaryService로, 80%를 stableService로 보냄
setCanaryScale:
replicas: 1 # 의미: canary 쪽은 Pod 복제수를 1로 제한(리소스 절약/리스크 제한)
- pause: {} # 다음 단계로 자동 진행하지 않고 '일시정지'
- setCanaryScale를 사용하면 Canary ReplicaSet을 고정하고, HPA는 stable만 스케일링합니다.
"Traffic Manager와 setCanaryScale를 활용하면
Canary 트래픽과 리소스 사용량을 독립적으로 관리할 수 있습니다."
🏆 Best Practices
- 배포 전략 선택: 단순한 배포는 Blue/Green, 비용 최적화는 previewReplicaCount, 안정적 Canary는 setCanaryScale 사용
- 모니터링 필수: stable과 Canary 모두 성능 지표를 모니터링
- HPA 설정 최적화: min/max Pod 수와 목표 메트릭 값을 애플리케이션 특성에 맞게 설정
- 롤백 시나리오 테스트: Canary 롤백 시 manual scaling 필요할 수 있음
- 리소스 요청/제한 설정: Pod 리소스 요청과 제한을 적절히 설정하여 HPA가 정확하게 동작하도록 지원
"적절한 전략, 모니터링, HPA 설정과 리소스 관리가
성공적인 롤아웃 핵심입니다."
📌핵심 요약
- Argo Rollouts는 HPA와 연동해 Pod 수를 자동 스케일링합니다.
- HPA는 spec.replicas만 수정하고, Rollout 컨트롤러가 실제 Pod 수를 조절합니다.
- Blue/Green 배포는 HPA가 두 ReplicaSet을 동시에 스케일링하며, previewReplicaCount로 preview Pod를 고정할 수 있습니다.
- Canary 배포는 setWeight와 setCanaryScale를 활용하여 트래픽과 Pod 수를 독립적으로 관리할 수 있습니다.
- Traffic Manager(Traefik, Istio 등)를 활용하면 Canary 트래픽 분배를 Pod 수와 독립적으로 제어할 수 있습니다.
- 모니터링, 리소스 제한 설정, HPA 최적화, 롤백 대비가 성공적인 롤아웃의 필수 요소입니다.
⚡ Vertical Pod Autoscaling (VPA)
- Kubernetes에서 **Vertical Pod Autoscaling(VPA)**은 클러스터 리소스 사용률을 최적화하고 관리 비용을 줄이기 위해 Pod의 리소스 요구사항(cpu, memory)을 자동으로 조정해주는 기능
⚙️ VPA 모드(VPA Modes)
VPA는 4가지 모드로 운영될 수 있으며, 각 모드는 Pod 리소스 요청을 업데이트하는 방식이 다릅니다.
- Auto
- Pod 생성 시 리소스 요청을 자동으로 설정하고 기존 Pod도 업데이트합니다.
- 현재는 Recreate 모드와 동일하게 동작하며, 추후 restart-free("in-place") 업데이트가 지원되면 자동으로 적용됩니다.
- ⚠️ 실험적 기능으로, 다운타임이 발생할 수 있음.
- "Auto 모드는 향후 restart-free 업데이트를 활용할 수 있는 가장 유연한 모드입니다."
- Recreate
- Pod 생성 시 리소스를 설정하고, 기존 Pod는 새로운 권장 사항과 큰 차이가 있으면 강제 재시작(evict) 합니다.
- Pod Disruption Budget(PDB)이 정의되어 있다면 이를 존중합니다.
- ⚠️ 실험적 기능으로, 다운타임이 발생할 수 있음.
- "Recreate 모드는 리소스 변경 시 반드시 Pod를 재시작해야 할 때 사용합니다."
- Initial
- Pod 생성 시 한 번만 리소스를 설정하며, 이후 변경하지 않습니다.
- "Initial 모드는 초기 설정만 필요할 때 적합합니다."
- Off
- Pod 리소스를 자동으로 변경하지 않지만, 추천 값은 계산되어 VPA 객체에서 확인 가능합니다.
- "Off 모드는 VPA 추천만 참고하고 직접 수동으로 관리할 때 사용됩니다."
📝 VPA와 Argo-Rollouts 연동 예제
아래는 Rollout Sample App과 VPA를 적용한 예시입니다.
1️⃣ Rollout Sample App
apiVersion: argoproj.io/v1alpha1 # Argo Rollouts CRD가 사용하는 API 버전
kind: Rollout # 리소스 유형: Rollout (Deployment 대신 Rollout으로 점진 배포 지원)
metadata:
name: vpa-demo-rollout # Rollout 리소스의 이름
namespace: test-vpa # 배포할 네임스페이스
spec:
replicas: 5 # 전체 목표 Pod 수 (안정/카나리 합쳐서 5개를 유지)
strategy:
canary: # 배포 전략: Canary (단계적으로 새 버전 확대)
steps: # Canary 진행 단계(스텝) 정의
- setWeight: 20 # 새 버전(카나리) 비중을 20%로 설정
# ⚠ trafficRouting 미지정 시 '트래픽 비중'이 아닌
# 'ReplicaSet 비율'로 해석되어 카나리 Pod 수만 20%에 맞춰 늘어남
- pause: {duration: 10} # 다음 단계로 넘어가기 전 10초 대기 (모니터링/확인 용)
- setWeight: 40 # 카나리 비중을 40%로 증가 (복제 수 기준)
- pause: {duration: 10} # 10초 대기
- setWeight: 60 # 카나리 비중을 60%로 증가 (복제 수 기준)
- pause: {duration: 10} # 10초 대기
- setWeight: 80 # 카나리 비중을 80%로 증가 (복제 수 기준)
- pause: {duration: 10} # 10초 대기
revisionHistoryLimit: 10 # 이전 ReplicaSet(리비전)을 최대 10개까지 보존 (롤백/추적에 유용)
selector: # Pod 선택자 (Rollout가 관리할 Pod 범위 지정)
matchLabels:
app: vpa-demo-rollout # 이 라벨을 가진 Pod가 Rollout에 의해 관리됨
template: # 새 버전(카나리/안정판 모두)의 Pod 템플릿 (Deployment의 template과 동일 개념)
metadata:
labels:
app: vpa-demo-rollout # Pod에 붙일 라벨 (selector와 일치해야 함)
spec:
containers:
- name: vpa-demo-rollout # 컨테이너 이름
image: ravihari/nginx:v1 # 컨테이너 이미지 (버전 v1; 새 릴리스 시 v2 등으로 변경)
ports:
- containerPort: 80 # 컨테이너가 노출하는 포트
resources:
requests: # 최소 보장 리소스 요청치 (스케줄링 판단에 사용)
cpu: "5m" # CPU 5 밀리코어 (매우 작은 값: 0.005 vCPU)
memory: "5Mi" # 메모리 5 MiB (매우 작은 값)
- 각 Pod는 초기 CPU 요청 5m, 메모리 5Mi로 시작합니다.
- "Rollout은 Canary 전략으로 점진적 업데이트를 관리합니다."
2️⃣ VPA 구성 예제
apiVersion: "autoscaling.k8s.io/v1beta2" # VPA CRD의 API 버전 (클러스터/설치 버전에 따라 다를 수 있음)
kind: VerticalPodAutoscaler # 리소스 유형: VPA
metadata:
name: vpa-rollout-example # VPA 리소스의 이름
namespace: test-vpa # 위치할 네임스페이스 (대상 Rollout과 동일 네임스페이스 권장)
spec:
targetRef: # VPA가 대상으로 삼을 워크로드(컨트롤러) 지정
apiVersion: "argoproj.io/v1alpha1" # 대상의 API 버전: Argo Rollouts
kind: Rollout # 대상 종류: Rollout
name: vpa-demo-rollout # 대상 이름 (이 Rollout이 만드는 Pod의 requests를 조정)
updatePolicy: # VPA가 추천치를 적용하는 방식(모드)
updateMode: "Auto" # "Auto": VPA Updater가 Pod를 재시작(퇴거)시켜 요청치 적용
# "Initial": 최초 생성 시에만 적용
# "Off": 추천만 하고 적용하지 않음 (status/recommendation 확인용)
resourcePolicy: # 컨테이너별 튜닝 범위/한도 정책
containerPolicies:
- containerName: '*' # 모든 컨테이너에 동일 정책 적용 (이름 매칭 가능)
minAllowed: # VPA가 내려줄 수 있는 최소 요청 한도(바닥)
cpu: 5m # CPU 최소 5 millicores(0.005 vCPU) 이하로 낮추지 않음
memory: 5Mi # 메모리 최소 5Mi 이하로 낮추지 않음
maxAllowed: # VPA가 올릴 수 있는 최대 요청 한도(천장)
cpu: 1 # CPU 최대 1 vCPU까지
memory: 500Mi # 메모리 최대 500Mi까지
controlledResources: ["cpu", "memory"] # VPA가 실제로 조정할 리소스 종류(요청치 기준)
- Auto 모드를 사용하여 VPA가 리소스 추천을 자동으로 적용합니다.
- CPU와 메모리의 최소/최대 허용값을 지정하여 Pod가 과도하게 리소스를 사용하는 것을 방지합니다.
- "VPA는 리소스 추천과 정책에 따라 Pod의 요청을 자동으로 조정합니다."
⏱️ VPA 추천 확인 과정
- 초기 배포 후: 몇 분 동안 VPA는 추천을 계산하지 않으므로 추천 정보는 표시되지 않습니다.
kubectl describe vpa kubengix-vpa -n test-vpa
- 몇 분 후: VPA가 추천을 생성하면 RecommendationProvided 상태가 표시됩니다.
Status:
Conditions:
Type: RecommendationProvided
Status: True
Recommendation:
Container Recommendations:
Container Name: vpa-demo-rollout
Lower Bound:
Cpu: 25m
Memory: 262144k
Target:
Cpu: 25m
Memory: 262144k
Upper Bound:
Cpu: 1
Memory: 500Mi
- "추천에는 Lower Bound, Target, Upper Bound가 포함되어 있어 Pod 리소스 범위를 쉽게 확인할 수 있습니다."
🔄 추천 적용 후 Pod 상태
kubectl get po -n test-vpa -w
- 기존 Pod는 리소스가 변경되어 Terminating 상태가 되고, 새 Pod가 생성됩니다.
- 새 Pod는 VPA 추천 값에 맞춰 CPU와 메모리가 자동으로 설정됩니다.
kubectl describe po vpa-demo-rollout-f5df6d577-vdlqq -n test-vpa
- Requests가 업데이트됨을 확인할 수 있습니다:
- CPU: 25m
- Memory: 262144k
- "VPA는 Pod를 재시작하여 최신 추천 값이 적용되도록 자동으로 관리합니다."
🛠️ VPA 요구사항
- Kubernetes 버전
- VPA는 Rollout CRD를 조작하기 위해 CRD subresources를 지원해야 합니다.
- Kubernetes v1.10: alpha 기능, feature flag 필요
- Kubernetes v1.11 이상: 기본 활성화
- RBAC 설정
- system:vpa-target-reader ClusterRole에 Rollouts 관련 권한 추가 필요
- apiGroups:
- argoproj.io # 접근을 허용할 API 그룹 (Argo Rollouts CRD가 속한 그룹)
resources:
- rollouts # Rollout 리소스에 대한 접근 허용
- rollouts/scale # Rollout의 scale 서브리소스 접근 허용 (replica 수 조정)
- rollouts/status # Rollout의 status 서브리소스 접근 허용 (상태 조회)
- replicasets # ReplicaSet 리소스 접근 허용 (Rollout이 생성하는 하위 리소스)
verbs:
- get # 리소스 단건 조회 허용
- list # 리소스 목록 조회 허용
- watch # 리소스 변경 이벤트 감시 허용
- Metrics-Server 설치 필요
- OpenSSL 최신 버전 필요 (VPA 최신 버전 추천 적용)
"VPA를 사용하려면 적절한 RBAC, Metrics-Server, 최신 OpenSSL 환경이 필요합니다."
📌 핵심 요약
- VPA는 Pod의 CPU/Memory 요청을 자동으로 관리하여 리소스 효율성을 높입니다.
- 운영 모드는 Auto, Recreate, Initial, Off가 있으며, 각 모드마다 Pod 업데이트 방식이 다릅니다.
- VPA 추천 후 기존 Pod는 종료되고, 새 Pod는 추천 값으로 자동 생성됩니다.
- RBAC, Metrics-Server, OpenSSL 설정이 제대로 되어야 정상 동작합니다.
- "Vertical Pod Autoscaler는 클러스터 리소스를 최적화하고 관리 부담을 줄이는 필수 Kubernetes 기능입니다."
'CICD Study [1기]' 카테고리의 다른 글
| Argo CD - Cluster Management (0) | 2025.11.20 |
|---|---|
| Argo Rollouts 설치 및 Sample 테스트 (0) | 2025.10.26 |
| Argo Rollouts - 배포 전략 (0) | 2025.10.19 |
| Argo Rollouts - Architecture (0) | 2025.10.19 |
| Argo Rollouts - 개념들 (0) | 2025.10.19 |
Comments