[Daily morning study] Kubernetes VPA와 오토스케일링 전략 비교 (HPA, VPA, Cluster Autoscaler)

#daily morning study

Image


Kubernetes 오토스케일링 종류

Kubernetes는 세 가지 주요 오토스케일링 메커니즘을 제공한다.

종류대상스케일 방향
HPA (Horizontal Pod Autoscaler)Pod 개수수평 (Pod 추가/제거)
VPA (Vertical Pod Autoscaler)Pod의 CPU/Memory 요청수직 (리소스 크기 변경)
Cluster Autoscaler (CA)Node 개수수평 (Node 추가/제거)

세 컴포넌트는 독립적으로 동작하지만 상호 보완적으로 함께 사용하는 경우가 많다.


HPA (Horizontal Pod Autoscaler)

동작 원리

HPA는 메트릭 서버(Metrics Server) 또는 커스텀 메트릭을 기반으로 Pod 레플리카 수를 자동 조절한다. 기본적으로 15초 주기로 메트릭을 평가하고, 목표 메트릭값과 현재값의 비율로 원하는 레플리카 수를 계산한다.

desiredReplicas = ceil[currentReplicas * (currentMetricValue / desiredMetricValue)]

예시

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: AverageValue
        averageValue: 500Mi

스케일업/다운 안정화

급격한 트래픽 변화에 대응하기 위해 behavior 필드로 스케일 속도를 조절할 수 있다.

behavior:
  scaleUp:
    stabilizationWindowSeconds: 0    # 즉시 스케일업
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleDown:
    stabilizationWindowSeconds: 300  # 5분 대기 후 스케일다운

한계

  • Pod 하나가 처리할 수 있는 한계를 넘는 워크로드에는 한계가 있다
  • 요청(requests) 값이 실제 사용량과 맞지 않으면 메트릭 기반 판단이 부정확해진다

VPA (Vertical Pod Autoscaler)

개념

VPA는 Pod의 CPU/Memory requests와 limits를 자동으로 조정한다. 실제 사용 패턴을 분석해서 적절한 리소스 값을 권장하거나 직접 적용한다.

구성 요소

컴포넌트역할
VPA Recommender히스토리 메트릭을 분석해 적절한 리소스 값 계산
VPA UpdaterVPA 정책에 따라 Out-of-Range Pod를 재시작
VPA Admission Controller새 Pod 생성 시 요청된 리소스 값을 권장값으로 변경

예시

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Auto"   # Off | Initial | Recreate | Auto
  resourcePolicy:
    containerPolicies:
    - containerName: my-container
      minAllowed:
        cpu: 100m
        memory: 128Mi
      maxAllowed:
        cpu: 2
        memory: 4Gi
      controlledResources: ["cpu", "memory"]

updateMode 종류

모드동작
Off권장값만 계산하고 적용하지 않음 (관찰 용도)
InitialPod 생성 시에만 권장값 적용, 실행 중에는 변경 없음
RecreateOut-of-Range Pod를 재시작하며 권장값 적용
Auto현재는 Recreate와 동일 동작 (인플레이스 업데이트 준비 중)

VPA 권장값 확인

kubectl describe vpa my-app-vpa

출력에서 Recommendation 섹션을 보면 현재 권장 CPU/Memory 값을 확인할 수 있다.

Recommendation:
  Container Recommendations:
    Container Name: my-container
    Lower Bound:
      Cpu:     100m
      Memory:  256Mi
    Target:
      Cpu:     250m
      Memory:  512Mi
    Upper Bound:
      Cpu:     500m
      Memory:  1Gi

