讲解
手动 kubectl scale 解决不了「流量半夜暴涨」的问题——总不能定闹钟起来扩副本。HorizontalPodAutoscaler(HPA)按指标自动调整 Deployment/StatefulSet 的副本数:你声明「目标 CPU 利用率 50%,副本数 1 到 3 之间」,HPA 控制器每隔一小段时间算一次「当前指标 ÷ 目标值 × 当前副本数」,向上取整得到期望副本数,再夹在 min/max 之间去改 scale。横向(加副本)叫 Horizontal,对应的还有纵向调 requests 的 VPA(需要额外安装,不作展开)。
HPA 的前置条件是 metrics-server:它是集群的指标管道,从各节点 kubelet 收集 CPU/内存用量,通过 metrics.k8s.io API 提供给 HPA 和 kubectl top。没有它,HPA 的 TARGETS 列会显示 ,控制器拿不到数据就不动作。kind/minikube 默认不带 metrics-server,要手动安装;云上托管集群一般都预装。还有个隐藏前提:按 CPU 利用率伸缩时,「利用率」是相对容器 requests 计算的——没配 requests 的 Deployment 没法用百分比目标,这就是第 17 章强调资源声明的又一个理由。
看一个 HPA 清单的核心字段:scaleTargetRef 指向被伸缩的对象;minReplicas/maxReplicas 划出副本数边界(min 建议至少 2,单副本缩到 0 或 1 都有可用性风险);metrics 里 resource.cpu.target.averageUtilization: 50 表示「所有 Pod 的 CPU 用量均值 ÷ requests 均值 ≈ 50%」。行为调优在 behavior 字段:scaleDown 默认有 5 分钟稳定窗口(防止指标抖动导致副本数来回震荡),scaleUp 默认更激进。理解这个「快扩慢缩」的不对称设计:扩容是救急,缩容是省钱,救急要快,省钱可以等。
示例
先部署一个带 requests 的应用(HPA 按 CPU 利用率伸缩要求容器必须声明 requests):
# wait: deploy/ohmydocs-verify-load
apiVersion: apps/v1
kind: Deployment
metadata:
name: ohmydocs-verify-load
spec:
replicas: 1
selector:
matchLabels:
app: ohmydocs-verify-load
template:
metadata:
labels:
app: ohmydocs-verify-load
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 32Mi
limits:
cpu: 500m
memory: 128Mi
HPA:CPU 均值超过 requests 的 50% 就扩容,副本数范围 1-3(这份清单会被真实 apply):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ohmydocs-verify-load
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ohmydocs-verify-load
minReplicas: 1
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
查看 HPA 状态。TARGETS 列显示 /50% 说明 metrics-server 不在——资源本身已生效,只是拿不到指标(本教程验证环境的网络限制见运行摘要):
kubectl get hpa ohmydocs-verify-load
kubectl describe hpa ohmydocs-verify-load | tail -6
metrics-server 可用时的观测手法(kubectl top 直接看各 Pod 的 CPU/内存用量;新 Pod 的指标要等一个抓取周期,脚本里带重试):
# 依赖: metrics-server
ok=0
for i in $(seq 1 12); do
if kubectl top pods -l app=ohmydocs-verify-load; then ok=1; break; fi
sleep 15
done
[ "$ok" = "1" ] || { echo "metrics-server 指标迟迟不可用"; exit 1; }
kubectl get hpa ohmydocs-verify-load
本地集群安装 metrics-server 的标准命令(GitHub 发布件,受限网络可能失败——脚本已在验证阶段尝试过一次):
# 仅示意:安装 metrics-server(GitHub 发布件 + 需追加 --kubelet-insecure-tls 补丁,网络受限时不可用)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
常见坑
- TARGETS 永远 :metrics-server 没装或没跑起来;HPA 资源创建不需要它,但伸缩需要。kind 上安装后还要追加 --kubelet-insecure-tls 参数。
- Deployment 没配 requests:按 Utilization 伸缩的 HPA 算不出百分比,事件里直接报 missing request for cpu。
- 缩容抖动:流量波动导致副本数上下来回跳——behavior.scaleDown.stabilizationWindowSeconds 拉长稳定窗口,或把目标利用率调高一点。
- minReplicas: 1 的关键服务:缩到单副本时一次节点故障就全站中断;生产关键服务 min 至少 2,且配合 Pod 反亲和分散到不同节点。
小结
HPA = 指标驱动的自动 scale:requests 是百分比基准,metrics-server 是数据来源,behavior 控制快扩慢缩;本地集群记得装 metrics-server 并打 insecure-tls 补丁。下一章收紧权限:RBAC。