2. Kubernetes 原生 HPA 原理:HPA 工作流程、metrics-server、资源指标与自定义指标
在深入 KEDA 之前,必须透彻理解 Kubernetes 原生的水平 Pod 自动伸缩器(HPA)。HPA 是控制面弹性伸缩的基石,KEDA 本质上是对 HPA 的扩展与增强。本章将拆解 HPA 的核心工作流程、关键组件 metrics-server,以及资源指标与自定义指标的区别。
2.1 HPA 核心工作流程
HPA 作为一个控制循环组件,定期(默认每 15 秒)通过 API Server 查询目标指标,计算期望副本数,并更新工作负载的副本数。其完整流程分为四个阶段:
- 指标采集:HPA Controller 通过 API Server 获取 metrics-server 或自定义指标 API 提供的指标数据。
- 指标聚合与归一化:将采集到的原始指标(如 CPU 使用率、QPS)转换为目标利用率百分比或值。
- 副本数计算:使用公式
期望副本数 = ceil(当前副本数 × (当前指标值 / 期望指标值))进行计算。 - 滚动更新与状态写入:HPA Controller 更新工作负载(Deployment/StatefulSet)的
spec.replicas,并记录伸缩事件到 HPA 资源的status字段。
关键公式说明: 当指标为资源类型(如 CPU)时,
当前指标值 是所有 Pod 的均值;当指标为 Pod 类型(如 QPS)时,当前指标值 是所有 Pod 的当前值之和。HPA 会忽略处于 Pending 或 Unknown 状态的 Pod。
2.2 metrics-server:资源指标的基石
metrics-server 是 Kubernetes 集群中资源指标(CPU、内存)的聚合器。它通过 kubelet 的 Summary API 从每个节点采集 Pod 和节点的资源使用数据,并暴露给 HPA 和 kubectl top 命令。
| 特性 | 说明 |
|---|---|
| 数据来源 | 每个节点上的 kubelet cAdvisor 接口 |
| 采集粒度 | 默认每 60 秒从 kubelet 拉取一次数据 |
| 存储方式 | 仅保存在内存中,不持久化,无历史数据 |
| 暴露 API | metrics.k8s.io 聚合 API |
| 资源消耗 | 极低,通常只需 0.1 CPU 和 50MB 内存 |
生产建议: metrics-server 是 HPA 资源指标伸缩的必备组件。如果集群中未部署,HPA 将无法获取 CPU/内存指标,导致自动伸缩失效。建议使用官方最新版本,并配置资源请求与限制。
2.3 资源指标与自定义指标
HPA 支持三种指标类型,理解它们的差异是配置正确伸缩策略的前提。
| 指标类型 | 数据来源 | 典型示例 | 适用场景 |
|---|---|---|---|
| 资源指标 | metrics-server | CPU 使用率、内存使用量 | 通用型工作负载,无状态应用 |
| Pod 自定义指标 | Prometheus Adapter / 自定义 API | QPS、请求延迟 P99、队列深度 | 有状态应用、消息处理、API 网关 |
| 对象自定义指标 | Prometheus Adapter / 自定义 API | Ingress 流量、消息队列积压数 | 基于外部系统状态的伸缩 |
2.4 自定义指标接入架构
自定义指标需要额外的适配器组件(如 Prometheus Adapter、Kubernetes 自定义指标 API 实现)将外部监控系统的指标转换为 HPA 可消费的格式。下图展示了资源指标与自定义指标在 HPA 中的协同路径。
2.5 HPA 配置示例
以下是一个同时使用资源指标和 Pod 自定义指标的 HPA 配置示例:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 1000
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
注意: 当同时配置多个指标时,HPA 会分别计算每个指标对应的期望副本数,并取其中的 最大值 作为最终伸缩目标。这可能导致扩容比预期更激进,建议配合
behavior 字段设置合理的伸缩策略。
2.6 HPA 的局限性
虽然 HPA 是 Kubernetes 原生的弹性伸缩方案,但在实际生产中存在以下不足,这也正是 KEDA 要解决的核心问题:
- 指标源有限:原生 HPA 无法直接对接消息队列(Kafka、RabbitMQ)、数据库连接池、自定义事件源等。
- 无事件驱动能力:HPA 基于轮询,无法实现“零工作负载时缩零”的事件驱动模式。
- 冷却策略僵化:默认的扩容/缩容冷却时间无法满足快速波动的业务场景。
- 无外部状态感知:无法根据外部系统的健康状态或业务指标进行精细化伸缩。