2026 年 9 月 2 日,Kubernetes 官方博客宣布,v1.37 起水平自动伸缩器(HPA)支持把工作负载缩容到零副本,该特性进入 Beta 阶段并默认开启。这意味着:你的后台任务在空闲时可以把运行实例全部停掉、成本降为零,活来了再自动拉起来。
先把项目说清楚。Kubernetes(简称 K8s)是一个容器编排平台,你可以把它当成一群应用的「总调度室」:决定每个应用跑几个实例、跑在哪台机器、挂了怎么重启。HPA(水平 Pod 自动伸缩器)是它内置的自动扩缩容控制器:盯住一个指标,指标高了就多开几个应用实例(术语叫「副本」),指标低了就关掉多余的。
过去 HPA 有个硬下限:至少保留 1 个副本。想缩到零,得装第三方组件或手动打开 Alpha 特性开关。从 v1.37 起,这成了 Kubernetes 核心自带的默认能力。
这个功能解决什么问题? 队列消费者、批处理作业这类后台负载经常长时间没活干,却一直占着机器。缩容到零 = 空闲时零占用、零成本;等新任务进来,再自动把实例拉起来。省钱最明显的场景是**每个实例都占着昂贵资源(专用 CPU、GPU)**的负载。
适合谁用? 跑消息队列消费者、批处理任务的团队,尤其是实例持有 GPU 或专用 CPU 的场景;不太适合直接用于对外提供 HTTP 接口的在线服务(原因见下文)。
为什么缩到零需要一个「特殊指标」
HPA 最常用的是 CPU、内存指标,但这两者来自正在运行的实例——副本数一旦归零,就没有实例可测,HPA 也就失去「该拉起来了」的信号。
对象指标(object metric)和外部指标(external metric)没有这个问题:它们描述的是独立于实例存在的事物,比如消息队列里的积压任务数——队列长度客观存在,跟有没有消费者实例在跑无关。所以缩到零必须用这两类指标;只配了 CPU/内存的 HPA 申请 minReplicas: 0 会被 API 服务器直接拒绝。
官方示例:用队列积压量把消费者缩到零
官方博客给了一个完整的 Prometheus(一个开源监控系统,负责采集和存储指标数据)方案,核心三步:
- 指标:Prometheus 里有一条
queue_consumer_lag指标,记录worker_tasks这个任务队列的积压数量。 - 适配器:Kubernetes 需要通过指标适配器才能读到外部指标,官方用的是 Prometheus Adapter,在配置里加一条
externalRules把该指标暴露出来。配置前先用kubectl get --raw ...确认 Kubernetes 能读到这个指标——指标读不到,HPA 就无法从零拉起。 - HPA 配置:目标 Deployment(Kubernetes 里定义「应用要跑几个副本」的资源对象)名为
queue-worker,minReplicas: 0、maxReplicas: 10,每积压 30 个任务分配 1 个副本。队列空了自动归零,任务来了自动回升,最多 10 个副本封顶。
注意两点:启动 Deployment 时至少要有 1 个副本——手动把副本设成 0 会被视为「暂停」,HPA 不会去唤醒它;默认「缩容稳定窗口」是 5 分钟,防止队列长度短暂回落就把所有 worker 全撤了,需要的话可用 spec.behavior.scaleDown 调整。
ScaledToZero:区分「自动缩零」与「手动暂停」
副本数为 0 时出现一个歧义:是 HPA 自己缩下来的,还是运维手动暂停的?两者处理方式完全不同。
Kubernetes 用状态条件解决:HPA 把负载从 1 个以上副本缩到 0 时,会写入 ScaledToZero=True 条件,表示「这个零状态归控制器管」,后续继续盯着对象/外部指标准备回升;负载重新拉起后条件变为 ScaledToZero=False(原因 NotScaledToZero)。没有这个条件的零副本负载 = 手动暂停,HPA 不会碰它。用 kubectl describe hpa queue-worker 可以查看这些条件。
代价:冷启动
缩到零不是免费的:HPA 需要先观察到指标变化、调度新的 Pod(Kubernetes 运行应用实例的最小单元)、再等应用启动完成——这段冷启动时间(从零到能干活)随应用启动速度而定。这个模式适合「工作可以等在队列里」的负载;HTTP 这类请求驱动的服务不适合直接缩到零,因为 Kubernetes Service(集群内的请求转发入口)在没有任何 Pod 就绪时不会缓冲请求,直接缩零会丢请求,需要另加一层缓冲。
升级与回滚注意
- v1.37 中
HPAScaleToZero特性开关在kube-apiserver(集群的 API 服务器)与kube-controller-manager(集群的控制器管理器)上都默认启用。版本倾斜升级时,要等两个组件都支持并启用该特性后再创建minReplicas: 0的 HPA——否则控制器会把零副本当成手动暂停,可能把负载留在零。 - 回滚或禁用特性前:把相关 HPA 改回
minReplicas: 1或更高,并手动把当前为零的负载拉回至少 1 个副本。
结论
Kubernetes v1.37 之后,队列类、批处理类负载可以完全靠核心能力实现「闲时零副本、来活自动拉起」,前提是指标必须来自独立于 Pod 的队列/对象指标(如积压任务数),并接受冷启动代价。这个特性从 v1.16 的 Alpha 实验(对应设计文档 KEP-2021)走到今天默认启用,是 Kubernetes 自动伸缩能力的一个里程碑。