Kubernetes v1.37:让 HPA 真正把工作负载缩容到零

2026-09-03 29 预计阅读时间: 1 分钟
来源: kubernetes.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Kubernetes v1.37 将 HPA 缩容到零副本推进到 Beta,并默认启用。对于队列消费者、批处理器这类并非持续接收 HTTP 请求的工作负载,空闲时可以不保留任何 Pod,有任务到来时再自动拉起。

这项能力减少了空闲资源消耗,尤其适合预留专用 CPU 或 GPU 的 Pod。但它也带来明确代价:从零恢复需要重新读取指标、调度 Pod、启动容器和初始化应用。因此,适用场景的关键不是“能不能缩到零”,而是“业务是否能承受冷启动”。

为什么 CPU 指标无法唤醒零副本工作负载

传统 HPA 经常根据 CPU 或内存使用率计算副本数。这些指标都来自正在运行的 Pod。当 Deployment 已经缩容到零时,没有 Pod,也就没有 CPU 或内存数据可以继续观察。

对象指标和外部指标不受这个限制。队列长度、任务积压量或外部系统中的待处理数量独立于消费者 Pod 存在。即使消费者全部停止,HPA 仍然可以读取队列指标,并据此决定重新创建 Pod。

典型流程如下:

  1. 队列为空,HPA 将消费者 Deployment 缩容到零。
  2. 新任务进入持久化队列,外部指标变大。
  3. HPA 读取指标并计算所需副本数。
  4. Deployment 创建 Pod,消费者开始处理任务。
  5. 队列再次变空,HPA 在稳定窗口后缩容。

用外部指标配置 HPA

下面的例子假设 Prometheus 已经采集名为 queue_consumer_lag 的指标,并且指标包含 namespacename 标签:

queue_consumer_lag{namespace="default",name="worker_tasks"} 75

Kubernetes 需要一个指标适配器,将 Prometheus 数据暴露为 External Metrics API。可以这样实践 Prometheus Adapter 的规则配置:

externalRules:
  - seriesQuery: '{__name__="queue_consumer_lag",name!=""}'
    metricsQuery: 'sum(<<.Series>>{<<.LabelMatchers>>}) by (name)'
    resources:
      overrides:
        namespace:
          resource: namespace

适配器的安装方式和完整发现规则取决于现有监控系统。创建 HPA 前,先确认 Kubernetes 能读到指标:

kubectl get --raw \
  '/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_consumer_lag?labelSelector=name%3Dworker_tasks'

如果 API 返回当前指标值,说明指标链路基本可用。若返回错误或空结果,应先修复 Prometheus、适配器或标签匹配问题。指标不可用时,HPA 无法从零副本状态恢复容量。

下面是一个可改造的完整 HPA 示例。它管理名为 queue-worker 的 Deployment,最多运行 10 个副本,每 30 个排队任务对应 1 个副本:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: queue-worker
  annotations:
    kubernetes.io/description: Scales queue-worker from the external queue metric
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: queue-worker
  minReplicas: 0
  maxReplicas: 10
  metrics:
    - type: External
      external:
        metric:
          name: queue_consumer_lag
          selector:
            matchLabels:
              name: worker_tasks
        target:
          type: Value
          value: "30"

应用前,先让 Deployment 至少运行一个副本:

kubectl scale deployment queue-worker --replicas=1
kubectl apply -f queue-worker-hpa.yaml
kubectl describe hpa queue-worker

当队列为空时,HPA 可以将 Deployment 降到零。当 queue_consumer_lag 上升时,HPA 会重新计算副本数,并受 maxReplicas: 10 限制。

零副本与手动暂停不是一回事

副本数为零可能有两种含义:HPA 自动缩容,或者运维人员手动暂停。Kubernetes v1.37 使用 ScaledToZero 状态条件区分这两种情况。

当 HPA 自己把工作负载从一个或多个副本缩容到零时,会记录:

ScaledToZero=True

之后控制器仍会继续评估对象指标或外部指标,并允许工作负载被唤醒。恢复到非零副本后,该条件会变为 ScaledToZero=False,原因通常是 NotScaledToZero

如果某个 Deployment 被手动设置为零,且没有 ScaledToZero=True 条件,HPA 会把它视为人为暂停,不会擅自唤醒它。这保留了手动缩容用于暂停业务的既有语义。

可以通过以下命令检查状态:

kubectl describe hpa queue-worker

如果指标适配器无法返回配置的指标,通常可以看到 ScalingActive=False,以及类似 FailedGetExternalMetric 的原因。此时应恢复指标链路,或者手动将工作负载扩容到至少一个副本以恢复处理能力。

HPA 的默认缩容稳定窗口仍然适用,默认值为 5 分钟。它可以避免队列短暂下降就立即删除全部消费者。需要更快或更慢缩容时,可以显式配置 spec.behavior.scaleDown,但要结合任务持续时间、冷启动开销和消息处理能力验证。

适用边界与升级注意事项

缩容到零最适合任务可以等待的场景,例如:

  • 持久化消息队列的消费者
  • 可以延迟执行的批处理任务
  • 具有明确积压指标的异步处理器
  • 单个 Pod 资源成本较高的 CPU 或 GPU 工作负载

它不适合直接作为普通 HTTP 服务的请求缓冲方案。Kubernetes Service 在没有 Ready Pod 时不会替客户端缓存请求。HTTP 请求驱动的工作负载需要额外的队列、网关缓冲或其他能够承受冷启动的架构,否则请求可能在 Pod 启动前失败。

v1.37 中,HPAScaleToZero 特性门控在 kube-apiserver 和 kube-controller-manager 中默认启用。控制平面滚动升级期间,应等待两个组件都支持并启用该能力后,再创建 minReplicas: 0 的 HPA。若 controller manager 仍处于旧版本或禁用了特性门控,可能把零副本视为手动暂停,导致工作负载无法自动恢复。

在禁用特性门控或回滚到不支持该实现的版本前,应完成以下操作:

  1. 将相关 HPA 的 minReplicas 改为至少 1。
  2. 将当前处于零副本状态的工作负载扩容到至少 1 个副本。
  3. 确认 HPA 至少配置了一个对象指标或外部指标。

API Server 会拒绝只使用 CPU、内存等资源指标、却将 minReplicas 设置为零的 HPA,因为这类指标无法在零 Pod 时提供唤醒信号。

落地检查清单

采用这项 Beta 能力前,可以逐项确认:

  • 队列或任务状态是否持久化,能否承受冷启动期间的等待?
  • 外部指标是否在零 Pod 时仍然存在并持续更新?
  • External Metrics API 是否能返回正确的标签和值?
  • maxReplicas 是否覆盖突发积压?
  • 应用启动时间、镜像拉取时间和初始化时间是否已纳入延迟预算?
  • 是否准备了指标不可用时的告警和人工恢复步骤?
  • 控制平面升级、回滚流程是否处理了 minReplicas: 0

Kubernetes v1.37 的重点不只是允许把 minReplicas 写成零,而是让 HPA 能区分“自动缩容到零”和“人为暂停”,并继续依赖对象指标或外部指标完成唤醒。对异步工作负载来说,这使缩容到零从外部插件能力变成了 Kubernetes 核心能力;对请求驱动服务来说,冷启动和请求缓冲仍然需要单独设计。


相关推荐