為什麼需要 HPA?
電商網站的場景:
- 平常:2 個 Pod 撐得住流量
- 雙 11 大促:流量翻 10 倍,2 個 Pod 直接被打爆
- 凌晨 3 點:沒人逛,10 個 Pod 閒在那邊浪費錢
kubectl scale\:
\\\bash\
kubectl scale deployment my-api --replicas=10 # 大促前
kubectl scale deployment my-api --replicas=2 # 大促後
\\
但你不可能 24 小時盯著儀表板。該自動化了。
HPA = Horizontal Pod Autoscaler——K8s 看 CPU 使用率,自動幫你加減 Pod。
HPA 怎麼運作?
[Metrics Server] ── 每 15 秒收集 Pod CPU/Memory 用量
│
▼
[HPA] ── 比對 target(如 50%),算出該幾個 Pod
│
▼
[Deployment] ── 改 replicas
│
▼
[Pods] ── 自動增減
前提:Resource requests 一定要設
\\\yaml\
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
\\
為什麼?因為 HPA 算的是百分比。
「CPU 使用率 50%」是相對於 requests 的 50%。如果 \requests: 100m\,使用率 50% 就是 50m。沒設 requests,HPA 沒辦法算百分比,直接擺爛不擴容。
安裝 metrics-server
HPA 需要 metrics-server 才能取得 CPU 數據。
\\\bash
# minikube
minikube addons enable metrics-server
# k3s(內建,不用裝)
# 自動已啟用
\\\
確認跑起來:
\\\bash\
kubectl top nodes
kubectl top pods
\\
如果 \kubectl top\ 顯示數字,就 OK 了。
HPA YAML
\\\yaml\
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-resources-demo # 要擴縮的 Deployment
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # CPU 超過 50% 就擴容
\\
關鍵欄位:
| 欄位 | 意義 |
|---|---|
\scaleTargetRef\ | 要擴縮哪個 Deployment |
\minReplicas\ | 最少幾個 Pod |
\maxReplicas\ | 最多幾個 Pod(防失控) |
\averageUtilization\ | 觸發擴容的 CPU 閾值(%) |
實作:壓測讓 Pod 自動長出來
Step 1:部署 HPA
\\\bash\
kubectl apply -f hpa.yaml
kubectl get hpa
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# api-hpa Deployment/api-resources-demo
\\
剛建立會看到 \,等 30 秒就會變成 \0%/50%\。
Step 2:壓力測試
開兩個終端:
終端 1(觀察):
\\\bash\
kubectl get hpa -w
\\
終端 2(壓測):
\\\bash\
# 進去 Pod 內部,無限呼叫 API
kubectl run -i --tty load-generator --rm \\
--image=busybox --restart=Never -- \\
/bin/sh -c "while true; do wget -q -O- http://api-svc; done"
\\
Step 3:看 HPA 自動加 Pod
終端 1 你會看到:
\\\\
NAME TARGETS REPLICAS
api-hpa 0%/50% 1
api-hpa 125%/50% 1 ← 流量來了
api-hpa 125%/50% 3 ← 自動加到 3 個
api-hpa 85%/50% 3
api-hpa 85%/50% 5 ← 還是太高,再加
api-hpa 50%/50% 5 ← 平衡了
\\
按 Ctrl+C 停掉壓測:
\\\\
api-hpa 10%/50% 5 ← 流量降了
api-hpa 0%/50% 5 ← 但還沒縮
... 等 5 分鐘 ...
api-hpa 0%/50% 1 ← 縮回去了
\\
為什麼縮容比擴容慢?
擴容快(30 秒內反應),縮容慢(預設 5 分鐘)——這是故意的。
原因:流量是波動的。如果剛降一點就馬上縮,等下流量又來,又得擴,Pod 一直開開關關反而災難。
可以微調 \behavior\:
\\\yaml\
spec:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 觀察 5 分鐘才縮
policies:
- type: Percent
value: 50
periodSeconds: 60
\\
HPA 沒效?三步驟排查
| 症狀 | 排查 |
|---|---|
TARGETS 一直 \ | metrics-server 沒裝或沒跑 |
TARGETS 是 \ 但 Pod 有跑 | Deployment 沒設 requests |
| CPU 100% 但不擴容 | 沒到 maxReplicas 嗎?看 HPA event |
\\bash
kubectl describe hpa api-hpa # 看 events 區塊找原因
\\\
重點整理
- HPA = K8s 自動 scale:流量大自動加、流量小自動砍
- 必須設 \
resources.requests\——HPA 算的是百分比 - 必須有 metrics-server——HPA 看不到數據就擺爛
- 擴容快(30s)、縮容慢(5min)——避免抖動
- 進階版:VPA(垂直擴縮)、KEDA(事件驅動擴縮)
下一步
服務有 Probe、有 limits、有自動擴容——但誰都能 \kubectl delete pod\ 把它砍掉。
實習生不小心 \kubectl delete deployment\,整個服務就沒了。該管權限了。
📅 下一篇:RBAC:讓只讀帳號真的只能讀
Role / RoleBinding / ServiceAccount 三件套——實作一個「只能 get/list,不能 delete」的帳號。
📚 完整系列總覽:K8s 系列教學首頁(共 40 課,按學習路徑順序排)