HPA(HorizontalPodAutoscaler)配上了,但流量压上来 Pod 死活不扩,是 K8s 运维的高频坑。本文列我见过的 6 个典型原因。

起手命令

kubectl describe hpa <name> -n <ns>
kubectl get hpa <name> -n <ns> -w
kubectl logs -n kube-system deploy/metrics-server | tail

describe hpa 底部的 ConditionsEvents 是关键。

陷阱 1:metrics-server 没装/挂了

最常见。kubectl top pods 报错就是这个:

error: Metrics API not available

修复:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

自签证书集群还得加 --kubelet-insecure-tls

陷阱 2:Pod 没设 resources.requests

HPA 算的是 当前用量 / requests没写 requests,HPA 啥也算不出来

kubectl get hpa <name> -o yaml | grep -A5 currentMetrics
# 看到 <unknown> 就是这个原因

修:deployment 里给容器加 resources.requests.cpu: 100m

陷阱 3:阈值算法和你想的不一样

HPA 公式:

desiredReplicas = ceil(currentReplicas × (currentMetric / desiredMetric))

举例:当前 2 个 Pod,CPU 平均使用率 60%,目标 50%:

desired = ceil(2 × (60/50)) = ceil(2.4) = 3

但有 10% 容忍区间horizontal-pod-autoscaler-tolerance 默认 0.1),60/50=1.2 超过 1.1 才扩。如果 currentMetric 在 45%~55% 之间,永远不会扩缩

陷阱 4:扩容/缩容窗口(v2 behavior)

HPA v2 引入 behavior,默认缩容窗口 5 分钟。流量降了但 Pod 不缩,可能正常:

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
  scaleUp:
    stabilizationWindowSeconds: 0

如果想更快响应,调小这两个值。

陷阱 5:自定义指标接不上

用 Prometheus Adapter / KEDA 的场景:

kubectl get apiservice | grep custom.metrics
# v1beta1.custom.metrics.k8s.io 必须是 Available

不 Available 就是 adapter 挂了或者配置没生效。Adapter 改完配置必须重启 Pod,热加载没用。

陷阱 6:目标 deployment 的 replicas 被其他东西管着

Argo CD / Flux 同步覆盖、PodDisruptionBudget 限制、StatefulSet 的 ordinal 限制都可能让 HPA 改了 replicas 立刻被改回去。

kubectl get events -n <ns> | grep -i hpa
kubectl get deployment <name> -o yaml | grep -B2 -A2 replicas

GitOps 场景的标准做法:让 HPA 管 replicas,Argo CD 忽略 replicas 字段:

# Application
spec:
  ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
    - /spec/replicas

几个调试 trick

  • 手动改 replicas 看 HPA 反应kubectl scale deploy/x --replicas=5,5 分钟后 HPA 应该把它拉回来
  • 临时打开 verbose 日志kubectl -n kube-system edit deployment metrics-server--v=4
  • 看是 metric 没采到还是算出来不扩describe hpacurrentMetrics 字段,<unknown> vs 有值 走不同分支

教训一句话:HPA 不扩 90% 是 metrics-server 或 requests 没设,剩下 10% 是 behavior 窗口或者算法容忍区间。

标签: none

添加新评论