导读:本期聚焦于小伙伴创作的《集群弹性伸缩如何基于 HPA 自定义指标实现精准扩缩容?》,敬请观看详情。当业务流量出现突发抖动,仅靠 CPU 利用率触发的默认扩缩容往往反应滞后或过度。HPA 自定义指标允许把每秒请求数、消息队列积压长度、应用内部延迟等真实负载信号接入扩缩逻辑。本文梳理自定义指标背后的采集链路:从应用暴露 Prometheus 格式数据,到 Adapter 将指标注册到 API 聚合层,再到 HPA 控制器周期性查询并计算结果。理解这条链路后,开发者能避开指标命名不规范、采样间隔过长导致的抖动问题,并根据业务特征设定合理的目标值与缩容冷却时间,让集群在成本与稳定性之间取得平衡。

在 Kubernetes 生产环境中,工作负载的流量曲线越来越难以用单一资源维度刻画。原生 HPA 基于 CPU 和内存的扩缩策略,在应对消息驱动型服务或长连接网关时常常失效。通过引入自定义指标,我们可以将业务语义层面的信号转化为扩缩依据,使副本数量真正跟随真实压力变化。

集群弹性伸缩如何基于 HPA 自定义指标实现精准扩缩容?

自定义指标的工作机制与架构链路

HPA 的扩缩决策依赖于 metrics 查询接口。当使用自定义指标时,集群需要部署 Metrics Adapter 组件,它负责将外部监控系统(如 Prometheus)中的时序数据,翻译成 Kubernetes API 所能识别的指标格式。HPA 控制器并不会直接连接监控系统,而是向 API 聚合层发起请求,聚合层再把请求转发给对应的 Adapter。这种解耦设计让 HPA 本身无需关心指标来源。

具体流程中,应用首先通过客户端库暴露符合 Prometheus 规范的端点,例如用 Counter 记录 HTTP 请求总量。Prometheus 定时抓取后存储为时序数据。Adapter 配置对应的发现规则,把诸如 http_requests_per_second 这样的指标映射为 custom.metrics.k8s.io 组下的资源。随后用户在 HPA 对象中引用该指标名并设定目标值,控制器便周期性计算当前值与目标值的比率来决定扩缩。

这一机制的优势在于扩展性强。除了请求率,还可以接入 Kafka 消费滞后量、Redis 连接数、甚至业务订单堆积数。但也带来新的挑战:指标链路变长后,任一环节延迟都会造成 HPA 决策滞后。因此在生产里通常将 Adapter 与 Prometheus 同可用区部署,并压缩抓取间隔到 15 秒级别,避免扩缩动作明显落后真实负载。

基于 Prometheus 的指标暴露与 Adapter 配置实例

我们以一个简单的 Go HTTP 服务为例,演示如何暴露请求率指标。服务使用官方 Prometheus 客户端,在处理函数中对计数器递增,并挂载 /metrics 端点。Kubernetes 的 Service 与 Pod 需添加 prometheus.io/scrape: "true" 注解以便被自动发现。

package main

import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var reqCounter = prometheus.NewCounter(prometheus.CounterOpts{
    Name: "http_requests_total",
    Help: "Total number of HTTP requests",
})

func init() {
    prometheus.MustRegister(reqCounter)
}

func handler(w http.ResponseWriter, r *http.Request) {
    reqCounter.Inc()
    w.Write([]byte("ok"))
}

func main() {
    http.Handle("/metrics", promhttp.Handler())
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Adapter 侧常用 kube-prometheus-stack 附带的 prometheus-adapter。其核心是配置文件中的 rules 段落,将 PromQL 查询结果绑定为自定义指标。例如下面规则把每秒请求率映射为名为 pods/http_requests_per_second 的指标,HPA 可直接引用。

rules:
- seriesQuery: 'http_requests_total'
  resources:
    overrides:
      namespace: {resource: "namespace"}
      pod: {resource: "pod"}
  name:
    matches: "http_requests_total"
    as: "http_requests_per_second"
  metricsQuery: 'sum(rate(http_requests_total[1m])) by (pod)'

配置生效后,使用 kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests_per_second" 可验证指标是否成功注册。若返回 JSON 中包含数值,说明链路通畅。这一步排查非常关键,很多 HPA 不生效的问题都源于 Adapter 规则匹配失败或权限不足。

扩缩策略调优与常见误区规避

即便指标接通,不合理的参数仍会导致集群抖动。HPA 默认的缩容冷却期为五分钟,扩容则较快。对于流量陡降明显的场景,过长冷却会让资源闲置;而对延迟敏感服务,频繁扩容可能引发冷启动雪崩。我们可以通过 behavior 字段精细控制扩缩速率,分别设定 scaleUpscaleDown 的步长与稳定窗口。

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  minReplicas: 2
  maxReplicas: 20
  metrics:
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "100"
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60

另一个常见误区是直接使用未做聚合的原始指标。例如将 Pod 的瞬时错误数作为扩缩依据,会因偶发报错造成非理性扩容。正确做法是用速率或滑动平均值平滑,并在 PromQL 中按 Pod 或 Deployment 合理分组。此外,自定义指标名称必须保持稳定,CI 中修改监控埋点而不同步 Adapter 规则,会让 HPA 陷入永久未知指标状态。

从成本视角看,自定义指标让弹性更贴近业务,但也要求团队具备指标治理意识。建议将核心链路的指标纳入告警,并定期审视 HPA 事件,确认扩缩动作与流量曲线吻合。只有把指标质量、参数调优和监控闭环结合起来,集群弹性伸缩才能既省成本又不误事。

Kubernetes_HPA自定义指标弹性伸缩修改时间:2026-08-15 19:32:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。