VPA의 한계

  • HPA와 동시 사용 시 충돌: CPU/Memory 기반 HPA와 VPA를 동시에 사용하면 서로 다른 방향으로 스케일하려 해서 충돌이 생긴다. VPA는 커스텀 메트릭 기반 HPA와 함께 사용하거나, VPA는 Off 모드로만 운영하는 방식을 권장한다
  • Pod 재시작 필요: 현재 VPA는 리소스 변경 시 Pod를 재시작해야 한다 (인플레이스 업데이트는 alpha 단계)
  • 짧은 주기 워크로드: 실행 시간이 짧은 배치 잡은 충분한 히스토리 데이터를 수집하기 어렵다

Cluster Autoscaler (CA)

동작 원리

CA는 Pod가 리소스 부족으로 Pending 상태가 됐을 때 Node를 추가하고, Node의 사용률이 낮고 Pod를 다른 Node로 옮길 수 있을 때 Node를 제거한다.

Pending Pod 발생
    ↓
CA가 새 Node를 추가하면 스케줄링 가능한지 시뮬레이션
    ↓
가능하면 Cloud Provider API를 호출해 Node 추가
    ↓
Node가 Ready 상태가 되면 Pod 스케줄링

AWS EKS에서의 설정

EKS에서는 Auto Scaling Group(ASG)의 min/max capacity로 Node 수 범위를 정하고, CA가 ASG를 제어한다.

# Cluster Autoscaler 배포 예시 (일부)
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
- --scale-down-utilization-threshold=0.5
- --scale-down-delay-after-add=10m

스케일다운 조건

Node 제거는 다음 조건을 모두 충족할 때 일어난다.

  • Node의 전체 리소스 사용률이 scale-down-utilization-threshold 미만 (기본 50%)
  • Node의 Pod를 다른 Node로 이동할 수 있음 (PDB, affinity 등 고려)
  • scale-down-delay-after-add 시간이 경과함 (기본 10분)

PodDisruptionBudget(PDB)을 설정해두면 CA가 Node를 제거할 때 최소 가용 Pod 수를 보장한다.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-app-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: my-app

Karpenter (CA의 현대적 대안)

AWS에서 만든 오픈소스 Node 프로비저너로, CA보다 빠르고 유연하다.

항목Cluster AutoscalerKarpenter
Node 프로비저닝 속도수분수십 초
인스턴스 타입 선택ASG 기반, 미리 정의 필요Pod 요구사항에 맞춰 자동 선택
통합Cloud Provider 의존적AWS 네이티브, 직접 EC2 API 호출

세 가지 오토스케일러 함께 사용하기

일반적인 권장 조합은 다음과 같다.

트래픽 증가
    ↓
HPA가 Pod 수를 늘림
    ↓
Node 리소스 부족으로 Pod가 Pending
    ↓
Cluster Autoscaler(또는 Karpenter)가 Node 추가
    ↓
Pod 스케줄링 완료

VPA는 주로 Off 모드로 리소스 권장값을 관찰하거나, 트래픽이 일정한 배치 작업, 데이터베이스처럼 수평 확장이 어려운 Stateful 워크로드에 적용한다.

조합 시 주의사항

  • CPU/Memory 기반 HPA와 VPA Auto 모드를 동시에 사용하지 않는다
  • VPA가 requests를 늘리면 CA의 스케일다운 기준이 달라질 수 있다
  • Node 추가 지연(수분)을 고려해 HPA의 minReplicas를 넉넉하게 설정한다

실제 운영 팁

requests 값 설정이 핵심이다. HPA와 CA 모두 requests 값을 기준으로 동작한다. requests가 너무 낮으면 스케일 트리거가 늦고, 너무 높으면 Node 리소스가 낭비된다. VPA의 Off 모드로 실제 사용 패턴을 수집한 다음 requests 값을 튜닝하는 방식이 안전하다.

Vertical Pod Autoscaler in-place update: Kubernetes 1.27부터 인플레이스 리소스 업데이트 기능이 alpha로 추가됐다. 이 기능이 stable해지면 VPA가 Pod 재시작 없이 리소스를 변경할 수 있어 훨씬 활용도가 높아질 것이다.