Kubernetes HPA 自动扩缩容实战:CPU 指标、扩缩容抖动与稳定窗口调优
Kubernetes HPA 自动扩缩容实战:CPU 指标、扩缩容抖动与稳定窗口调优
流量高峰手动加 Pod、低谷手动减,是很多团队的日常。HPA(HorizontalPodAutoscaler)本该把这事自动化,但真配上去往往遇到两个尴尬:要么 HPA 一直显示 <unknown> 根本不扩容,要么扩缩容像抽风一样反复横跳(flapping)。这篇从能跑起来到调稳,一步步来。
前置:没有 metrics-server,HPA 就是瞎子
HPA 靠 CPU/内存指标决策,这些指标由 metrics-server 提供。很多人 HPA 配好了却发现 TARGETS 永远是 <unknown>/50%,九成是没装 metrics-server:
# 检查是否已安装
kubectl get deployment metrics-server -n kube-system
# 没有就装(裸机/自建集群常需要加 --kubelet-insecure-tls)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 验证能拿到指标(能列出各 Pod 的 CPU/内存才算 OK)
kubectl top pods
kubectl top pods 能出数据,HPA 才有的谈。
关键前提:Deployment 必须声明 resources.requests
这是第二个高频坑。HPA 的 CPU 百分比是相对于 request 算的,不是相对于节点总量。如果 Deployment 没写 requests.cpu,HPA 拿不到基准,同样显示 <unknown>:
# deployment.yaml —— 必须有 resources.requests
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: your-web:1.0
resources:
requests:
cpu: 200m # HPA 按这个算利用率:实际用 100m 就是 50%
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
记住这条换算:如果 request 是 200m,HPA 目标设 50%,那么当每个 Pod 平均用到 100m CPU 时就触发扩容。没有 request,一切免谈。
配一个基础 HPA
用 autoscaling/v2 版本(v1 只支持单一 CPU 指标,别用了):
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # 平均 CPU 超过 request 的 60% 就扩容
应用并观察:
kubectl apply -f hpa.yaml
kubectl get hpa web -w # -w 持续观察 TARGETS 和 REPLICAS 变化
TARGETS 显示 45%/60% 这种真实数字,就说明链路通了。
治抖动:behavior 稳定窗口
基础 HPA 跑起来后,你可能发现流量一波动 Pod 数就来回跳——扩上去马上又缩,缩下来又扩,这叫 flapping,对服务和成本都不友好。根因是扩容很激进、缩容也很激进。v2 的 behavior 字段就是用来驯服它的:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleDown:
# 缩容前先观察 5 分钟,确认负载真的降下来了才缩,避免刚缩就又要扩
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50 # 每次最多缩掉当前副本数的 50%
periodSeconds: 60
scaleUp:
# 扩容要快,窗口设 0,负载一高立刻响应
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100 # 每分钟最多翻倍
periodSeconds: 60
- type: Pods
value: 4 # 或每分钟最多加 4 个,取两者中更激进的
periodSeconds: 60
调优的核心思路是扩容快、缩容慢:
scaleUp.stabilizationWindowSeconds: 0—— 流量一涨立刻扩,别让用户等。scaleDown.stabilizationWindowSeconds: 300—— 缩容前先观察 5 分钟,是 HPA 在这个窗口里取「最大推荐副本数」作为决策,相当于「宁可多扛一会儿也别急着缩」,这是消除抖动最有效的一招。
kubectl describe hpa web 能看到它每次决策的事件日志,调参时对着这个看最直观。
小结
- HPA 依赖 metrics-server(
kubectl top pods能出数)+ Deployment 的resources.requests.cpu,缺一个都会卡在<unknown>。 - CPU 利用率是相对于 request 算的,不是节点总量,配目标值前先想清楚这个基准。
- 用
autoscaling/v2的behavior治抖动,原则是扩容窗口设 0(快)、缩容窗口设几分钟(慢)。
一句话记忆:HPA 不出数先查 metrics-server 和 requests;HPA 抖动就把缩容的 stabilizationWindowSeconds 拉长——扩容要果断,缩容要克制。
更多推荐
所有评论(0)