K8s HPA 오토스케일링 심화

K8s HPA란? 수평 파드 오토스케일링의 핵심

Kubernetes HPA(Horizontal Pod Autoscaler)는 워크로드의 CPU, 메모리 또는 커스텀 메트릭을 기반으로 파드 수를 자동 조절하는 핵심 오토스케일링 메커니즘입니다. 트래픽 급증 시 자동 확장하고, 유휴 시 축소하여 비용과 성능을 동시에 최적화합니다.

이 글에서는 HPA v2 API의 다중 메트릭 스케일링, 커스텀·외부 메트릭 연동, 스케일링 행동(behavior) 정밀 제어, KEDA 연동까지 실무 운영에 필요한 심화 전략을 다룹니다.

HPA v2 기본 구조와 동작 원리

HPA 컨트롤러는 기본 15초 주기로 메트릭을 수집하고, 목표 대비 현재 사용률을 비교하여 파드 수를 결정합니다. 핵심 공식은 다음과 같습니다:

desiredReplicas = ceil(currentReplicas × (currentMetricValue / desiredMetricValue))

예를 들어, 현재 3개 파드가 CPU 80%를 사용하고 목표가 50%라면: ceil(3 × 80/50) = 5개로 스케일아웃됩니다.

기본 HPA 매니페스트

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 75

다중 메트릭을 지정하면 HPA는 각 메트릭별로 필요한 레플리카 수를 계산한 뒤, 가장 큰 값을 최종 레플리카 수로 채택합니다. CPU는 3개를 요구하고 메모리는 5개를 요구하면 5개로 스케일합니다.

Behavior: 스케일링 속도 정밀 제어

HPA v2의 behavior 필드는 스케일아웃/스케일인 속도를 세밀하게 제어합니다. 트래픽 급증 시 빠르게 확장하되, 축소는 천천히 진행하여 플래핑(flapping)을 방지하는 것이 핵심 전략입니다.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 2
  maxReplicas: 50
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
        - type: Percent
          value: 100
          periodSeconds: 30
        - type: Pods
          value: 5
          periodSeconds: 60
      selectPolicy: Max
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 10
          periodSeconds: 60
      selectPolicy: Min

위 설정의 의미를 분석하면:

  • scaleUp: 안정화 윈도우 0초(즉시 반응), 30초마다 현재의 100% 증가 또는 60초마다 5개 추가 중 큰 값(Max) 적용
  • scaleDown: 5분간 안정화 후, 60초마다 최대 10%씩만 감소, 여러 정책 중 작은 값(Min) 적용

selectPolicy: Max는 가장 공격적인 스케일링을, Min은 가장 보수적인 스케일링을 선택합니다. Disabled로 설정하면 해당 방향의 스케일링을 완전히 차단할 수 있습니다.

커스텀 메트릭 기반 스케일링

CPU/메모리만으로는 실제 부하를 정확히 반영하지 못하는 경우가 많습니다. Prometheus Adapter를 통해 비즈니스 메트릭 기반 스케일링을 구현할 수 있습니다.

Prometheus Adapter 설정

# prometheus-adapter-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: adapter-config
  namespace: monitoring
data:
  config.yaml: |
    rules:
      - seriesQuery: 'http_requests_per_second{namespace!="",pod!=""}'
        resources:
          overrides:
            namespace: {resource: "namespace"}
            pod: {resource: "pod"}
        name:
          matches: "^(.*)$"
          as: "requests_per_second"
        metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
      - seriesQuery: 'rabbitmq_queue_messages{queue!=""}'
        resources:
          overrides:
            namespace: {resource: "namespace"}
        name:
          as: "queue_depth"
        metricsQuery: 'avg_over_time(<<.Series>>{<<.LabelMatchers>>}[1m])'

커스텀 메트릭 HPA 적용

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: worker-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-worker
  minReplicas: 1
  maxReplicas: 30
  metrics:
    - type: Pods
      pods:
        metric:
          name: requests_per_second
        target:
          type: AverageValue
          averageValue: "100"
    - type: Object
      object:
        describedObject:
          apiVersion: v1
          kind: Service
          name: rabbitmq
        metric:
          name: queue_depth
        target:
          type: Value
          value: "500"

메트릭 타입별 차이점:

  • Resource: CPU, 메모리 등 기본 리소스 (metrics-server 필요)
  • Pods: 파드별 평균값으로 계산되는 커스텀 메트릭
  • Object: 특정 쿠버네티스 오브젝트에 연결된 메트릭 (큐 깊이 등)
  • External: 클러스터 외부 메트릭 (SQS 큐 길이, CloudWatch 등)

KEDA로 이벤트 드리븐 오토스케일링

K8s DaemonSet 운영 전략에서 다뤘듯이 워크로드 특성에 맞는 스케일링이 중요합니다. KEDA(Kubernetes Event-Driven Autoscaler)는 HPA를 확장하여 0→N 스케일링과 60+ 이벤트 소스를 지원합니다.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaler
  namespace: production
