在云原生世界中,资源优化是永恒的主题。我们不仅希望应用能水平伸缩以应对流量变化(HPA 的领域),还希望每个 Pod 本身都能被“恰到好处”地配置——既不会因资源请求过高而浪费集群容量,也不会因请求过低而面临 OOM(内存溢出)或 CPU 饥饿的风险。
Kubernetes 的 Vertical Pod Autoscaler (VPA) 正是为解决这一“权利定”(Rightsizing)问题而生。它通过自动调整 Pod 的 CPU 和内存 requests 与 limits,实现了对单个 Pod 资源分配的精细化管理。
一、VPA vs. HPA:互补的弹性维度
理解 VPA 的第一步是将其与广为人知的 HPA 进行对比:
| 特性 |
HPA (Horizontal Pod Autoscaler) |
VPA (Vertical Pod Autoscaler) |
| 扩缩维度 |
水平: 增加/减少 Pod 副本数 |
垂直: 调整单个 Pod 的 资源请求 (CPU/内存) |
| 适用场景 |
无状态、可水平扩展的应用 (如 Web 服务器) |
有状态应用、无法轻易拆分的应用、或需要优化单体资源消耗的场景 |
| 核心目标 |
应对负载变化,保证服务可用性 |
优化资源利用率,降低成本,防止 OOM |
| 是否需要重启 |
否 (仅调整副本数) |
通常需要 (除非使用就地更新) |
协同工作: 在生产环境中,HPA 和 VPA 可以且应该协同工作。HPA 负责根据流量动态调整实例数量,而 VPA 则确保每个实例的资源配置都是最优的。
二、VPA 核心架构:三大组件协同工作
VPA 并非 Kubernetes 核心组件,而是一个需要单独安装的附加控制器。其架构由三个关键部分组成,共同构成了一个智能的反馈闭环。

