Kubernetes HPA自定义指标扩缩容的应用场景
Kubernetes水平Pod自动扩缩容(HPA)默认只支持CPU和内存利用率指标,但真实业务场景中,CPU利用率往往不能准确反映负载压力。消息队列堆积深度、HTTP请求延迟、数据库连接数等业务指标才是更精确的扩缩容信号。通过Prometheus Adapter将自定义指标接入Kubernetes Metrics API,HPA即可基于业务真实负载做弹性伸缩,这是生产环境保障服务稳定性的核心能力。
Metrics API与自定义指标体系
Kubernetes的指标体系分三层:
Resource Metrics——CPU/内存指标,由metrics-server提供,是最基础的HPA数据源。
Pod Metrics——Pod级别的自定义指标,如每个Pod的消息消费速率。
Object/External Metrics——外部系统指标,如RabbitMQ队列深度、Redis命令延迟,与特定Kubernetes资源无关。
自定义指标需要Prometheus Adapter将Prometheus中的指标暴露为Kubernetes Metrics API格式,HPA控制器通过API查询指标值。
Prometheus Adapter安装与配置
使用Helm安装prometheus-adapter:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring --create-namespace \
--set prometheus.url=http://prometheus.monitoring.svc:9090 \
--set prometheus.port=9090
核心配置在于rules.custom段,定义PromQL查询到Metrics API指标的映射关系。以下是一个完整的values覆盖配置:
# custom-values.yaml
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(http_requests_total{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
- seriesQuery: 'rabbitmq_queue_messages{queue!="",namespace!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
name:
matches: "^(.*)$"
as: "${1}"
metricsQuery: 'rabbitmq_queue_messages{<<.LabelMatchers>>}'
- seriesQuery: 'redis_connected_clients{namespace!="",app!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
app: {resource: "deployment"}
name:
as: "redis_connected_clients"
metricsQuery: 'redis_connected_clients{<<.LabelMatchers>>}'
prometheus:
url: http://prometheus.monitoring.svc
port: 9090
更新安装:
helm upgrade prometheus-adapter prometheus-community/prometheus-adapter \
--namespace monitoring \
-f custom-values.yaml
验证Metrics API可用性
安装完成后,验证自定义指标是否注册成功:
# 查看已注册的自定义指标
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq '.resources[].name'
# 查询特定指标
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http-requests-per-second
# 测试外部指标
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1 | jq '.items[].metricName'
如果查询返回404,检查Prometheus Adapter日志中是否有PromQL解析错误:
kubectl logs -n monitoring deploy/prometheus-adapter | grep -i error
HPA基于自定义指标的配置
场景1:基于HTTP请求QPS扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http-requests-per-second
target:
type: AverageValue
averageValue: "1000"
场景2:基于RabbitMQ队列深度扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-consumer-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-consumer
minReplicas: 2
maxReplicas: 50
metrics:
- type: External
external:
metric:
name: rabbitmq_queue_messages
selector:
matchLabels:
queue: order-queue
target:
type: AverageValue
averageValue: "500"
场景3:多指标混合策略
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: gateway-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-gateway
minReplicas: 5
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http-requests-per-second
target:
type: AverageValue
averageValue: "2000"
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 50
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
扩缩容行为调优
HPA的behavior字段是控制扩缩容节奏的关键。生产环境中常见的配置原则:
扩容要快——stabilizationWindowSeconds设为0,立刻响应负载增长。缩容要慢——冷却窗口300秒以上,防止指标波动导致Pod反复创建销毁。scaleDown策略用百分比(如10%/分钟),避免一次性缩容过多导致负载再次飙升。
多指标策略下HPA取各指标计算出的最大副本数,即”取大者”原则。这意味着任何一个指标触发扩容条件都会执行扩容,但缩容需要所有指标都低于阈值。
常见问题与排查
HPA显示”failed to get custom metric”:检查Prometheus Adapter的seriesQuery是否匹配Prometheus中的实际指标名和标签。用kubectl get --raw直接查询Metrics API确认指标路径是否正确。
扩缩容频繁抖动:增大scaleDown.stabilizationWindowSeconds到300-600秒,或对指标查询增加rate()窗口(如从1m改为5m)平滑短期波动。
PromQL查询性能差:Prometheus Adapter每个HPA评估周期(默认15秒)都执行一次PromQL查询。高基数指标(如按URL路径分组的请求量)会导致查询超时。降低标签维度或使用Recording Rule预聚合。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kuberneteshpa-zi-ding-yi-zhi-biao-zi-dong-kuo-suo-rong-pei/