HPA 基于 CPU 扩缩容出现抖动,你会如何引入自定义指标并设置稳定窗口
解读
- 抖动本质:CPU 瞬时冲高→HPA 立即扩容→Pod 启动后 CPU 回落→HPA 立即缩容→流量再来又冲高,形成“扩-缩-扩”循环。
- 国内生产环境常见诱因:
- 促销/整点秒杀带来的脉冲流量,CPU 采样周期 15 s 内被“尖刺”拉高;
- Java 应用 Full GC 瞬时拉高 CPU,但仅持续 3–5 s;
- 容器限额设置不合理,单核限流导致 CPU 被 throttle,利用率失真。
- 面试考点:
- 能否跳出“调大 CPU 阈值”思维,用自定义指标刻画“真实业务压力”;
- 能否利用 K8s 原生 stabilizationWindowSeconds、behavior.scaleDown/selectPolicy 等参数做“防抖”;
- 能否给出可落地的灰度验证方案,兼顾国内云厂商(ACK、TKE、CCE)实现差异。
知识点
- 自定义指标链路
Prometheus → Adapter(prometheus-adapter 或 alibaba-cloud-metrics-adapter)→ Metrics API(custom.metrics.k8s.io)→ HPA v2。 - HPA 行为策略
- behavior.scaleDown.stabilizationWindowSeconds:缩容冷静期;
- behavior.scaleDown.selectPolicy: Min,取所有指标中最保守的推荐副本数;
- behavior.scaleDown.policies:可定义“过去 300 s 内最多缩 10%” 的步长限制。
- 业务层黄金指标
- QPS/RT:gateway_request_qps{job="ingress-nginx"}、gateway_request_duration_seconds_bucket;
- 队列积压:kafka_consumer_lag_sum、rocketmq_group_diff;
- 线程池饱和度:tomcat_threads_busy_ratio。
- 采样窗口与 P95 聚合
用 2 min 滑动 P95 过滤尖刺,比瞬时平均值更稳。 - 国内云差异
- 阿里云 ACK:prometheus-adapter 需开启 alibaba-metrics-discovery,支持 SLB 7 层 QPS 直接透出;
- 腾讯云 TKE:自定义指标需通过云监控 CLS 中转,adapter 版本 ≥0.10 才支持 selectPolicy。
答案
“出现抖动,我不会简单把 CPU 阈值从 70% 调到 85%,而是分三步走:
第一步,引入业务自定义指标。选最能代表‘用户压力’的指标,比如网关 QPS 或消息队列堆积量。以 Gateway QPS 为例,我们在 Prometheus 里记录 ingress-nginx 的 gateway_request_qps,adapter 配置:
- seriesQuery: gateway_request_qps{namespace!=""} resources: {template: "<<.Resource>>"} name: {matches: "gateway_request_qps", as: "gateway_qps_per_pod"} metricsQuery: 'sum(rate(gateway_request_qps[2m])) by (<<.GroupBy>>) / count(pod:container_cpu_usage:sum{<<.LabelMatchers>>})'
得到“单 Pod 平均 QPS”指标,HPA 里同时监控 CPU 与 gateway_qps_per_pod。
第二步,设置稳定窗口与步长策略,防止毛刺触发扩缩。HPA v2 行为字段如下:
behavior: scaleDown: stabilizationWindowSeconds: 300 # 过去 5 min 内最大副本数 selectPolicy: Min policies: - type: Percent value: 10 periodSeconds: 60 # 每 60 s 最多缩 10% scaleUp: stabilizationWindowSeconds: 0 selectPolicy: Max policies: - type: Percent value: 50 periodSeconds: 60
这样即使 CPU 瞬时掉到 20%,也必须连续 5 min 保持低负载才真正缩容,且一次只缩 10%,把抖动幅度降到 1–2 Pod。
第三步,灰度验证。先在预发环境注入 2× 脉冲流量,持续 10 min,观察:
- 扩容触发时间 ≤ 30 s,冷启动 RT 上涨不超过 20%;
- 流量回落后,缩容动作延迟 5 min,副本数呈阶梯式下降,无回弹。
通过后再上生产,并配合告警:若 10 min 内扩缩循环 ≥3 次,自动锁住 HPA 手动介入。”
拓展思考
- 如果业务是“定时任务型”,CPU 每天 02:00 突增 3 min,是否仍用 QPS?可改用 CronHPA 提前扩容,避免与实时指标混用。
- 国内部分金融客户要求“副本数不能低于 3”,可通过 HPA 的 minReplicas 硬限制,但突发高峰可能仍不足,可再引入 KEDA 的“队列长度 + Cron”混合触发器。
- 当集群节点池开启 CA(Cluster Autoscaler)时,HPA 扩容后若节点不够,CA 再扩容节点,整体冷启动可能 3–5 min,需把 stabilizationWindowSeconds 与 CA 的扩容信号联动,防止“Pod 已缩、节点才到”的浪费。