1. Recommender (推荐器)
- 职责: VPA 的“大脑”。它定期(默认每分钟)从 Metrics Server 获取目标 Pod 的 CPU 和内存使用数据。
- 分析内容:
- 历史资源消耗模式和趋势。
- 使用峰值和方差,以确保有足够的“余量”(headroom)。
- OOM 事件:这是 VPA 的关键输入,能帮助它学习并避免未来的内存溢出。
- 输出: 为每个目标容器计算出三组推荐值,并存储在 VPA 对象的
.status.recommendation 字段中:
- Target: 典型使用场景下的最优资源值。
- Lower Bound: 最小可行资源值。
- Upper Bound: 最大合理资源值。
2. Updater (更新器)
- 职责: VPA 的“执行者”。它监控 VPA 对象的状态,并负责将 Recommender 的推荐值应用到实际运行的 Pod 上。
- 执行方式:
- 传统方式 (Eviction): 终止(驱逐)不符合推荐值的 Pod。工作负载控制器(如 Deployment)会自动创建一个新的 Pod,此时 Admission Controller 会为其注入新的资源请求。
- 现代方式 (In-Place Update): 如果集群支持(Kubernetes v1.27+),Updater 可以直接修改正在运行的 Pod 的资源请求,无需重启,从而实现真正的零中断更新。
3. Admission Controller (准入控制器)
- 职责: VPA 的“守门员”。它作为一个变异准入 Webhook运行,在每次创建新 Pod 时被触发。
- 工作流程: 当一个新 Pod 被创建时,Admission Controller 会检查它是否属于某个 VPA 的管理范围。如果是,它会从对应的 VPA 对象中读取
.status.recommendation.target 值,并将其作为该 Pod 的 requests 和 limits。这确保了所有新 Pod 从诞生起就拥有最优的资源配置。
三、VPA 更新模式详解
VPA 的行为高度可配置,主要通过 updatePolicy.updateMode 字段来控制。
| 模式 |
行为 |
适用场景 |
Off |
只观察,不干预。Recommender 会生成推荐值,但 Updater 和 Admission Controller 不会应用它们。你可以通过 kubectl get vpa <name> -o jsonpath='{.status.recommendation}' 来查看建议,用于手动调优。 |
安全评估阶段。在将 VPA 应用于生产环境前,先用此模式观察其推荐是否合理。 |
Initial |
仅在 Pod 创建时生效。VPA 会为新创建的 Pod 设置推荐的资源值,但对于已经运行的 Pod,即使推荐值发生变化,也不会去更新它们。 |
批处理任务或一次性 Job。这些工作负载的生命周期短,不需要在运行时调整资源。 |
Recreate |
主动管理。Updater 会主动驱逐不符合推荐值的 Pod,强制其重建以应用新的资源配置。这是最常用、最可靠的模式。 |
大多数长期运行的服务。能够确保所有 Pod 最终都符合最优资源配置。 |
InPlaceOrRecreate |
智能更新。优先尝试就地更新(无需重启),如果失败(例如,集群不支持或资源类型不支持),则回退到 Recreate 模式。 |
对启动时间敏感或希望实现零中断更新的应用。需要 Kubernetes v1.27+ 及相关特性支持。 |
Auto (已弃用) |
在旧版本中是 Recreate 的别名。强烈建议不要使用,应明确选择 Recreate 或 InPlaceOrRecreate。 |
N/A |
四、高级配置:资源策略与边界控制
为了防止 VPA 的“过度优化”导致应用不稳定,VPA 提供了精细的资源策略 (resourcePolicy)。
1. 设置资源边界
通过 minAllowed 和 maxAllowed,你可以为 VPA 的推荐值设定安全边界。
resourcePolicy:
containerPolicies:
- containerName: "app"
minAllowed:
cpu: "100m"
memory: "128Mi"
maxAllowed:
cpu: "2"
memory: "2Gi"
即使 Recommender 认为只需要 50m CPU,VPA 也会尊重你的 minAllowed,至少分配 100m,确保应用有基本的性能保障。
2. 控制管理的资源类型
通过 controlledResources,你可以指定 VPA 只管理 CPU 或只管理内存。
controlledResources: ["cpu"] # 只调整CPU,内存保持不变
3. 控制 Requests vs. Limits
controlledValues 字段决定了 VPA 如何处理 requests 和 limits。
RequestsAndLimits(默认): VPA 同时设置 requests 和 limits,并保持它们之间的比例不变。
RequestsOnly: VPA 只调整 requests,limits 保持用户定义的原始值不变。这对于那些 limits 是硬性安全上限的场景非常有用。
4. 与 LimitRange 集成
VPA 的 Admission Controller 和 Updater 在应用推荐值之前,会自动检查集群中的 LimitRange 策略。如果推荐值超出了 LimitRange 定义的 min 或 max,VPA 会自动将其裁剪到合规范围内,确保操作的成功。
五、总结与最佳实践
VPA 是 Kubernetes 弹性体系中不可或缺的一环,它专注于深度优化单个 Pod 的资源效率。要成功运用 VPA,请遵循以下最佳实践:
- 先观察,后行动: 始终从
Off 模式开始,验证推荐值的合理性。
- 谨慎选择更新模式: 对于关键业务,
Recreate 模式虽然会重启 Pod,但最为稳定可靠。只有在充分测试并确认集群支持后,才考虑 InPlaceOrRecreate。
- 设置合理的边界: 务必使用
minAllowed 和 maxAllowed 来保护你的应用免受极端推荐值的影响。
- 确保 Metrics Server 可用: VPA 依赖 Metrics Server 提供指标,确保它已在集群中正确部署。
- 与 HPA 和 CA 协同: 将 VPA 与 HPA(应用层弹性)和 Cluster Autoscaler(基础设施层弹性)结合使用,构建一个全方位、多层次的弹性系统。
通过合理配置和使用 VPA,你不仅能显著降低云资源成本,还能大幅提升应用的稳定性和可靠性,真正实现“按需所用,恰到好处”的云原生运维理念。如果你想了解更多关于 Kubernetes 的实践技巧,欢迎到 云栈社区 与其他开发者交流探讨。
|