spec:
  scaleTargetRef:
    name: kafka-consumer
  pollingInterval: 15
  cooldownPeriod: 300
  idleReplicaCount: 0
  minReplicaCount: 1
  maxReplicaCount: 50
  fallback:
    failureThreshold: 3
    replicas: 5
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka.production:9092
        consumerGroup: order-processor
        topic: orders
        lagThreshold: "100"
        activationLagThreshold: "10"
    - type: prometheus
      metadata:
        serverAddress: http://prometheus.monitoring:9090
        metricName: error_rate
        query: |
          sum(rate(http_errors_total{service="order"}[5m]))
          / sum(rate(http_requests_total{service="order"}[5m])) * 100
        threshold: "5"
        activationThreshold: "1"

KEDA의 핵심 개념:

  • idleReplicaCount: 0: 이벤트 없으면 파드를 0으로 축소 (비용 절감)
  • activationLagThreshold: 0→1 스케일업을 트리거하는 최소 임계값
  • fallback: 메트릭 수집 실패 시 안전한 레플리카 수 유지
  • cooldownPeriod: 마지막 트리거 활성화 후 0으로 축소까지 대기 시간

VPA와 HPA 조합 전략

VPA(Vertical Pod Autoscaler)는 파드의 리소스 요청/제한을 자동 조절하고, HPA는 파드 수를 조절합니다. 두 가지를 함께 사용하면 최적의 리소스 효율을 달성할 수 있지만, 같은 메트릭(CPU/메모리)에 대해 동시 적용하면 충돌합니다.

# VPA: 리소스 크기만 조정 (UpdateMode: Auto)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: api-server-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  updatePolicy:
    updateMode: "Auto"
  resourcePolicy:
    containerPolicies:
      - containerName: api
        minAllowed:
          cpu: 100m
          memory: 128Mi
        maxAllowed:
          cpu: 2
          memory: 4Gi
        controlledResources: ["cpu", "memory"]
---
# HPA: 커스텀 메트릭으로만 스케일링 (CPU/메모리 충돌 방지)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: requests_per_second
        target:
          type: AverageValue
          averageValue: "200"

핵심 원칙: VPA가 CPU/메모리를 관리하면 HPA는 반드시 커스텀 메트릭만 사용해야 합니다. K8s Pod Probe 헬스체크 전략과 함께 적용하면 안정적인 스케일링 파이프라인을 구축할 수 있습니다.

실전 트러블슈팅 패턴

1. 메트릭 수집 실패 디버깅

# HPA 상태 확인
kubectl describe hpa api-server-hpa -n production

# metrics-server 동작 확인
kubectl top pods -n production

# 커스텀 메트릭 API 확인
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .

# 특정 파드의 커스텀 메트릭 조회
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/production/pods/*/requests_per_second" | jq .

2. 플래핑 방지 체크리스트

# 스케일다운 안정화 윈도우 확인
kubectl get hpa api-server-hpa -o jsonpath='{.spec.behavior.scaleDown.stabilizationWindowSeconds}'

# HPA 이벤트에서 플래핑 징후 확인
kubectl get events --field-selector involvedObject.name=api-server-hpa 
  --sort-by=.lastTimestamp -n production

# kube-controller-manager 플래그 확인
# --horizontal-pod-autoscaler-downscale-stabilization (기본 5분)
# --horizontal-pod-autoscaler-tolerance (기본 0.1 = 10%)

3. 스케일링 시뮬레이션

# 부하 테스트로 HPA 동작 검증
kubectl run load-gen --image=busybox --restart=Never -- 
  /bin/sh -c "while true; do wget -q -O- http://api-server.production/health; done"

# HPA 메트릭 실시간 모니터링
kubectl get hpa api-server-hpa -n production -w

# Grafana 대시보드 쿼리 (HPA 이력 시각화)
# kube_horizontalpodautoscaler_status_current_replicas
# kube_horizontalpodautoscaler_status_desired_replicas
# kube_horizontalpodautoscaler_spec_min_replicas
# kube_horizontalpodautoscaler_spec_max_replicas

운영 베스트 프랙티스 정리

항목 권장 설정 이유
minReplicas ≥ 2 고가용성 보장, 단일 장애점 방지
CPU 목표 50-70% 버스트 여유 확보
scaleDown 안정화 300-600초 플래핑 방지
scaleUp 안정화 0-60초 빠른 확장 대응
PDB 병행 필수 스케일다운 시 가용성 보장
Resource Requests 반드시 설정 HPA 메트릭 계산의 기준값

Resource Requests 미설정 시 HPA가 동작하지 않습니다. Utilization 타입은 requests 대비 현재 사용량 비율이므로, requests가 없으면 계산 자체가 불가능합니다. 이는 가장 흔한 HPA 설정 실수입니다.

마무리

K8s HPA는 단순한 CPU 기반 스케일링을 넘어, behavior 정밀 제어, 커스텀 메트릭, KEDA 이벤트 드리븐, VPA 조합까지 확장하면 진정한 클라우드 네이티브 오토스케일링을 구현할 수 있습니다. 핵심은 워크로드 특성에 맞는 메트릭 선정과 보수적인 스케일다운 정책입니다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux