VPA 垂直自动扩缩
本教程共 65 篇 · 第 49 篇 · 更新于 2026-08-14 · 约 15 分钟阅读
本节目标:搞懂 VPA 是怎么自动调 Pod 的 CPU/内存配额的,它和 HPA 到底什么关系,四种更新模式各自怎么用,以及为什么它需要先单独安装。
HPA 解决的是”开几条收银台”。但还有另一种烦恼:你给每个 Pod 设的 requests.cpu 是拍脑袋定的。设小了,Pod 跑着跑着被限流甚至 OOM;设大了,节点资源白白浪费,调度器还嫌贵排不进去。
这种”每个 Pod 到底该分多少资源”的难题,交给 VPA(Vertical Pod Autoscaler,垂直 Pod 自动扩缩器)。
49-1 VPA 与 HPA 的区别
一句话区分:
- HPA:改的是副本数(Pod 几个)。应对”请求总量”的变化。
- VPA:改的是单个 Pod 的资源请求(每个 Pod 多少 CPU/内存)。应对”单个实例该多大”的问题。
它们调的是不同维度,所以本质上不冲突。但在同一工作负载上同时挂 HPA 和 VPA 要小心——如果两者都基于 CPU 来算,会互相打架。官方建议:要么 HPA 用自定义/外部指标、VPA 管 CPU/内存;要么干脆只用一个。
WarningVPA 不是 Kubernetes 控制平面自带的核心组件。它是一套需要单独安装的扩展(通常装在
kube-system命名空间)。装好之后才有VerticalPodAutoscaler这个资源类型和对应的控制器。没装就直接kubectl apply它的 YAML,会报”找不到这个资源”。
49-2 VPA 的架构
VPA 由三个角色协作,理解它们有助于排错:
- Recommender(推荐器):长期观察历史用量,算出一个”合理区间”,给出推荐值。它只建议,不直接改。
- Updater(更新器):根据你设的更新模式,真的去改 Pod 的资源。多数模式下它靠”删掉旧 Pod、让控制器重建新 Pod”来生效。
- Admission(准入):一个变异型(mutating)的 Webhook。当 Pod 被创建时,它把推荐值自动写进容器的
resources里。
VPA 对象通过 targetRef 指向一个工作负载(Deployment、StatefulSet 等),然后托管这一组 Pod 的资源。
49-3 四种更新模式 updateMode
spec.updatePolicy.updateMode 决定 VPA 改资源的方式,有四个取值:
| 模式 | 行为 | 适合场景 |
|---|---|---|
Off | 只计算推荐值,绝不自动改 | 先观察、不敢动生产 |
Initial | 只在 Pod 首次创建时设一次资源 | 只想给新 Pod 一个合理起点 |
Recreate | 当推荐值变了,删掉旧 Pod 重建 | 能接受短暂中断的无状态服务 |
Auto | 等于 Initial + Recreate 的组合 | 想要全自动调节 |
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web
updatePolicy:
updateMode: "Auto" # Off / Initial / Recreate / Auto
Tip新手最稳的起步是
updateMode: Off。先挂上一周,用kubectl describe vpa看推荐值是否合理,确认无误后再切到Auto。这能避免一上来就乱改生产 Pod。
Note较新的 Kubernetes 版本还引入了”原地(InPlace)“调整能力,可以在不重启 Pod 的情况下改资源。具体可用模式取决于你集群的版本与特性开关,使用前请确认你的集群支持。对于 v1.36,保守起见仍以
Off/Initial/Recreate/Auto四种为标准。
49-4 资源策略 resourcePolicy
你不一定想让 VPA 对容器为所欲为。用 resourcePolicy.containerPolicies 划出上下限和可控资源:
spec:
resourcePolicy:
containerPolicies:
- containerName: web
mode: "Auto" # 对本容器的调节方式
minAllowed: # 下限,低于此 VPA 不会调
cpu: "100m"
memory: "128Mi"
maxAllowed: # 上限,高于此 VPA 不会调
cpu: "2000m"
memory: "4Gi"
controlledResources: # 控制哪些资源,默认 cpu+memory
- cpu
- memory
minAllowed / maxAllowed 是安全围栏:VPA 再聪明,也不会把你的 Pod 调到超出这个范围。这能防止推荐值异常时把 Pod 撑爆或饿死。
49-5 查看推荐值
在 Off 模式或排查时,推荐值是你最该看的东西:
# 看所有 VPA
kubectl get vpa
# 看某个 VPA 的推荐详情
kubectl describe vpa web-vpa
describe 输出里有一段 Recommendation,对每个容器给出四档:
- Lower Bound:下限,给再少就可能不够。
- Target:推荐目标值,最该取的。
- Uncapped Target:没封顶时的理想值。
- Upper Bound:上限,给再多也白给。
Tip把
Target的 CPU/内存跟你现在requests比一比。差很多说明你一开始拍的脑袋偏了,正好借 VPA 校准。
49-6 VPA 与 HPA 能否共存
直接说结论:
- 能共存,但别用同一指标。典型分工:VPA 管 CPU/内存的”单实例大小”,HPA 用 QPS 之类自定义指标管”实例数量”。
- 别让两者都盯 CPU。否则 VPA 一调大 requests,HPA 看 CPU 利用率降了就去缩副本,副本一缩 VPA 又觉得不够……死循环。
- 如果只想解决”资源配额不准”,先用 VPA(Initial 或 Auto)就够了,不一定非要上 HPA。
49-7 什么时候该用 VPA
VPA 不是银弹,先想清楚场景再上:
- 适合:单实例、没法水平拆分的负载(如某些单写数据库代理);资源需求波动大、但加副本没意义的计算任务;你根本不确定该给 Pod 配多少资源,想先让系统帮算。
- 不适合:无状态 Web 服务——这类优先用 HPA 加副本,重启式 VPA 反而会打断已有连接;对可用性要求极高、一点重启都不能有的负载——先用
Off观察,别急着Auto。 - 和 HPA 的分工口诀:HPA 管”开几条收银台”,VPA 管”每个收银台多大”。两者都基于 CPU 时才会打架。
49-8 常见排查
VPA 不生效或行为怪,按这个顺序查:
- 组件装了没?
kubectl get pods -n kube-system | grep vpa,看不到 Recommender/Updater/Admission 就是没装。 - 推荐值有没有生成?
kubectl describe vpa web-vpa,Recommendation若是<unknown>,多半是 Metrics 来源没接上。 - 推荐有了但 Pod 没变?检查
updateMode是不是Off(只建议不改),或目标 Pod 被别的机制占着无法重建。 - 调得太频繁?给
minAllowed/maxAllowed收口,或确认没有异常指标在猛拉推荐值。
WarningVPA 调整资源多数要靠”删掉旧 Pod、让控制器重建”来落地。如果目标工作负载的 Pod 设了不可驱逐、或卡在
CrashLoopBackOff,VPA 的推荐就一直落不了地,也不会报错——只是默默没生效。排查时别只盯 VPA,也要看 Pod 自身状态。
小结
VPA 帮你把”每个 Pod 该分多少资源”这件麻烦事自动化:
- VPA 调的是单 Pod 资源,HPA 调的是副本数,维度不同。
- VPA 要单独安装,不是集群自带的。
- 先用
Off观察推荐值,再决定要不要Auto。 - 用
minAllowed/maxAllowed设安全围栏。 - 和 HPA 同用时,别让它们都基于 CPU 算。
- 多数模式靠重建 Pod 落地,确认 Pod 能被正常调度和重启。
两章弹性伸缩讲完,下一章我们看”怎么把新版本安全地推上线”——滚动、蓝绿、金丝雀三种发布策略。