首页 / Kubernetes (k8s) 入门教程 / VPA 垂直自动扩缩

Kubernetes (k8s) 入门教程

VPA 垂直自动扩缩

本教程共 65 篇 · 第 49 篇 · 更新于 2026-08-14 · 约 15 分钟阅读

KubernetesVPA垂直扩缩自动扩缩资源配额弹性

本节目标:搞懂 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/内存;要么干脆只用一个。

Warning

VPA 不是 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 不生效或行为怪,按这个顺序查:

  1. 组件装了没?kubectl get pods -n kube-system | grep vpa,看不到 Recommender/Updater/Admission 就是没装。
  2. 推荐值有没有生成?kubectl describe vpa web-vpaRecommendation 若是 <unknown>,多半是 Metrics 来源没接上。
  3. 推荐有了但 Pod 没变?检查 updateMode 是不是 Off(只建议不改),或目标 Pod 被别的机制占着无法重建。
  4. 调得太频繁?给 minAllowed/maxAllowed 收口,或确认没有异常指标在猛拉推荐值。
Warning

VPA 调整资源多数要靠”删掉旧 Pod、让控制器重建”来落地。如果目标工作负载的 Pod 设了不可驱逐、或卡在 CrashLoopBackOff,VPA 的推荐就一直落不了地,也不会报错——只是默默没生效。排查时别只盯 VPA,也要看 Pod 自身状态。

小结

VPA 帮你把”每个 Pod 该分多少资源”这件麻烦事自动化:

  1. VPA 调的是单 Pod 资源,HPA 调的是副本数,维度不同。
  2. VPA 要单独安装,不是集群自带的。
  3. 先用 Off 观察推荐值,再决定要不要 Auto
  4. minAllowed/maxAllowed 设安全围栏。
  5. 和 HPA 同用时,别让它们都基于 CPU 算。
  6. 多数模式靠重建 Pod 落地,确认 Pod 能被正常调度和重启。

两章弹性伸缩讲完,下一章我们看”怎么把新版本安全地推上线”——滚动、蓝绿、金丝雀三种发布策略。