导读:本期聚焦于勇士创作的《Kubernetes集群自动扩缩容指标如何自定义?HPA与Prometheus自定义指标实战详解》,敬请观看详情。HPA默认只支持CPU和内存指标,但在真实业务场景中,QPS、消息队列堆积长度、接口响应时间往往才是判断扩容时机的关键信号。本文围绕Kubernetes自定义指标体系展开,先讲清HPA的工作原理与三种指标类型(资源指标、自定义指标、外部指标)的区别,再演示如何部署Prometheus与Prometheus Adapter,把应用暴露的业务数据转换成HPA可用的自定义指标,最后给出基于QPS和队列堆积的完整配置示例,以及指标采集延迟、抖动等常见问题的排查思路,帮助你建立一套贴合业务的弹性伸缩方案。

Kubernetes自带的Horizontal Pod Autoscaler(HPA)在默认配置下只能根据CPU和内存使用率来决定Pod的扩缩容。但很多业务的压力并不能体现在这两个指标上:比如一个消息队列消费者服务,CPU占用很低,队列里却积压了几万条消息;又比如一个Web服务在QPS暴涨时CPU还没来得及升高,接口已经开始超时了。这时候就需要自定义指标(Custom Metrics)和外部指标(External Metrics)出场了。本文会从HPA的原理讲起,一步步演示如何搭建一套基于Prometheus的自定义指标扩缩容体系。

Kubernetes集群自动扩缩容指标如何自定义?HPA与Prometheus自定义指标实战详解

一、先弄懂HPA支持的三种指标类型

HPA从v1到v2演进后,autoscaling/v2 API引入了三种指标来源,理解它们的区别是自定义指标的第一步。第一种是Resource类型,也就是CPU和内存,由metrics-server组件直接采集,开箱即用但只有这两个指标。第二种是Pods类型,允许你为每个Pod暴露自定义指标,HPA会对所有副本的指标求平均值,比如每个Pod的每秒请求数。第三种是External类型,指标来源不在Pod本身,而是集群外部的东西,典型例子就是RabbitMQ的队列长度、Redis的某个key的值。

三者的本质区别在于指标的归属对象。ResourcePods类型都挂在Pod上,删除Pod指标随之消失;而External类型与Pod无关,即使副本数为零,指标依然存在。这一点在缩容到0或者依赖外部资源排队场景中非常关键。另外要注意,Pods类型指标在做除法时的分母是Pod数量,如果你的指标本身就是全局值(比如整个服务的总QPS),直接用Pods类型会导致副本越多每个Pod的值越小,扩缩容逻辑会完全错乱,这种情况下应该用External类型并自己控制计算逻辑。

还需要了解HPA的控制循环逻辑:HPA Controller默认每15秒(可通过--horizontal-pod-autoscaler-sync-period调整)从指标API拉取一次数据,计算期望副本数并与当前值对比。公式大致是期望副本数 = ceil(当前副本数 × 当前指标值 / 目标指标值)。如果指标接口返回错误或者数据缺失,HPA会跳过本轮计算并记录事件,这也是排查扩容不生效时首先要看的点。

二、搭建Prometheus与Prometheus Adapter指标链路

自定义指标的核心组件是Prometheus Adapter,它的作用是充当翻译官:Prometheus负责抓取应用暴露的指标,Adapter把这些时序数据转换成Kubernetes的Custom Metrics API格式,HPA才能查询到。整套链路是:应用暴露metrics端点到Prometheus抓取,Adapter查询Prometheus并对外提供API。

首先确认Prometheus已经部署并能正常抓取到业务指标。以一个暴露HTTP QPS指标的应用为例,通过ServiceMonitor或prometheus.io/scrape注解让Prometheus采集,然后在Prometheus里验证查询语句:

# 验证Prometheus中已有该指标
curl -s http://prometheus:9090/api/v1/query \
  --data-urlencode 'query=sum(rate(http_requests_total{app="web"}[2m]))'

接下来部署Prometheus Adapter。最关键的配置是custom-metrics-config.yaml中的规则映射,它决定了Prometheus查询结果如何映射成API指标:

rules:
- seriesQuery: 'http_requests_total{app!=""}'
  seriesFilters: []
  resources:
    overrides:
      namespace: {resource: "namespace"}
      app: {resource: "service"}
  name:
    matches: "^(.*)_total$"
    as: "http_requests_per_second"
  metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'

这段配置里有几个容易踩坑的地方。resources.overrides把Prometheus的label映射成Kubernetes的资源维度,app label映射为service后,HPA里才能用service/web这样的格式引用指标。metricsQuery中的<<.Series>><<.LabelMatchers>>是模板变量,Adapter会自动填充。部署完成后用kubectl get --raw验证:

# 查看Adapter暴露了哪些自定义指标
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .

# 查询具体指标值
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/services/web/http_requests_per_second"

如果返回404,优先检查Adapter的规则配置和Prometheus查询是否能出数据;如果返回的数据是空的,多半是label映射对不上。验证通过后再创建HPA资源:

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: "1000"

三、外部指标实战:基于消息队列堆积量扩缩容

消费类服务的最佳扩容信号往往不是CPU,而是消息堆积量。假设Prometheus中已经采集了RabbitMQ的rabbitmq_queue_messages_ready指标,我们可以把它配置成外部指标。Adapter的配置中,External指标不需要映射resource,直接用seriesQuery过滤出目标队列即可:

rules:
- seriesQuery: 'rabbitmq_queue_messages_ready{queue="order-queue"}'
  name:
    matches: "^rabbitmq_queue_messages_ready$"
    as: "order_queue_backlog"
  metricsQuery: 'max(rabbitmq_queue_messages_ready{queue="order-queue"})'

对应的HPA配置改为External类型,目标设定为每个副本处理5000条堆积消息。这种模式下有一个实用技巧:设置一个合理的minReplicas保底,同时把目标值设得偏保守一点。因为消息消费速率有上限,堆积量短期波动很正常,如果目标太敏感会导致副本频繁增减,反而增加调度开销。

除了单一指标,autoscaling/v2还支持多指标组合,HPA会取所有指标算出的最大期望副本数。比如同时配置CPU和队列堆积两个指标,CPU指标负责应对计算密集型突发,队列指标负责消费能力不足的场景,两者取最大值,扩容更及时。

四、常见问题与调优建议

第一个高频问题是扩缩容抖动。流量在临界值附近波动时,副本数会来回变化。解决办法是配置HPA的行为参数(behavior字段),比如缩容时设置stabilizationWindowSeconds: 300让系统等待5分钟再缩容,扩容时限制每分钟最多增加一定比例的副本,这些策略能显著减少震荡。

第二个问题是指标延迟。Prometheus抓取间隔加上rate函数的计算窗口,整体可能滞后30秒到1分钟,对于秒级流量突刺,扩容永远慢半拍。实践中的做法是缩短抓取间隔、使用更小的rate窗口,同时把扩容目标值调低留出缓冲,而不是追求指标零延迟。另外建议在Pod里预留好resources.requests,否则扩出来的新Pod会因为资源不足卡在Pending状态,扩容形同虚设。

第三个问题是多指标冲突排查。当HPA不生效时,依次执行kubectl describe hpa查看事件信息、确认Adapter返回值是否为<unknown>、检查Prometheus查询本身是否有数据,基本能定位到问题层。最后提醒一点,自定义指标体系建设完成后,一定要在低峰期做一次压测演练,验证从指标上升到副本扩容再到流量承接的完整链路,避免故障时刻才发现配置有漏洞。

KubernetesHPA自动扩缩容自定义指标修改时间:2026-09-05 12:05:08

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