水平Pod自动扩缩容(HPA)原理:控制循环、指标采集、目标值设定
核心原理:HPA 是一个闭环控制系统
水平Pod自动扩缩容(Horizontal Pod Autoscaler,HPA)本质上是一个负反馈控制循环。它持续观测工作负载(Deployment、StatefulSet 等)的实时指标,将观测值与用户设定的目标值进行比较,然后根据偏差调整 Pod 的副本数。这个循环由 kube-controller-manager 中的 horizontal-pod-autoscaler 控制器负责执行,默认每 15 秒(由 --horizontal-pod-autoscaler-sync-period 控制)运行一次。
控制循环的核心逻辑可以概括为:期望副本数 = ceil(当前副本数 × (当前指标值 / 目标指标值))。当当前指标值高于目标值时,比值大于 1,副本数增加;反之则减少。这个公式简单但强大,它保证了系统始终朝着“指标收敛到目标值”的方向调整。
指标采集:Metrics API 与 metrics-server
HPA 控制器本身不直接采集指标,而是通过 Metrics API 获取数据。Kubernetes 定义了 metrics.k8s.io 这个 API 组,由 metrics-server 组件实现。metrics-server 以 DaemonSet 方式运行在每个节点上,通过 kubelet 的 Summary API 每 15~30 秒采集一次每个 Pod 的 CPU 和内存使用数据,并聚合后暴露给 API Server。
对于 CPU 指标,HPA 使用的是资源请求量(requests)作为分母来计算利用率百分比。例如,某个 Pod 的 CPU request 为 500m(0.5 核),当前实际使用量为 400m,则利用率为 80%。对于内存指标,计算方式类似,但内存通常不用于自动扩容(因为内存不会自动释放,扩容后旧 Pod 不缩容可能导致内存持续增长)。
除了内置的 CPU/内存指标,HPA 还支持通过 自定义 Metrics API(custom.metrics.k8s.io)和 外部 Metrics API(external.metrics.k8s.io)采集业务指标,例如 QPS、队列深度、AI 推理延迟等。这需要部署 Prometheus Adapter 或 Kubernetes 官方提供的 Custom Metrics Adapter 来实现。
目标值设定与扩缩容策略
在 HPA 的 YAML 定义中,spec.targetCPUUtilizationPercentage 或 metrics[].resource.target.averageUtilization 用于设定目标值。目标值的选择直接影响系统的响应速度和稳定性:
- 目标值过低(如 30%):系统会过早扩容,导致资源浪费,但响应延迟低。
- 目标值过高(如 90%):资源利用率高,但突发流量可能导致 Pod 过载,响应时间恶化。
- 推荐做法:对于延迟敏感型 AI 服务,建议将 CPU 目标值设在 50%~70%,同时结合自定义指标(如推理队列长度)进行综合判断。
HPA 还提供了一些重要的行为控制参数,在 behavior 字段中定义:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
上述配置表示:扩容时不做稳定窗口限制,允许每 15 秒最多增加 100% 的副本数;缩容时设置 300 秒的稳定窗口,且每 60 秒最多减少 1 个 Pod,避免抖动。
案例:AI 推理服务的 HPA 配置
假设我们有一个基于 PyTorch 的 AI 图像分类服务,部署在 Kubernetes 上,每个 Pod 的 CPU request 为 1 核。我们希望当 CPU 利用率超过 70% 时自动扩容,同时结合自定义指标——推理请求队列深度(由 Prometheus 暴露)来更精准地扩缩容。配置如下:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ai-inference-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ai-inference
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: inference_queue_depth
target:
type: AverageValue
averageValue: 5
behavior:
scaleDown:
stabilizationWindowSeconds: 180
在这个配置中,HPA 会同时评估 CPU 利用率和队列深度两个指标,并取两者中建议副本数较大者作为最终结果。例如,CPU 利用率 60%(低于目标 70%)建议缩容到 2 个副本,但队列深度为 8(高于目标 5)建议扩容到 6 个副本,最终 HPA 会选择 6 个副本,确保推理请求不会积压。
误区与复盘:HPA 使用中的常见问题
| 误区 | 现象 | 正确做法 |
|---|---|---|
| 只依赖 CPU 指标 | AI 服务 GPU 密集但 CPU 空闲,HPA 不触发扩容 | 结合自定义指标(如 GPU 利用率、队列深度) |
| 目标值设得过低 | 副本数频繁波动,资源浪费 | 根据压测结果设定合理目标值,留出缓冲 |
| 忽略稳定窗口 | 缩容过快导致服务抖动 | 设置 scaleDown.stabilizationWindowSeconds |
| Pod 未设置 requests | HPA 无法计算利用率,指标缺失 | 为所有容器设置合理的 requests 和 limits |
| metrics-server 未部署 | HPA 状态显示 <unknown> 指标 | 确认 metrics-server 正常运行且 API 可用 |
kubectl get hpa ai-inference-hpa -o yaml 查看 HPA 的状态和事件,重点关注 status.conditions 中的 AbleToScale、ScalingActive 和 ScalingLimited 三个条件,它们能快速定位问题所在。
HPA 控制循环的稳定性依赖于三个关键因素:准确的指标采集、合理的目标值以及恰当的扩缩容策略。在实际生产环境中,建议先通过压测工具模拟业务负载,观察 HPA 在不同目标值和策略下的表现,再逐步调整参数,最终找到适合自身业务模型的配置组合。同时,定期检查 HPA 的事件和指标趋势,及时发现并修正配置偏差,才能让自动扩缩容真正服务于 AI 服务的稳定性和成本效率。