HPA自动伸缩原理:从CPU指标到自定义指标驱动
Kubernetes Horizontal Pod Autoscaler(HPA)是容器编排平台实现弹性伸缩的核心组件。HPA控制器以固定间隔(默认15秒)轮询指标源,根据当前指标值与目标值的比值计算期望副本数。HPA v2支持三类指标源:Resource指标(CPU/内存)、Pods自定义指标和外部指标。
伸缩算法公式为:期望副本数 = ceil(当前副本数 × 当前指标值 / 目标指标值)。当指标低于目标时缩减,高于目标时扩容。HPA内置冷却机制防止抖动:扩容无延迟(尽快响应流量增长),缩容默认等待5分钟(–horizontal-pod-autoscaler-downscale-stabilization-window)。理解这个时间窗口对配置合理的伸缩策略至关重要。
基础配置:基于CPU利用率的HPA
使用CPU指标的前提是Deployment中的容器必须配置resources.requests.cpu。HPA计算的是实际CPU使用量占request的百分比。以下是一个完整的Deployment+HPA配置示例:
# api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: registry.example.com/api-server:v2.1
resources:
requests:
cpu: 200m # 0.2核
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
ports:
- containerPort: 8080
---
# hpa-cpu.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60 # 目标CPU利用率60%
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # 扩容立即执行
policies:
- type: Percent
value: 100 # 每次最多扩容100%
periodSeconds: 30
- type: Pods
value: 4 # 或每次最多扩4个Pod
periodSeconds: 30
selectPolicy: Max # 取两者中较大的
scaleDown:
stabilizationWindowSeconds: 300 # 缩容冷却5分钟
policies:
- type: Percent
value: 10 # 每次最多缩容10%
periodSeconds: 60
behavior字段是HPA v2的关键特性。不配置behavior时使用默认策略,可能导致扩缩容过于激进。scaleDown的stabilizationWindowSeconds设为300秒意味着:每次缩容前,HPA会取过去5分钟内计算出的最大期望副本数作为本次缩容目标,避免指标瞬时波动导致的反复伸缩。
Prometheus Adapter集成:自定义指标驱动伸缩
CPU指标无法覆盖所有场景。当需要基于QPS、消息队列深度、自定义业务指标伸缩时,需要部署Prometheus Adapter将Prometheus指标暴露为Kubernetes自定义指标API。
安装Prometheus Adapter的Helm配置:
# values.yaml
prometheus:
url: http://prometheus-server.monitoring.svc.cluster.local
port: 80
rules:
custom:
- seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "^(.*)_total"
as: "http_requests_per_second"
metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
# seriesQuery: 从Prometheus查询的原始指标序列
# resources: 将Prometheus label映射为K8s资源
# metricsQuery: 实际执行的PromQL,计算每秒请求数
部署Adapter后,基于QPS的HPA配置:
# hpa-custom.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa-custom
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 30
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100" # 每个Pod目标100 QPS
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
多指标模式下,HPA对每个指标独立计算期望副本数,取最大值作为最终结果。上述配置中,若CPU达到70%但QPS未达100/s,HPA仍会基于CPU指标扩容。averageValue的单位是flat value(绝对值),与Utilization(百分比)不同。
验证自定义指标可用性
HPA创建后经常遇到自定义指标无法获取的问题。排查链路如下:
# 1. 检查自定义指标API是否注册
kubectl get apiservice v1beta1.custom.metrics.k8s.io
# 2. 检查Adapter Pod日志
kubectl logs -n monitoring prometheus-adapter-xxxxx
# 3. 直接查询自定义指标API
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/production/pods/*/http_requests_per_second"
# 输出示例:
# {
# "kind": "MetricValueList",
# "items": [{
# "describedObject": {
# "namespace": "production",
# "name": "api-server-abc123",
# "kind": "Pod"
# },
# "metricName": "http_requests_per_second",
# "timestamp": "2026-07-30T10:00:00Z",
# "value": "85"
# }]
# }
# 4. 检查HPA状态和指标值
kubectl describe hpa api-server-hpa-custom -n production
describe输出中的”Metrics”部分会显示当前指标值和目标值。若显示<unknown>,说明Adapter未正确返回该指标。常见原因是Prometheus中该指标的label不匹配rules.custom.resources.overrides中的映射规则。
常见问题诊断与排查
问题1:HPA显示 desired replicas 为 minReplicas,指标正常但不扩容
排查方向:检查指标值是否超过target。HPA有一个容忍度(tolerance)参数,默认0.1,指标值在目标值的±10%范围内不会触发伸缩。若CPU target为60%,实际为63%,不会扩容。查看describe输出中的”Conditions”字段确认AbleToScale和ScalingActive状态。
问题2:扩容正常但缩容太慢
排查方向:scaleDown.stabilizationWindowSeconds默认300秒。业务有明显潮汐特征时,可调整behavior.scaleDown.policies的periodSeconds和value控制缩容速率。注意不要让缩容太快——流量恢复时需要重新拉起Pod,冷启动延迟可能导致请求超时。
问题3:自定义指标Pods类型报错”no metrics for pods”
排查方向:Pods类型的指标要求每个Pod都能返回指标值。若部分Pod刚启动或未产生指标数据,HPA会报错。确保Prometheus的scrape配置正确采集了所有Pod的指标,且metricsQuery的聚合逻辑不会因为缺少数据点而返回空结果。在metricsQuery中使用sum by而非avg by可避免NaN问题。
问题4:HPA与VPA同时运行冲突
排查方向:HPA基于CPU utilization(使用量/request百分比)伸缩,VPA动态调整request值。两者同时运行会导致HPA不断重算基准值,形成正反馈循环。生产环境应避免HPA和VPA同时作用于同一资源,或使用VPA的off模式仅做推荐不自动调整。
生产环境伸缩策略建议
minReplicas的设置应基于服务SLA。面向用户的服务minReplicas不应低于3——保证滚动更新和单Pod故障时仍有2个可用实例。maxReplicas的上限取决于集群剩余资源和预算控制,建议结合Cluster Autoscaler联动,在节点不足时自动扩容节点池。
多指标配置的最佳实践是:CPU指标作为兜底保障,自定义业务指标(QPS/队列深度)作为主驱动。behavior的scaleUp策略中配置多种policy取Max值,确保流量激增时快速扩容;scaleDown配置较长冷却窗口和保守缩容比例,避免流量恢复期间的短暂下降导致过早缩容。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kuberneteshpa-zi-dong-shen-suo-pei-zhi-shi-zhan-zi-ding-yi/