평소에는 Pod 3개로 충분한데 트래픽이 갑자기 10배가 되면, 수동으로 replicas를 바꿔야 할까요?

정적인 replicas 설정으로는 트래픽 변동에 대응할 수 없습니다. Kubernetes는 HPA(Horizontal Pod Autoscaler)와 VPA(Vertical Pod Autoscaler)로 트래픽에 따라 자동으로 Pod을 조절합니다.

HPA (Horizontal Pod Autoscaler)

HPA는 메트릭을 기반으로 Pod의 수를 자동으로 늘리거나 줄입니다.

기본 설정 — CPU 기반

YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70  # CPU 사용률 70% 목표
SHELL
# 명령어로 간단히 생성
kubectl autoscale deployment web-app --min=2 --max=20 --cpu-percent=70

필수 조건: Metrics Server

HPA가 동작하려면 Metrics Server가 설치되어 있어야 합니다.

SHELL
# Metrics Server 설치
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 동작 확인
kubectl top nodes
kubectl top pods

스케일링 알고리즘

HPA는 다음 공식으로 필요한 replicas를 계산합니다.

PLAINTEXT
필요 replicas = ceil(현재 replicas × (현재 메트릭 / 목표 메트릭))

예: 현재 3개 Pod, CPU 사용률 90%, 목표 70%

PLAINTEXT
ceil(3 × (90 / 70)) = ceil(3.86) = 4

다중 메트릭

YAML
spec:
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:

나머지 설정을 이어서 정의합니다.

YAML
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "1000"

여러 메트릭을 설정하면 가장 많은 replicas를 요구하는 메트릭 이 적용됩니다.

behavior — 스케일링 속도 제어

급격한 변동(flapping)을 방지하고 스케일링 속도를 세밀하게 제어합니다.

YAML
spec:
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0    # 즉시 스케일 업
      policies:
        - type: Percent
          value: 100                   # 현재 수의 100%까지 한 번에 증가 가능
          periodSeconds: 60
        - type: Pods
          value: 4                     # 또는 한 번에 최대 4개 추가
          periodSeconds: 60
      selectPolicy: Max                # 두 정책 중 큰 값 적용

scaleDown 설정에서는 stabilizationWindow를 두어 급격한 스케일 다운으로 인한 flapping을 방지합니다.

YAML
    scaleDown:
      stabilizationWindowSeconds: 300  # 5분간 안정화 후 스케일 다운
      policies:
        - type: Percent
          value: 10                    # 한 번에 10%씩만 감소
          periodSeconds: 60

스케일 업은 빠르게, 스케일 다운은 천천히 하는 것이 일반적인 전략입니다.

커스텀 메트릭으로 HPA

Prometheus Adapter를 설치하면 Prometheus 메트릭으로 HPA를 구성할 수 있습니다.

YAML
spec:
  metrics:
    - type: Object
      object:
        metric:
          name: requests_per_second
        describedObject:
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          name: web-ingress
        target:
          type: Value
          value: "2000"

VPA (Vertical Pod Autoscaler)

VPA는 Pod의 CPU/메모리 requests를 자동으로 조절합니다.

YAML
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  updatePolicy:
    updateMode: "Auto"    # 자동 적용

resourcePolicy에서 각 컨테이너의 리소스 허용 범위를 지정하여 VPA가 과도한 리소스를 할당하지 않도록 제한합니다.

YAML
  resourcePolicy:
    containerPolicies:
      - containerName: app
        minAllowed:
          cpu: 100m
          memory: 128Mi
        maxAllowed:
          cpu: 2
          memory: 4Gi
        controlledResources: ["cpu", "memory"]

updateMode 옵션

모드동작사용 사례
Off추천만 제공, 변경 없음적정 리소스 파악
InitialPod 생성 시에만 적용재시작 최소화
RecreatePod을 재생성하여 적용프로덕션
Auto최적의 방법으로 적용기본값
SHELL
# VPA 추천값 확인
kubectl describe vpa web-vpa
# Recommendation:
#   Container: app
#     Lower Bound:  Cpu: 100m, Memory: 256Mi
#     Target:       Cpu: 250m, Memory: 512Mi
#     Upper Bound:  Cpu: 500m, Memory: 1Gi

VPA의 한계

  • **Pod 재시작이 필요합니다 **: 리소스 변경 시 Pod을 재생성합니다
  • **HPA와 동시 사용 제한 **: 같은 메트릭(CPU)으로 HPA와 VPA를 동시에 사용하면 충돌합니다
  • **Stateful 워크로드 주의 **: 재시작이 빈번하면 서비스에 영향을 줄 수 있습니다

