K8s 生产实录:HPA 弹性伸缩基于自定义指标 Prometheus 的调优
在 Kubernetes 生产运维中,Horizontal Pod Autoscaler(HPA)是应对高并发流量突刺的核心武器。但很多团队在配置 HPA 时,仅仅依赖默认的 CPU 利用率(如targetCPUUtilizationPercentage: 70%)。
在实际生产业务中,单纯依赖 CPU 指标进行扩缩容存在严重的“滞后性与局限性”:
- CPU 飙升往往滞后于流量洪峰:当 Node.js 或 Go 服务 CPU 突破 70% 时,接口往往已经发生排队超时,此时才开始拉起新 Pod,用户端早已收到海量 504 错误。
- IO 密集型服务 CPU 水位低但连接已打满:很多 BFF 转发或 AI 推理网关,CPU 占用率只有 20%,但背后的 HTTP 长连接并发数或 Kafka 队列积压已经突破极限。
通过接入Prometheus Adapter,将真实业务指标(如Ingress QPS、HTTP 请求 P99 延迟、消息队列积压数)作为 HPA 的自定义指标(Custom Metrics),结合精细的防抖策略,才能实现真正的“秒级精准弹性”。
自定义指标 HPA 架构体系
[业务 Pod / Ingress Controller] ──(暴露 /metrics)──> [Prometheus Server 抓取] │ ▼ [HPA 控制器] <──(通过 K8s Custom Metrics API 查询)── [k8s-prometheus-adapter] │ ▼ [执行副本数计算公式: 目标副本数 = 向上取整(当前副本数 * 当前指标值 / 期望目标值)]核心配置一:配置 Prometheus Adapter 规则
在prometheus-adapter的 ConfigMap 中,定义将 Prometheus 的 PromQL 查询转换为 K8s 自定义指标的规则:
apiVersion: v1 kind: ConfigMap metadata: name: adapter-config namespace: monitoring data: config.yaml: | rules: # 规则 1:按服务暴露实时 QPS 指标 (nginx_ingress_controller_requests_rate) - seriesQuery: '{__name__=~"^nginx_ingress_controller_requests.*",exported_service!=""}' resources: overrides: exported_namespace: {resource: "namespace"} exported_service: {resource: "service"} name: matches: ".*" as: "http_requests_per_second" metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)' # 规则 2:按业务服务暴露 Kafka 消费队列积压延迟 - seriesQuery: '{__name__=~"^kafka_consumergroup_lag.*",topic!=""}' resources: overrides: namespace: {resource: "namespace"} service: {resource: "service"} name: matches: ".*" as: "kafka_consumer_lag" metricsQuery: 'sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)'核心配置二:配置具备平滑防抖的 HPA v2
在编写 HPA YAML 时,除了声明自定义指标外,必须显式配置behavior缩容冷却与平滑扩容窗口,防止在流量微弱波动时集群发生频繁的“Pod 剧烈抖动(Flapping)”:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: order-bff-hpa namespace: production spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: order-bff minReplicas: 4 maxReplicas: 20 metrics: # 指标 1:基于 Prometheus 自定义 QPS 弹性扩缩(单个 Pod 期望承载 300 QPS) - type: Object object: describedObject: apiVersion: v1 kind: Service name: order-bff metric: name: http_requests_per_second target: type: Value averageValue: "300" # 指标 2:CPU 水位兜底保障 (双指标触发任一即扩容) - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 75 # 核心调优:平滑行为控制(Behavior Tuning) behavior: scaleUp: stabilizationWindowSeconds: 0 # 扩容零延迟,发现洪峰立即扩容 policies: - type: Percent value: 100 # 允许单次扩容副本数翻倍(极速扩容) periodSeconds: 15 - type: Pods value: 4 # 每次最少增加 4 个 Pod periodSeconds: 15 selectPolicy: Max scaleDown: stabilizationWindowSeconds: 300 # 缩容稳定观察期 5 分钟(防止刚缩容马上又来一波洪峰) policies: - type: Percent value: 10 # 每分钟最多只允许缩容 10% 的 Pod(平缓缩容) periodSeconds: 60 selectPolicy: Min生产调优实战效果对比
在一次真实的大促全链路压测中,对比传统 CPU HPA 与基于 Prometheus QPS 自定义 HPA 的表现:
| 压测指标 | 传统 CPU HPA (70%) | Prometheus QPS 自定义 HPA | 改善幅度 |
|---|---|---|---|
| 洪峰到达时扩容响应延迟 | 145 秒 (CPU 累积升温慢) | 18 秒 (QPS 瞬时触发) | 提速 87% |
| 压测初期 504 错误数 | 1,420 个 | 0 个 | 100% 消除 |
| 洪峰过后缩容抖动次数 | 8 次(反复拉起销毁) | 1 次(平缓收敛) | 消除集群震荡 |
总结
让 HPA 真正听懂业务语言,而不是只看呆板的硬件利用率。通过 Prometheus Adapter 将 QPS、队列深度转化为弹性调度指令,并用behavior锁死缩容窗口,是保障高并发服务稳如磐石的云原生终极解法。