Skip to content

Kubernetes HPA 水平自動擴縮

依據 CPU、記憶體或自訂指標,自動調整 Deployment Pod 副本數的 Kubernetes 原生機制。

概述

HPA(HorizontalPodAutoscaler)是 Kubernetes 的原生水平自動擴縮資源,透過監控 Pod 的資源使用率,在負載升高時自動增加副本數(scale out),負載降低時縮減副本數(scale in),確保服務在維持效能的同時不浪費資源。

HPA 的運作依賴 Metrics Server 持續採集各 Pod 的 CPU/Memory 使用數據。控制器每 15 秒計算一次目前使用量與目標值的比例,依此決定目標副本數。HPA 屬於「反應型」擴縮——先出現使用率超標才觸發擴縮,而非預測性的提前擴展。

autoscaling/v2 是目前(K8s 1.23+)推薦使用的 API 版本,支援多指標條件和自訂外部指標。舊版 autoscaling/v1 只能基於 CPU,已不推薦。

核心內容

運作原理

HPA 控制器每 15 秒執行一次評估:

  1. 從 Metrics Server 取得目標 Deployment 所有 Pod 的指標值(如 CPU 使用率)
  2. 計算「所有 Pod 指標的平均值」與「target averageUtilization」的比值
  3. 依比值計算出目標副本數:desiredReplicas = ceil(currentReplicas × (current / desired))
  4. 若目標副本數超過 maxReplicas 或低於 minReplicas,則夾在範圍內
  5. 與目前副本數不同時,更新 Deployment 的 spec.replicas

先決條件:設定 resources.requests

HPA 計算使用率(Utilization)的方式是「實際使用量 / requested 量 × 100%」。若 Deployment 的 Container 未設定 resources.requests,HPA 無法計算比例,scale 邏輯不會觸發。

yaml
resources:
  requests:
    cpu: 100m
    memory: 128Mi

這是使用 HPA 的必要前提,也是 K8s 資源管理的最佳實踐。

autoscaling/v2 設定範例

以 CPU 使用率 50% 為目標、最多 10 個副本的設定:

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: azure-hpa-test
  namespace: ingress-basic
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: template-server
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  • scaleTargetRef:指定要擴縮的 Deployment(或 StatefulSet、其他支援 scale 的資源)
  • averageUtilization: 50:當所有 Pod 的平均 CPU 使用率超過 request 的 50%,就開始 scale out
  • minReplicas: 1:HPA 不會縮至零(想要 scale-to-zero 需改用 KEDA)

多指標同時觸發

autoscaling/v2 支援同時指定多個 metrics,任一條件達標即觸發擴縮:

yaml
metrics:
- type: Resource
  resource:
    name: cpu
    target:
      type: Utilization
      averageUtilization: 50
- type: Resource
  resource:
    name: memory
    target:
      type: Utilization
      averageUtilization: 80

HPA 會取各指標計算出的目標副本數中的最大值作為最終副本數,確保任何瓶頸都能被及時擴展。

原生 HPA 的限制

限制說明
無法 scale-to-zerominReplicas 最小值為 1
指標來源有限只支援 CPU、Memory 和 Custom Metrics API
反應有延遲每 15 秒評估一次,加上冷卻期(scale down 預設 5 分鐘)
不支援佇列長度無法直接基於 RabbitMQ、Kafka 等訊息佇列的積壓量擴縮

若需要 scale-to-zero 或基於 Queue 深度、Prometheus 指標等外部事件擴縮,應改用 KEDA

關鍵要點

  • HPA 需要 Metrics Server 支援,AKS 預設已安裝;自建叢集需手動安裝
  • resources.requests 必須設定,否則 CPU/Memory Utilization 模式無法計算
  • autoscaling/v2 支援多指標,取各指標計算副本數的最大值
  • Scale down 有冷卻期(--horizontal-pod-autoscaler-downscale-stabilization,預設 5 分鐘),避免頻繁縮容
  • 原生 HPA 不能 scale-to-zero;需要此功能請使用 KEDA

實際應用

典型場景:Web API 服務在白天流量高峰期需要更多副本,深夜流量下降後自動縮容節省成本。設定 CPU 使用率 50% 作為擴縮閾值,可確保每個 Pod 有足夠餘裕處理突發流量,同時整體負載不會過低(浪費資源)。

在 AKS 上,HPA 搭配 KEDA 的 CPU/Memory Scaler 可以用宣告式的 ScaledObject 達成相同效果,並可混用 Prometheus 等外部指標。

部署設定參考

以下為實際使用的 HPA YAML,供日後查詢與複製使用。

HPA YAML(CPU 使用率觸發)

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: azure-hpa-test
  namespace: ingress-basic
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: template-server
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

操作指令

bash
# 查看 HPA 狀態(含目前副本數與指標值)
kubectl get hpa -n ingress-basic

# 查看 HPA 詳細資訊(含 Conditions 與 Events)
kubectl describe hpa azure-hpa-test -n ingress-basic

相關概念

來源