HPA + VPA 조합 전략

PLAINTEXT
HPA: 커스텀 메트릭(RPS) 기반으로 Pod 수 조절
VPA: CPU/메모리 기반으로 리소스 크기 조절

같은 메트릭을 기반으로 하지 않으면 동시 사용이 가능합니다.

KEDA (Kubernetes Event-Driven Autoscaling)

KEDA는 외부 이벤트 소스(Kafka, RabbitMQ, Prometheus 등)를 기반으로 스케일링합니다. 0개까지 스케일 다운할 수 있어 이벤트가 없을 때 리소스를 절약합니다.

YAML
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaler
spec:
  scaleTargetRef:
    name: kafka-consumer
  minReplicaCount: 0    # 이벤트 없으면 0으로 스케일 다운
  maxReplicaCount: 50
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka:9092
        consumerGroup: my-group
        topic: orders
        lagThreshold: "100"  # 컨슈머 랙 100 초과 시 스케일 업

KEDA 지원 이벤트 소스 (일부)

소스메트릭
Kafka컨슈머 랙
RabbitMQ큐 길이
Prometheus커스텀 쿼리
AWS SQS메시지 수
Cron시간 기반
HTTP요청 수
SHELL
# KEDA 설치
helm install keda kedacore/keda --namespace keda --create-namespace

Cluster Autoscaler — 노드 수준 스케일링

HPA/VPA가 Pod 수준이라면, Cluster Autoscaler는 노드를 추가/제거합니다.

PLAINTEXT
트래픽 증가 → HPA가 Pod 수 증가 → 노드 리소스 부족 → Cluster Autoscaler가 노드 추가
트래픽 감소 → HPA가 Pod 수 감소 → 노드 유휴 → Cluster Autoscaler가 노드 제거

오토스케일링 디버깅

SHELL
# HPA 상태 확인
kubectl get hpa web-hpa
# NAME      REFERENCE       TARGETS    MINPODS   MAXPODS   REPLICAS
# web-hpa   Deployment/web  45%/70%    2         20        3

# HPA 이벤트 확인
kubectl describe hpa web-hpa

# 메트릭 확인
kubectl top pods -l app=web

자주 만나는 문제

증상원인해결
TARGETS가 <unknown>Metrics Server 미설치 또는 requests 미설정Metrics Server 설치, requests 추가
스케일 업이 느림stabilizationWindow가 긴 경우behavior 조정
최대치에서 멈춤maxReplicas 도달maxReplicas 증가 또는 노드 추가
계속 스케일 업/다운 반복목표값이 경계에 있음목표값 조정 또는 window 확대

주의할 점

1. HPA와 VPA를 같은 메트릭(CPU/메모리)으로 동시에 사용하면 충돌한다

HPA가 CPU 사용률을 보고 Pod 수를 늘리는데, VPA도 CPU를 보고 requests를 올리면 HPA의 계산 기준이 바뀌어 스케일링이 불안정해집니다. 두 가지를 함께 쓰려면 HPA는 커스텀 메트릭(RPS 등)으로, VPA는 CPU/메모리로 역할을 분리해야 합니다.

2. requests를 설정하지 않으면 HPA의 CPU 목표치가 동작하지 않는다

HPA의 targetAverageUtilization은 requests 대비 사용률(%)입니다. requests가 없으면 비율을 계산할 수 없어서 TARGETS 컬럼에 <unknown>이 표시되고 스케일링이 전혀 동작하지 않습니다. Metrics Server가 정상인데도 HPA가 작동하지 않으면 requests 설정부터 확인하세요.

3. minReplicas를 1로 설정하면 스케일 다운 시 단일 장애점이 된다

트래픽이 줄어들면 HPA가 Pod을 1개까지 줄이는데, 이 상태에서 Pod이 죽거나 노드 장애가 발생하면 서비스가 완전히 중단됩니다. 프로덕션 서비스의 minReplicas는 최소 2 이상으로 설정하세요.

정리

HPA는 Pod 수를 늘려 수평 확장하고, VPA는 Pod의 리소스를 키워 수직 확장합니다. KEDA는 Kafka 큐 같은 외부 이벤트 기반 스케일링을 가능하게 합니다. behavior 설정으로 스케일링 속도를 제어하고, Cluster Autoscaler와 연계하면 노드까지 자동으로 관리할 수 있습니다.

댓글 로딩 중...