Kubernetes 原位 Pod 调整大小
Source: Dev.to

背景
大约六年前,在 Kubernetes 上运行一个大型基于 Java 的平台时,我注意到一个反复出现的问题:我们的服务在应用启动期间需要显著更高的 CPU 和内存。大量使用 Spring Bean 和 AutoConfiguration 迫使我们为生存启动阶段设置夸大的资源请求和上限,即使这些资源在之后大多未被使用。
这种变通办法从未让人感觉正确。作为工程师,我希望有一种解决方案能够反映应用的实际生命周期,而不是其最糟糕的时刻。
我在 Kubernetes 仓库中打开了一个issue,描述了这个问题并提出了一种在不重启的情况下动态调整 Pod 资源的思路。该 issue 讨论不多,但悄悄地积累了兴趣(13 个 👍 表情)。每隔几个月,自动化机器人就会尝试将其标记为陈旧,每次我都会移除该标签。这种情况持续了将近六年……
直到 Kubernetes 1.35 发行,In‑Place Pod Resize 功能被标记为稳定。
什么是原地 Pod 调整大小
原地 Pod 调整大小允许 Kubernetes 在安全的情况下更新 CPU 和内存 请求 与 限制,而无需重启 Pod。这显著减少了因资源变更导致的不必要重启,降低了中断并提升了工作负载的可靠性。
对于资源需求随时间演变的应用——尤其是在启动后——此功能提供了长期缺失的构建块。
对 VerticalPodAutoscaler 的影响
新的 resizePolicy 字段在 pod‑spec 级别进行配置。虽然技术上可以手动更改 pod 资源,但这样并不会触发扩缩容。实际上,这一功能应由工作负载控制器来驱动。
目前唯一支持原地 pod 调整的控制器是 Vertical Pod Autoscaler(VPA)。
有两个增强提案实现了此行为:
- AEP‑4016:在 VPA 中支持原地更新 – 引入
InPlaceOrRecreate更新模式。 - AEP‑7862:CPU 启动加速 – 在启动期间临时为 pod 提供更多 CPU,以实现加速。这在概念上与我最初 issue 中提出的方法相似。
示例:使用两个 AEP 功能的 Deployment + VPA
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
spec:
replicas: 1
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: app
image: my-heavy-java-app:stable
ports:
- containerPort: 80
resources:
requests:
cpu: 1000m
memory: 1024Mi
limits:
cpu: 2000m
memory: 2048Mi
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: example-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: example
updatePolicy:
updateMode: InPlaceOrRecreate
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: "250m"
memory: "512Mi"
maxAllowed:
cpu: "3000m"
memory: "8192Mi"
# The CPU boosted resources can go beyond maxAllowed.
startupBoost:
cpu:
type: Factor
quantity: "2"
使用此配置后,pod 在启动期间的 CPU 请求和限制将翻倍。在加速期间不会进行任何重新调整。pod 达到 Ready 状态后,VPA 控制器会将 CPU 缩减至当前推荐的数值。此后,VPA 将继续正常工作,关键区别在于资源更新将在可能的情况下 原地 应用。
限制
此功能是否完全解决了上述问题?仅部分解决。
-
运行时约束 – Java 和 Python 运行时目前不支持在不重启的情况下调整内存限制。此限制存在于 Kubernetes 之外,并在 OpenJDK 项目中通过一个未解决的工单进行跟踪。

-
内存限制的降低 – 即使启用了 In‑Place Pod Resize,Kubernetes 仍未支持降低内存限制。这是一个已知限制,已在针对内存限制降低的增强提案中记录。
就地 Pod Resize – 内存限制降低
因此,虽然就地 Pod Resize 能有效解决 CPU 相关的启动峰值问题,但内存大小的动态调整仍是一个未解决的问题。
最终思考
就地 Pod 调整为诸如 StartupBoost 等酷炫新特性奠定了基础,并使 VPA 的使用更加可靠。虽然仍存在重要的缺口——例如 memory‑decrease support 和 scheduling race condition——此更改代表了一个有意义的前进步伐。
对于具有明显启动阶段和稳态阶段的工作负载,Kubernetes 终于开始更贴近现实地建模。
