我不会起名字322· 后端 / 算法 / 数据库 技术栈 力扣 Hot100 Go 项目 Redis MySQL文章目录HPA 不扩容metrics-server 与指标延迟的 3 个原因一、先看 HPA 自己怎么说二、原因 1Pod 没设 CPU request三、原因 2metrics-server 本身有问题先确认它活着最常见拿不到指标一个关键的延迟账四、原因 3稳定窗口与扩缩容策略把它按住了机制 1稳定窗口stabilization window机制 2behavior 里的速率限制机制 3容忍度tolerance五、基于自定义指标的 HPA六、带走物HPA 不扩容metrics-server 与指标延迟的 3 个原因一、先看 HPA 自己怎么说排查 HPA 不扩容第一步永远是看它的Conditions——HPA 会把为什么不扩直接写在这里kubectl describe hpaname-nnsConditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True SucceededRescale the HPA controller was able to update the target scale to 3 ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: failed to get cpu utilization: missing request for cpu ScalingLimited True TooFewReplicas the desired replica count is more than the maximum replica count三个字段的读法Type含义常见 False 原因AbleToScale能不能改副本数被minReplicas/maxReplicas卡住、 stabilize 窗口内ScalingActive能不能拿到指标metrics-server 挂了、Pod 没设 requestScalingLimited是否被上下限限制期望副本数超过maxReplicasScalingActive: FalseFailedGetResourceMetric是最常见的一类先看它。二、原因 1Pod 没设 CPU request这是最高频的原因而且报错信息很直白failed to get cpu utilization: missing request for cpuHPA 的 CPU 利用率是这么算的利用率 实际 CPU 使用量 / CPU request如果 Pod 没设resources.requests.cpu分母就是 0HPA 根本算不出百分比于是拒绝扩容。kubectl get podpod-ojsonpath{.spec.containers[*].resources}# {} ← 空的就是没设修法给所有会被 HPA 管理的容器都设 request。resources:requests:cpu:200m# 必须有HPA 的分母memory:256Mi注意是所有容器如果 Pod 里有个 sidecar比如日志采集、service mesh 的 envoy没设 request主容器的 request 也可能不被正确汇总——推荐用LimitRange给 namespace 设默认值一劳永逸。三、原因 2metrics-server 本身有问题先确认它活着kubectl get pod-nkube-system|grepmetrics-server kubectl logs-nkube-system deploy/metrics-server--tail50最常见拿不到指标kubectltopnodes# error: Metrics API not available或者kubectl get--raw/apis/metrics.k8s.io/v1beta1/nodes|headmetrics-server 不工作的几个典型原因(a) 没装。很多自建集群默认没有kubectl get apiservice v1beta1.metrics.k8s.io-oyaml|grep-A5conditions(b) kubelet 证书问题。最经典的错误是x509: cannot validate certificate for 10.0.1.20 because it doesnt contain any IP SANs解法是给 metrics-server 加启动参数args:---kubelet-insecure-tls# 测试环境可接受生产应配好证书---kubelet-preferred-address-typesInternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP© 采集间隔太慢。metrics-server 默认--metric-resolution15s旧版 60s。指标本身就有延迟。一个关键的延迟账HPA 从负载升高到真的扩容中间有几段延迟应用 CPU 升高 → metrics-server 采集默认 15~60s → HPA 控制器同步默认 --horizontal-pod-autoscaler-sync-period15s → 判断是否连续满足条件默认 5 分钟稳定窗口扩容时通常更快 → 改 replicas → 新 Pod 调度 启动 就绪几十秒到几分钟加起来通常是 1~3 分钟加上 Pod 冷启动可能 3~5 分钟。这意味着HPA 救不了秒级的突发流量。如果你的业务是秒级尖峰HPA 来不及需要预留 buffer 或者用 KEDA 这类基于队列长度/请求数的触发器。四、原因 3稳定窗口与扩缩容策略把它按住了即使指标正常HPA 也可能故意不扩。两个机制机制 1稳定窗口stabilization window默认缩容有 5 分钟的稳定窗口HPA 会取最近 5 分钟里最大的期望副本数防止抖动导致频繁缩容。behavior:scaleDown:stabilizationWindowSeconds:300# 默认 300所以如果你刚经历了一波高峰又降下来HPA 不会立刻缩——这是正常行为不是 bug。机制 2behavior里的速率限制K8s 1.18 支持自定义扩缩容速率behavior:scaleUp:stabilizationWindowSeconds:0policies:-type:Percentvalue:100periodSeconds:60# 每分钟最多扩一倍-type:Podsvalue:4periodSeconds:60# 或每分钟最多扩 4 个selectPolicy:MaxscaleDown:stabilizationWindowSeconds:300policies:-type:Percentvalue:100periodSeconds:60如果这里配得保守指标超了也不会快速扩。检查kubectl get hpaname-oyaml|grep-A20behavior机制 3容忍度toleranceHPA 默认有10% 的容忍度目标利用率 70%实际在 63%~77% 之间时HPA 认为已经达标不动。这个不能通过配置改硬编码但要知道它的存在——所以别指望 HPA 把利用率精确控制在 70%。五、基于自定义指标的 HPACPU 不总是合适的指标。比如一个消费者服务CPU 一直很低但消息积压很高——这时应该用自定义指标比如 Kafka lag。链路是应用暴露指标 → Prometheus 抓取 → prometheus-adapter 暴露成 custom.metrics.k8s.io → HPA 使用# 看有哪些自定义指标可用kubectl get--raw/apis/custom.metrics.k8s.io/v1beta1|jq.resources[].name|headHPA 配置apiVersion:autoscaling/v2kind:HorizontalPodAutoscalerspec:metrics:-type:Podspods:metric:name:kafka_consumer_lagtarget:type:AverageValueaverageValue:1000# 每个 Pod 平均积压 1000 条就扩自定义指标的延迟比 CPU 更大多了一跳 Prometheus 抓取调 stable window 时要考虑进去。六、带走物排查顺序# 1. HPA 自己说的理由最重要kubectl describe hpaname-nns|grep-A8Conditions# 2. 指标能不能拿到kubectltoppods-nnskubectl get--raw/apis/metrics.k8s.io/v1beta1/pods|head# 3. Pod 有没有 requestHPA 的分母kubectl get pod-ojsonpath{.spec.containers[*].resources}# 4. metrics-server 活着吗kubectl logs-nkube-system deploy/metrics-server--tail50# 5. 有没有被 behavior 限制kubectl get hpaname-oyaml|grep-A20behavior对应的三类修法原因症状修法没设 requestmissing request for cpu给所有容器设requests.cpu用 LimitRange 兜底metrics-server 异常Metrics API not available、x509错误检查 Pod/证书/--kubelet-insecure-tls稳定窗口/速率限制指标正常但不扩看behavior缩容默认有 5 分钟窗口属正常一句话结论HPA 不扩容时先看describe里的 Conditions八成的原因写在那里而没设 request和metrics-server 挂了这两条占了绝大多数。