简短回答:当你的工作负载可以运行多个相同副本且需求会波动时,使用 HPA——按 CPU/内存、应用指标(RPS/延迟)或外部队列/积压指标进行扩缩容。 不要将 HPA 用于单副本有状态服务,或者当真正的瓶颈是节点容量或下游限制时(DB 连接、第三方速率限制)。
Tl;DR:
- 对于可进行水平拆分的工作负载,当每个 Pod 的指标或外部指标能够反映负载时,请使用 HPA。
- 使用资源/自定义/外部指标(CPU、RPS、队列深度);并结合 Cluster Autoscaler 实现节点容量扩缩。
- 使用 KEDA 实现事件驱动的缩容到零或外部扩缩;使用处于建议模式的 VPA 来确定资源请求值。
快速决策清单 (是/否) :
- 工作负荷在多个副本之间是无状态的还是可分区的? (是→ HPA 候选人)
- 是否可以将负载作为每个 Pod 的指标或外部指标来监测(CPU、每秒请求数、队列深度)? (是→HPA适用)
- 群集可以计划更多 Pod(群集自动缩放程序或备用容量)吗? (是→继续;如果否,则启用节点自动缩放)
- 下游服务(数据库池、第三方 API)是否限制并发? (是→添加限流/连接池,或优先采用纵向扩展)
决策矩阵(工作负荷→最佳指标→推荐缩放器):
| 工作负荷类型 | 最佳目标指标 | 推荐的缩放器 |
|---|---|---|
| Web/API (无状态) | 每个 Pod 的 CPU 或 RPS | HPA (+VPA 建议 + 群集自动缩放程序) |
| 后台队列工作器 | 队列长度或消息数/秒 | HPA 通过外部指标或 KEDA (KEDA 支持从小到零) |
| 单实例数据库或有状态应用 | N/A (不可水平分区) | VPA 或手动缩放 |
| Batch/临时事件辅助角色 | 事件积压 | 具有外部指标的 KEDA 或 HPA |
HPA 的工作原理(简单的控制循环和重要字段)
- 组件:HPA 控制器(控制平面)+ 指标提供程序(通过适配器或 KEDA 提供资源指标、自定义/外部指标 API 的指标服务器)。
- 控制循环(高级别):HPA 控制器轮询指标 API → 根据每个已配置的指标计算 desiredReplicas → 取计算得到的最大 desiredReplicas → 应用 min/max 和行为规则(策略/稳定化)→ 更新目标资源上的 spec.replicas → 重复。 有关详细信息,请参阅 Kubernetes HPA 文档 。
- 公式(计算所需副本的方式):desiredReplicas = ceil(current_total/ target_per_pod)。 控制器为每个配置的指标计算 desiredReplicas,然后在应用 min/max 和行为之前使用最大值(此指标优先行为记录在 HPA 文档中)。
- 重要的自动缩放/v2 字段:minReplicas、maxReplicas、指标(Resource、Pods、Object、External)、行为(scaleUp/scaleDown 策略和稳定WindowSeconds)。
- 使用 behavior 配置来限制变更速率并避免抖动;stabilizationWindowSeconds 是 scaleDown 平滑处理的关键调节参数。
示例行为片段 (自动缩放/v2)
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
何时使用 HPA (按指标类型/常见用例)
- CPU/内存(资源指标)
- 当每个 Pod 的 CPU 或内存利用率与容量需求相关,且 Pod 设置了正确的资源请求时,请使用 HPA。 Web API 和无状态微服务的典型情况。
- 实际起点:在 60-80% 范围内以平均 CPU 利用率为目标,并通过负载测试进行优化。 HPA 从 Pod 请求计算利用率,因此必须设置请求。
- 自定义群集内指标 (Prometheus / 自定义指标)
- 当应用级信号(请求数/秒、延迟、队列使用者/pod)比 CPU 更好地表示负载时,请使用 HPA。
- 使用 Prometheus + prometheus-adapter(custom.metrics.k8s.cn)或其他自定义指标提供程序暴露指标,并在 HPA 中将这些指标设为目标指标。
- 外部指标(队列、云端积压)
- 当扩缩容需要根据队列长度(RabbitMQ、Azure 服务总线)、Event Hubs 或云监控指标等外部信号做出响应时,请使用 HPA(通过外部指标 API)或 KEDA。
- 如果需要缩放到零或严格的事件驱动行为,首选 KEDA — 它原生集成外部缩放程序并支持从零缩放(KEDA 文档)。
何时不应使用 HPA
- 单副本有状态服务(数据库、Pod 内唯一状态):除非能够安全地进行分片/分区,否则不适合使用 HPA。
- 当瓶颈出现在节点级别(GPU、磁盘 I/O、节点 CPU)而不是 Pod 级别时:应优先选择节点池自动扩缩容或垂直扩缩容。
- 当下游系统(DB 连接池、缓存、第三方 API)具有严格的并发限制时:缩放 Pod 且不会增加下游容量可能会恶化故障,请参阅下面的“下游和操作注意事项”。
- 如果需要缩容到零,仅靠 HPA 无法做到这一点;请使用 KEDA 或外部控制器。
多个指标、优先级和示例
- 如果配置多个指标,HPA 控制器会独立计算每个指标的 desiredReplicas 值,然后选择最大的 desiredReplicas 作为缩放的基础。 之后,将应用 minReplicas/maxReplicas 和行为策略(源: Kubernetes HPA 文档)。
- 示例:CPU 目标计算 5 个副本,请求/秒的目标计算 12 个副本→ HPA 将选取 12 个副本(然后最小/最大值和行为策略可以修改最终应用的更改)。
- 为避免突然超调,请结合使用基于百分比的扩容策略,以及合理的 scaleDown stabilizationWindowSeconds 设置(请参阅上面的 behavior 配置片段)。
HPA 与 VPA 与群集自动缩放程序与 KEDA (简短指南)
- HPA:根据指标对副本进行水平扩缩容。 最适合可分区的工作负载。
- VPA:调整 Pod 的资源请求/限制(垂直)。 最适合非并行工作负荷或设置合理的默认值。
- 集群自动扩缩器(或 Karpenter):扩缩节点规模以满足调度请求(节点级容量)。 当 Pod 由于没有可用节点而处于 Pending 状态时使用。
- KEDA:事件驱动的自动缩放程序,它集成了外部触发器,并支持事件工作负荷的缩放到零。
常见模式:使用处于推荐模式的 VPA 来设置基线请求,使用 HPA 扩缩副本,并使用集群自动扩缩器(或 Karpenter)提供节点容量。 当您需要缩减到零,或直接与外部事件源集成时,请使用 KEDA。
注意:托管 Kubernetes 服务(AKS/GKE/EKS)可能会预装指标提供程序,或提供集成的自动扩缩容功能。 AKS 群集自动缩放器文档
下游和操作注意事项(常见问题)
- 数据库连接池:增加副本数会增加并发连接数。 可通过连接池(例如 PgBouncer)、限制每个 Pod 的并发数,或在扩缩 Pod 之前增大数据库连接池大小来缓解。
- API 速率限制与第三方配额:确保下游系统能够处理 Pod 扩容后产生的请求量;考虑采用客户端限流。
- PodDisruptionBudgets (PDB):PDB 不会阻止 HPA 纵向扩展,但可能会影响维护操作和排水行为:确保缩放策略与 PDB 保持一致。
- 启动和预热的影响:initContainers、缓存预热或较长的冷启动时间都可能使指标失真并引发波动——应使用就绪探针/启动探针和稳定窗口。
- 推荐的运行方法:设置保守的扩缩容速率,调整资源请求/限制和探针配置,在非生产环境中进行测试,并在下游系统成为瓶颈时增加基于 SLO 的限流。
配置清单与安全上线步骤
确保指标和基于角色的访问控制(RBAC):
- 部署 metrics-server 以获取资源指标(或使用托管服务提供商)。
- 如果需要,可为自定义指标(custom.metrics.k8s.io)部署 Prometheus 和 prometheus-adapter。
- 对于外部或事件扩缩器,可以考虑使用 KEDA。
使用以下内容编写 HPA(autoscaling/v2):
- minReplicas 和 maxReplicas,
- 显式指标和行为(scaleUp/scaleDown 策略),
- Pod 上的就绪情况和启动探测,
- 合理的资源请求,使资源指标有意义。
安全测试清单(如何安全地测试 HPA):
- 在启用了类似节点大小和自动缩放的非生产命名空间/群集中进行测试。
- 先采用保守的最小/最大副本数配置和较温和的扩容策略(例如,每分钟最多增长 100%)。
- 进行渐进式负载测试,监控 desiredReplicas、currentReplicas 以及处于 Pending 状态的 Pod。
- 在提高激进程度之前,先反复调整资源请求/限制、就绪探针和行为策略。
AKS 和节点自动缩放说明:
- AKS 和其他云服务可能会预装 metrics-server,或者提供托管式自动扩缩器集成。 启用群集自动缩放程序的示例 AKS CLI:
az aks nodepool update --resource-group myRG --cluster-name myAKS --name node-pool1 --enable-cluster-autoscaler --min-count 1 --max-count 5
卡彭特注意:Karpenter 是一种侧重于快速预配的替代节点自动缩放方法;如果需要快速节点预配,请考虑它。
可用的 YAML 示例
基于 CPU 的 HPA (自动缩放/v2):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapi-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapi
minReplicas: 3
maxReplicas: 12
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
HPA 使用 Prometheus 公开的自定义指标(通过 prometheus-adapter):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-requests-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
有关映射查询,请参阅prometheus-adapter 文档
KEDA ScaledObject (Azure 服务总线) - 支持从小到零:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sb-queue-scaledobject
namespace: workers
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: event-worker
minReplicaCount: 0
maxReplicaCount: 20
pollingInterval: 30
cooldownPeriod: 300
triggers:
- type: azure-servicebus
metadata:
queueName: orders-queue
queueLength: "50"
authenticationRef:
name: keda-azure-credentials
可观测性、警报和 SRE 示例
建议的告警(可直接复制的 Prometheus 示例——请根据你的导出配置调整指标名称):
当 HPA 的期望值 > 当前值并持续 > 5 分钟时发出告警(调度容量问题)
alert: HPAUnschedulable expr: (kube_hpa_status_desired_replicas - kube_hpa_status_current_replicas) > 0 for: 5m labels: severity: page annotations: summary: "HPA desired replicas exceed current replicas for >5m (possible scheduling issue)"对命名空间中处于挂起状态的 Pod 发出告警
alert: PodsPendingHigh expr: sum(kube_pod_status_phase{phase="Pending", namespace="production"}) > 3 for: 2m labels: severity: ticket annotations: summary: "High number of Pending pods in production"频繁缩放的警报(点击)
alert: HPAFlapping expr: increase(kube_hpa_status_replicas_last_transition_count[10m]) > 5 for: 0m labels: severity: warning annotations: summary: "Frequent HPA scaling events detected"
仪表板显示:
- HPA:currentReplicas、desiredReplicas、lastScaleTime、HPA 所使用的指标值
- Pod 运行状况:挂起的 Pod、FailedScheduling 事件、Pod 重启次数
- 下游:数据库连接使用情况、错误率、外部 API 错误/429 速率
操作和调试命令(快速参考)
- HPA 列表:
kubectl get hpa -n - 描述 HPA(查找当前/当前指标、desiredReplicas、lastScaleTime、事件):
kubectl describe hpa -n - 用于在描述输出中检查的字段:currentReplicas、desiredReplicas、指标(当前/目标值)、lastScaleTime、事件(指标提供程序的错误或缩放失败)
- 查看资源使用情况(需要 metrics-server):
kubectl top pods -n - 检查 Pending Pod 和调度失败:
kubectl get pods -n | grep Pending、kubectl describe pod -n(在kubectl describe pod -n中查找 FailedScheduling) - 检查指标提供程序日志:
kubectl logs -n kube-system deploy/metrics-serverkubectl logs -n deploy/prometheus-adapter - 应用 HPA 清单:
kubectl apply -f hpa.yaml
快速故障排除提示:
- HPA 显示 desiredReplicas > currentReplicas,且 Pod 仍处于 Pending 状态 → 很可能是节点容量不足;启用集群自动扩缩器或增加节点池。
- HPA 显示事件中的指标错误,→检查适配器 RBAC/config 和指标提供程序日志。
- HPA 缩放速度太快/速度过慢→优化行为策略(百分比/Pod 限制)和稳定窗口。
推荐的调优默认值和启发式方法
- CPU 目标:从平均利用率约 60% 开始(常见范围为 60–80%),并根据每个工作负载进行调整。
- minReplicas:为了保证可用性,至少应设为 1;如果需要将 minReplicas 设为 0,请使用 KEDA。
- maxReplicas:根据容量规划和成本进行设置;确保 Cluster Autoscaler 的限制允许将节点增加到所需容量。
- stabilizationWindowSeconds:scaleDown ≈ 300s(5 分钟)通常可作为一个常见的起始值,以避免快速缩容;请根据工作负载进行调整。
- 缩放策略:限制每个周期的增长百分比上限(例如,允许每分钟最多增长 100%),以避免使下游系统不堪重负。
- 就绪/启动探针:务必配置,以确保 Pod 在完全就绪之前不会接收流量。
注意:特定的控制器计时默认值和确切行为可能因 Kubernetes 版本和分发而异 - 检查群集版本的 HPA 文档
启用 HPA 前的常见陷阱和检查清单
- Pod 资源请求缺失或不正确,→基于资源的 HPA 目标将产生误导。
- 没有指标提供程序(metrics-server/prometheus-adapter/KEDA)→ HPA 无法读取指标。
- 集群没有可用节点容量,且未启用集群自动扩缩器 → 这些 Pod 将一直处于 Pending 状态。
- 混合使用 HPA 和 VPA:避免让两个控制器同时主动调整资源请求——让 VPA 以建议模式运行,并由 HPA 负责扩缩副本数。
- 启动时出现尖峰(initContainers、冷缓存)且未配置探针时→调整稳定时间窗口,或手动预热实例。
- RBAC 配置错误:确保指标适配器和 HPA 控制器具有读取指标所需的权限。
快速常见问题解答
问:HPA 有什么好处? 答:使用正确的指标和节点自动缩放时,自动调整副本计数以更改负载、提高利用率和成本,并维护延迟目标。
问:HPA 如何计算期望副本数? 答:它会读取已配置的指标,针对每个指标计算 desiredReplicas = ceil(current_total / target_per_pod),取计算结果中的最大值,然后再应用 min/max 和行为策略(来源:HPA 文档)。
问:HPA 能否缩放到零? 答:否 - 普通 HPA 无法缩放为零。 使用 KEDA 实现缩容到零(KEDA 文档)。
问:如何根据队列长度或 RPS 进行缩放? 答:将队列长度/RPS 公开为外部或自定义指标(Prometheus 适配器或外部指标 API),或使用 KEDA 进行事件驱动的缩放。