Kubernetes HPA为什么需要自定义指标
Kubernetes水平Pod自动扩缩器(HPA)默认基于CPU利用率做伸缩决策,这对Web类应用勉强够用,但对消息消费、队列处理、GPU推理等场景完全失效。一个消息消费者Pod的CPU可能只有20%,但队列积压了10万条消息——靠CPU指标永远触发不了扩容。
自定义指标让HPA基于业务真实负载做决策,而不是代理CPU这一间接指标。Prometheus + Prometheus Adapter是当前最成熟的方案。
Prometheus Adapter部署与配置
Prometheus Adapter充当Kubernetes自定义指标API的后端,将Prometheus查询结果转换为Kubernetes可识别的指标格式:
# values.yaml - Helm部署配置
image:
repository: k8s.gcr.io/prometheus-adapter/prometheus-adapter
tag: v0.12.0
prometheus:
url: http://prometheus-server.monitoring.svc
port: 9090
rules:
custom:
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_total"
as: "${1}_per_second"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
rules.custom段定义了如何将Prometheus指标映射为Kubernetes自定义指标。上面的规则将http_requests_total转换为http_requests_per_second,用2分钟窗口的速率计算。
部署命令:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus-adapter prometheus-community/prometheus-adapter -n monitoring -f values.yaml
验证自定义指标API可用:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq . | head -20
基于消息队列深度的HPA配置
消息消费场景下,队列深度是最直接的业务指标。以RabbitMQ为例,先在Prometheus中采集队列指标:
# RabbitMQ Exporter暴露的指标
# rabbitmq_queue_messages{queue="order_process"} 12580
在Prometheus Adapter的rules中添加队列指标规则:
rules:
custom:
- seriesQuery: 'rabbitmq_queue_messages{queue!="",namespace!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
name:
matches: "rabbitmq_queue_messages"
as: "queue_messages"
metricsQuery: 'rabbitmq_queue_messages{queue="order_process",<<.LabelMatchers>>}'
创建HPA资源:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-processor-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-processor
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: queue_messages
target:
type: AverageValue
averageValue: "500" # 每个Pod期望处理500条消息
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120
behavior段精细控制扩缩行为:扩容30秒内生效,每次最多翻倍;缩容需稳定5分钟,每次最多减1个Pod。这种保守策略避免队列消息短暂波动导致Pod频繁创建销毁。
基于QPS的Web应用弹性扩缩
Web应用用请求速率做扩缩比CPU更精准:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000" # 每Pod 1000 QPS
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
policies:
- type: Percent
value: 50
periodSeconds: 60
- type: Pods
value: 4
periodSeconds: 60
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 600
policies:
- type: Percent
value: 10
periodSeconds: 120
同时配置QPS和CPU两个指标,Kubernetes取需求副本数更大的那个。selectPolicy: Max确保扩容用最激进策略——两种策略取最大值。
混沌工程验证弹性策略有效性
HPA配置完成后,必须用混沌工程验证在真实异常下弹性策略是否生效。Chaos Mesh是Kubernetes生态的主流工具:
# 注入CPU压力测试
apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
name: cpu-stress-test
namespace: chaos-testing
spec:
selector:
namespaces: ["production"]
labelSelectors:
app: "api-server"
stressors:
cpu:
workers: 4
load: 80
duration: "5m"
注入CPU压力后,观察HPA事件:
kubectl get hpa api-server-hpa -w
正常情况下30秒内HPA会触发扩容。如果1分钟内无反应,需要排查:Prometheus指标是否正常采集、Adapter规则是否匹配、HPA指标名称是否一致。
流量突增场景模拟:
apiVersion: chaos-mesh.org/v1alpha1
kind: HTTPChaos
metadata:
name: traffic-surge
namespace: chaos-testing
spec:
selector:
namespaces: ["production"]
labelSelectors:
app: "api-server"
target: Request
podPhase: Running
schedule:
duration: "3m"
method:
- GET
path:
- "/api/v1/orders"
abort: false
delay:
fixed: 5ms # 注入5ms延迟模拟高负载
监控告警闭环
弹性扩缩本身也需要监控。关键告警项:
# Prometheus告警规则
groups:
- name: hpa-alerts
rules:
- alert: HPAAtMaxReplicas
expr: kube_hpa_status_current_replicas == kube_hpa_spec_max_replicas
for: 5m
labels:
severity: warning
annotations:
summary: "HPA {{ $labels.hpa }} 已达最大副本数但仍需扩容"
- alert: HPAScaleUpFrequent
expr: increase(kube_hpa_status_current_replicas[10m]) > 3
labels:
severity: info
annotations:
summary: "HPA {{ $labels.hpa }} 10分钟内扩容超过3次,检查负载模式"
- alert: HPACustomMetricUnavailable
expr: kube_hpa_status_condition{condition="ScalingLimited",status="true"} > 0
for: 2m
labels:
severity: critical
annotations:
summary: "HPA {{ $labels.hpa }} 扩缩受限,检查指标源"
HPA达最大副本数的告警尤其重要——意味着当前资源上限无法承载业务流量,需要手动介入或调整maxReplicas。这是容量规划的直接信号。
弹性扩缩不是配置完就结束的事。持续观察扩缩行为是否符合预期,根据业务流量模式调整stabilizationWindowSeconds和扩缩策略,才能让Kubernetes容器编排真正发挥自动化运维的价值。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-rong-qi-bian-pai-jin-jie-hpa-zi-ding-yi-zhi-biao/