CFN Cloud
Cloud Future New Life
en zh
2025-12-29 · 0 次浏览

Kubernetes Tips:扩缩容不抖(HPA + VPA + Cluster Autoscaler)

把 requests 写对、HPA 行为调稳、VPA 做推荐、CA 能补容量,让扩缩容可预测而不是“抽风”。

扩缩容是一套“系统的系统”。如果你觉得它不稳,往往不是 HPA 这个功能不好,而是:

  • requests 不准(分母错)
  • 多个控制器在打架(HPA/VPA/发布/surge 同时发生)
  • 集群容量层(Cluster Autoscaler/节点池)跟不上

这篇 tips 给一个可落地的稳定扩缩容思路。

三层扩缩容:先搞清楚谁负责什么

  1. HPA(Horizontal Pod Autoscaler):改副本数(replicas)
  2. VPA(Vertical Pod Autoscaler):改/推荐 requests(有些模式也能自动改)
  3. Cluster Autoscaler:改节点数(加/减节点)

想要稳定,需要三层对齐:指标、requests、容量与启动时间。

Step 0:requests 是地基(不写或写错,一切都不准)

很多扩缩容逻辑都以 requests 为基础:

  • HPA 的 CPU utilization 常用:当前 CPU / requests.cpu
  • 调度器靠 requests 放置 Pod
  • Cluster Autoscaler 看到 Pod Pending 才会补节点(Pending 常由 requests 触发)

因此第一步永远是:所有容器都要有合理 requests

HPA 基础例子(CPU 利用率)

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api
  namespace: app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 3
  maxReplicas: 30
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60

含义:

  • 平均 CPU 接近 requests 的 60% 时保持稳定
  • 高于 60% 倾向扩容,低于 60% 倾向缩容

但注意:如果 requests 不准,这个“60%”没有意义。

防止抖动:stabilization window 与 scaling policy

HPA v2 支持行为配置,用来避免“上上下下”:

behavior:
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
      - type: Percent
        value: 100
        periodSeconds: 60
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
      - type: Percent
        value: 20
        periodSeconds: 60

思路是:

  • 扩容尽量快(应对突发)
  • 缩容慢一点(避免流量小波动导致频繁缩容)

指标选择:CPU 不是万能

CPU 利用率适合:

  • 典型无状态 Web/API

但对这些类型往往不准:

  • 队列 worker(更适合 backlog/lag)
  • 内存型服务(CPU 低但内存持续升)
  • I/O 型服务(瓶颈不在 CPU)

更靠谱的做法是选择贴近业务负载的指标:

  • 队列深度、消费滞后
  • RPS/并发连接数
  • 关键路径延迟(谨慎,避免反馈环)

结论:

用“能代表负载”的指标扩容,而不是只看资源消耗。

冷启动与 readiness:扩了也不一定立刻有用

扩容增 Pod,但 Pod 变成可用需要时间:

  • 拉镜像
  • 启动(JVM warmup、迁移、缓存)
  • readiness 通过

如果启动慢,HPA 扩容再快也救不了峰值。

你可能需要:

  • 提高 minReplicas
  • 提前预热镜像(节点缓存)
  • 对启动慢服务加 startupProbe
  • 合理的 scaleUp policy

Cluster Autoscaler:容量层的关键

HPA 扩容后,如果节点不够,Pod 会 Pending。Cluster Autoscaler 需要能识别并补节点。

如果 CA 不工作,常见原因:

  • affinity/nodeSelector 让 Pod 只能去不存在的节点池
  • requests 太大,没有任何节点规格能容纳
  • 节点池 max size/配额到顶
  • PDB/约束导致缩容逻辑受限(与 scale-down 相关)

排查 Pending:

kubectl get pod -n <ns> | rg -n "Pending"
kubectl describe pod -n <ns> <pod> | rg -n "FailedScheduling|Insufficient"

VPA:即使只做推荐也很有价值

VPA 模式(按你们平台而定)通常有:

  • Off:只推荐
  • Initial:只在创建 Pod 时设置 requests
  • Auto:自动调整 requests(可能带来重建/波动,需谨慎)

建议路径:

  1. 先 Off(观察推荐,校正 requests)
  2. 再 Initial(更安全的自动化)
  3. 最后再评估 Auto(按业务风险分层)

HPA + VPA 一起用:避免打架

如果 HPA 以 CPU utilization 扩容,而 VPA 频繁改 CPU requests:

  • 分母变了,HPA 会突然改变判断
  • 容易产生“看起来负载没变,但副本数在变”的现象

实践上常见组合:

  • HPA 用 CPU 或业务指标控制副本数
  • VPA 用来推荐/调整 内存 requests(或以 Initial 模式周期性更新)

内存扩缩容要谨慎

HPA 也能按内存指标扩缩,但内存通常是滞后指标:

  • 缓存增长导致内存上升,但扩容并不一定能立刻缓解
  • 缩容后缓存重建反而变慢

更常见的稳妥方式:

  • HPA 按 CPU/RPS 扩容
  • VPA 优化内存 requests
  • 缩容保守(长 stabilization window)

一个现实的落地计划(不容易翻车)

  1. 所有容器补齐 requests(先做到“可预测调度”)
  2. 上 HPA:target 保守、scaleDown 慢
  3. 做一次压测或观察一次真实峰值(看扩容时间线)
  4. 确认 CA 能补节点且节点池有余量/配额
  5. 上 VPA 推荐,逐步把 requests 校正到更合理

排障:HPA/指标为什么不工作

看 HPA 状态:

kubectl get hpa -n <ns>
kubectl describe hpa -n <ns> <hpa>

常见提示:

  • 无法获取指标(metrics pipeline 问题)
  • 缺 requests(HPA 无法计算 utilization)
  • 频繁 scale events(需要 behavior 调整或指标换更贴近负载)

Checklist

  • requests 对齐真实负载(别拍脑袋)
  • HPA 缩容保守,避免抖动
  • 指标链路可靠(metrics-server/adapter)
  • Cluster Autoscaler 能满足调度约束并有容量余量
  • 用 VPA 推荐持续修正 requests

参考链接

FAQ

Q: HPA 和 VPA 怎么选? A: HPA 负责副本数,VPA 负责 requests/limits 的自动校准。同一工作负载不要让两者同时生效,可用 VPA recommendation 模式配合 HPA。

Q: 为什么 HPA 会抖动? A: 指标延迟和激进策略会导致反复伸缩。加 stabilization window、放慢 scale down,并调准目标值。

Q: 一定要装 metrics-server 吗? A: CPU/内存的 HPA 需要 metrics-server;自定义指标需要指标管道(如 Prometheus + adapter)。