什么是 VPA (Vertical Pod Autoscaler)?
VPA (Vertical Pod Autoscaler),中文称为垂直 Pod 自动扩缩容,是 Kubernetes 中的一种自动伸缩机制。
简单来说,它的作用是自动调整 Pod 的 CPU 和内存预留(Requests)与限制(Limits),以便让 Pod 拥有“刚好够用”的资源,既不浪费,也不会因为资源不足而崩溃。
以下是关于 VPA 的详细解析:
1. 核心概念:横向 vs. 纵向
为了理解 VPA,我们需要对比一下 Kubernetes 中最常用的 HPA:
- HPA (Horizontal Pod Autoscaler - 横向):
- 动作: 增加或减少 Pod 的数量(副本数)。
- 比喻: 饭馆客人多了,多雇几个服务员。
- 适用: 无状态应用(Stateless),如 Web 服务。
- VPA (Vertical Pod Autoscaler - 纵向):
- 动作: 增加或减少单个 Pod 的资源大小(CPU/内存)。
- 比喻: 某个服务员力气不够大,让他去健身变强壮(或者换个更强壮的人来)。
- 适用: 有状态应用(Stateful)、单体应用、或者难以水平扩展的应用(如数据库、Java 应用)。
2. VPA 解决什么问题?
在 Kubernetes 中部署应用时,开发者必须手动设置 resources.requests (调度所需资源) 和 resources.limits (资源上限)。
痛点在于:
- 难以预估: 开发者很难准确知道应用到底需要多少 CPU 和内存。
- 浪费资源: 为了保险,开发者通常会设置过大的资源(Over-provisioning),导致集群资源浪费。
- OOM 崩溃: 如果设置得太小,应用负载一高就会因为内存不足(OOM Killed)被杀掉。
- 维护困难: 随着业务迭代,资源需求会变,手动去改 YAML 文件很麻烦。
VPA 的作用就是通过监控历史数据,自动帮你填上这个“最优值”。
3. VPA 的工作原理
VPA 由三个主要组件组成:
- Recommender(推荐器):
- 它监控 Metrics Server(或 Prometheus)的历史资源使用数据。
- 它计算出建议的 CPU 和内存值。
- Updater(更新器):
- 它检查运行中的 Pod,如果发现 Pod 当前的资源配置与推荐值偏差太大,它会驱逐(Evict/Kill) 该 Pod。
- Admission Controller(准入控制器):
- 当 Pod 被驱逐后(或新创建时),控制器会拦截 Pod 的创建请求。
- 它将 Recommender 计算出的推荐值注入到新的 Pod 定义中。
- 最终,Pod 以新的资源大小启动。
4. VPA 的三种运行模式 (updateMode)
你可以配置 VPA 以不同的激进程度工作:
Off(仅推荐):- VPA 只计算推荐值,不修改 Pod。
- 用途: 你想看看 VPA 建议设多少,然后手动去改 YAML。这是最安全的入门模式。
Initial(仅初始化):- VPA 仅在 Pod 创建时修改资源请求。如果 Pod 已经在运行了,VPA 不会 重启它。
- 用途: 避免运行中服务中断,但能保证新发布的版本资源分配合理。
Auto(自动 - 默认):- VPA 会在 Pod 创建时修改资源,并且如果运行中的 Pod 资源配置不合理,VPA 会主动重启 Pod 来应用新配置。
- 注意: 这会导致服务重启,需要配合 PDB (Pod Disruption Budget) 使用以保证高可用。
5. VPA 与 HPA 的冲突
千万不要在同一个指标(CPU/内存)上同时开启 HPA 和 VPA。
原因:
- 负载变高 -> HPA 增加 Pod 数量 -> 平均负载降低。
- VPA 看到平均负载低 -> 缩小 Pod 的 CPU/内存 -> 负载百分比又变高了。
- HPA 看到负载高 -> 继续增加 Pod...
结果: 造成死循环,资源疯狂扩容。
例外情况:
HPA 使用自定义指标(如 QPS),而 VPA 管理 CPU/内存,这样是可以共存的。
6. VPA 的优缺点总结
优点:
- 节省成本: 自动缩减申请过大的资源。
- 提高稳定性: 自动为内存泄漏或流量突增的应用增加内存,减少 OOM。
- 自动化运维: 减少人工调优的时间。
缺点/局限性:
- 重启服务: 修改资源限制(目前)必须重启容器。在
Auto模式下,这可能导致短暂的服务不可用。- 注:Kubernetes 正在开发 "In-place Pod Vertical Scaling" (原地升级) 功能,未来可能不需要重启,但目前尚未完全成熟普及。
- 启动尖峰问题: 某些应用启动时需要大量 CPU(如 Java),启动后只需很少。VPA 可能会根据运行时的低负载把资源缩得太小,导致下次启动极其缓慢或超时。
- 不仅是 CPU/Mem: 对于像 JVM 这种自己管理内存的应用,VPA 调整了容器内存后,还需要确保 JVM 的
-Xmx参数也能随之调整(通常通过百分比设置)。
总结
VPA 是一个帮你把 Pod 调整到“体型最合适”的工具。 如果你的应用是单体的、有状态的,或者你不知道该给应用多少资源,VPA 是一个非常好的帮手;但如果你追求高并发且应用是无状态的,通常优先考虑 HPA。