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-nkube-system# 没有就装(裸机/自建集群常需要加 --kubelet-insecure-tls)kubectl apply-fhttps://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml# 验证能拿到指标(能列出各 Pod 的 CPU/内存才算 OK)kubectltoppodskubectl top pods能出数据,HPA 才有的谈。关键前提:Deployment 必须声明 resources.requests这是第二个高频坑。HPA 的 CPU 百分比是相对于 request 算的,不是相对于节点总量。如果 Deployment 没写requests.cpu,HPA 拿不到基准,同样显示unknown:# deployment.yaml —— 必须有 resources.requestsapiVersion:apps/v1kind:Deploymentmetadata:name:webspec:replicas:2selector:matchLabels:{app:web}template:metadata:labels:{app:web}spec:containers:-name:webimage:your-web:1.0resources:requests:cpu:200m# HPA 按这个算利用率:实际用 100m 就是 50%memory:256Milimits:cpu:500mmemory:512Mi记住这条换算:如果 request 是200m,HPA 目标设 50%,那么当每个 Pod 平均用到100mCPU 时就触发扩容。没有 request,一切免谈。配一个基础 HPA用autoscaling/v2版本(v1 只支持单一 CPU 指标,别用了):# hpa.yamlapiVersion:autoscaling/v2kind:HorizontalPodAutoscalermetadata:name:webspec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:webminReplicas:2maxReplicas:10metrics:-type:Resourceresource:name:cputarget:type:UtilizationaverageUtilization:60# 平均 CPU 超过 request 的 60% 就扩容应用并观察:kubectl apply-fhpa.yaml kubectl get hpa web-w# -w 持续观察 TARGETS 和 REPLICAS 变化TARGETS显示45%/60%这种真实数字,就说明链路通了。治抖动:behavior 稳定窗口基础 HPA 跑起来后,你可能发现流量一波动 Pod 数就来回跳——扩上去马上又缩,缩下来又扩,这叫 flapping,对服务和成本都不友好。根因是扩容很激进、缩容也很激进。v2的behavior字段就是用来驯服它的:apiVersion:autoscaling/v2kind:HorizontalPodAutoscalermetadata:name:webspec:scaleTargetRef:apiVersion:apps/v1kind:Deploymentname:webminReplicas:2maxReplicas:10metrics:-type:Resourceresource:name:cputarget:type:UtilizationaverageUtilization:60behavior:scaleDown:# 缩容前先观察 5 分钟,确认负载真的降下来了才缩,避免刚缩就又要扩stabilizationWindowSeconds:300policies:-type:Percentvalue:50# 每次最多缩掉当前副本数的 50%periodSeconds:60scaleUp:# 扩容要快,窗口设 0,负载一高立刻响应stabilizationWindowSeconds:0policies:-type:Percentvalue:100# 每分钟最多翻倍periodSeconds:60-type:Podsvalue: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拉长——扩容要果断,缩容要克制。