
想象一下这样的场景:你的生产系统突然流量激增,某个 Pod 的 CPU 使用率已经飙升到 90%。传统做法是重建整个 Pod,这往往导致服务中断 30 秒以上。现在,借助 Kubernetes 1.35 带来的一项重磅功能,你只需一行命令,CPU 资源就能瞬间调整完毕,实现服务零中断!
这就是 Kubernetes 1.35 中正式达到稳定阶段(GA)的原地 Pod 资源调整(In-Place Pod Resize)功能。
1. 什么是 In-Place Pod Resize?
原地 Pod 资源调整(In-Place Pod Resize) 是 Kubernetes 的一项关键特性,它允许你直接修改正在运行的 Pod 的 CPU 和内存资源配置,而无需重建 Pod 本身。这项特性对于追求高可用性和敏捷性的云原生应用来说意义重大。
1.1 核心意义
In-Place Pod Resize 是一个基础构建块,旨在解锁无缝、垂直的自动缩放功能,并提升工作负载的资源使用效率。
核心优势
- ⚡ 零中断调整:CPU 调整无需重启容器,内存调整仅在必要时才重启。
- 这意味着,对延迟敏感或重启成本高的工作负载,可以在不停机或不丢失状态的情况下,就地修改其资源配额。
- ⚙️ 即时生效:资源调整指令下达后立即开始处理,无需等待漫长的 Pod 重建和调度过程。
- 🛡️ 高稳定性:避免了因 Pod 重建而引发的网络抖动、服务端点变化等潜在中断风险。
- 🎛️ 简化运维:将资源调优从一场需要谨慎计划的“重型手术”,转变为可以快速响应的“日常微调”。
解锁新能力
- 更强大的自动缩放功能:自动扩缩器现在可以以更小的影响来调整资源。例如,垂直 Pod 自动缩放器(VPA)的
InPlaceOrRecreate 更新模式就利用了此特性,该模式现已升级到 beta 版。这使得资源可以根据实际使用情况自动、无缝地调整,并将服务中断降至最低。
- 解决临时资源需求:可以快速应对工作负载临时需要更多资源的情况。这将支持像 CPU 启动加速(AEP-7862)这样的功能,应用程序可以在启动期间请求更多 CPU 资源,完成任务后再自动缩减。
1.2 发展历程
这个功能经过了社区长期的孵化和打磨:
- v1.27: 🧪 Alpha 版本,进行基础功能验证。
- v1.33: 🏗️ Beta 版本,稳定性和可用性得到大幅提升。
- v1.35: 🎉 正式 GA,标志着该功能已足够稳定,可以放心地在生产环境中使用。
2. ⚠️ 重要限制和注意事项
在兴奋之余,了解其限制是安全使用的前提。
2.1 💚 支持的资源类型
| 资源类型 |
支持程度 |
重启要求 |
说明 |
| CPU |
✅ 完全支持 |
🚫 无需重启 |
最常用,可实现真正的零中断调整 |
| 内存 |
✅ 支持 |
⚠️ 通常需要重启 |
大多数应用和容器运行时不支持内存热更新 |
| 存储 |
❌ 不支持 |
- |
存在技术限制,未来可能支持 |
| GPU 等扩展资源 |
❌ 不支持 |
- |
相关支持仍在开发中 |
2.2 🏷️ QoS 类限制
Pod 的 QoS(服务质量)类别在调整前后必须保持一致:
- 🛡️ Guaranteed:
requests = limits,拥有最高优先级。
- ⚖️ Burstable:
requests < limits,拥有中等优先级。
- 🎲 BestEffort:未设置资源限制,拥有最低优先级。
⚠️ 重要提醒:无法通过资源调整来改变一个 Pod 的 QoS 类别!
2.3 🐳 容器类型支持情况
| 容器类型 |
支持程度 |
说明 |
| 普通容器 |
✅ 完全支持 |
最常见的应用场景 |
| Sidecar 容器 |
✅ 支持调整 |
适用于服务网格等场景 |
| Init 容器 |
⚠️ 条件支持 |
仅支持调整尚未开始执行的 Init 容器 |
| Ephemeral 容器 |
❌ 不支持 |
用于临时调试的容器不支持资源调整 |
2.4 🖥️ 节点和运行时限制
| 环境/配置 |
支持程度 |
影响范围 |
| Windows Pod |
❌ 不支持 |
整个 Windows 节点环境 |
| 静态 CPU 管理器 |
❌ 不支持 |
使用了 CPU 亲和性(如 static 策略)的场景 |
| 内存管理器 |
❌ 部分不支持 |
使用了特定内存策略(如 Memory Manager)的场景 |
| Swap 内存 |
⚠️ 条件支持 |
仅在特定配置下可用 |
2.5 🛡️ 安全和稳定性保证
重要风险提醒
- 💥 内存减少风险:当尝试降低内存限制时,如果容器当前的内存使用量已经超过新的限制值,可能会立即触发 OOM(内存溢出)导致容器被杀死!
- ✅ 调整验证:Kubelet 会严格验证每个调整请求的可行性(如节点资源是否充足),确保操作安全。
- 🔄 回滚保护:如果调整失败,系统会自动保持原有的资源配置,不会破坏 Pod 的运行状态。
💡 最佳实践:在调低内存限制前,务必先通过监控工具检查容器的当前内存使用量,避免意外触发 OOM。
3. 🔧 核心修改,一探究竟
3.1 📊 资源字段重构
In-Place Pod Resize 对 Kubernetes API 的资源字段进行了精妙的设计,将其分为两个层面:
- 期望资源:
spec.containers- .resources
- 这是你期望容器拥有的资源配置。
- 实际资源:
status.containerStatuses- .resources
- 这是容器实际正在使用的资源配置。
✨ 关键变化:现在,spec.containers.resources 字段支持在 Pod 运行时进行修改!无论是 requests 还是 limits,都可以动态调整。
3.2 📋 新增 Pod 状态
为了让资源调整过程对用户透明且可观测,Kubernetes 引入了三个新的 Pod 状态条件(Condition):
| 状态 |
含义 |
常见原因 |
| PodResizePending |
⏳ 调整请求待处理 |
节点资源不足、节点压力大、策略检查未通过等 |
| PodResizeInProgress |
🔄 正在执行调整 |
Kubelet 已接收并正在处理调整请求 |
| PodResizeStatusInfeasible |
❌ 无法调整(不符合策略) |
违反 QoS 类限制、容器类型不支持、资源请求无效等 |
通过 kubectl get pod 和 kubectl describe pod 命令,你可以实时监控资源调整的进度和状态。
3.3 ⚙️ resizePolicy 配置
新增的 resizePolicy 字段允许你为每种资源类型精确控制调整行为。
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: nginx
resizePolicy: # 🎛️ 新增配置
- resourceName: cpu # 支持 cpu、memory
restartPolicy: NotRequired # CPU:调整无需重启(默认值)
- resourceName: memory
restartPolicy: RestartContainer # 内存:调整时需要重启容器
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 100m
memory: 128Mi
🔧 restartPolicy 选项:
NotRequired:调整该资源时,无需重启容器(这是 CPU 调整的最佳选择)。
RestartContainer:调整该资源时,需要重启容器(这是内存调整的默认且安全的选择)。
💡 高级用法:如果你的应用程序本身支持热更新内存(例如某些配置了特定参数的 JVM 应用),你可以将内存的 restartPolicy 设置为 NotRequired,从而尝试实现真正的内存零中断调整。但请务必充分测试。
4. 🎮 实战演示,亲手试试!
4.1 🏗️ 创建测试 Pod
首先,我们创建一个用于测试的 Pod 配置文件。
cat << 'EOF' > pod-resize.yaml
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
spec:
containers:
- name: pause
image: registry.cn-shanghai.aliyuncs.com/kubeclipper/busybox:1.36.0
command: ["sleep", "3600"]
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # 默认值,此处显式声明
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
EOF
配置解读:
resizePolicy 定义了调整策略:CPU 调整无需重启 (NotRequired),内存调整则需要重启容器 (RestartContainer)。
- 初始资源请求和限制均为 CPU 700m,内存 200Mi。
创建 Pod:
kubectl apply -f pod-resize.yaml
4.2 ⚡ CPU 调整:真正的零中断体验!
现在,我们尝试将 CPU 资源从 700m 提升到 800m。
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'
验证:查看 Pod 状态与资源
root@lixd-dev-2:~/k8s2# k get po resize-demo -oyaml|grep "resources:" -A 6
resources:
limits:
cpu: 800m
memory: 200Mi
requests:
cpu: 800m
memory: 200Mi
--
resources:
limits:
cpu: 800m
memory: 200Mi
requests:
cpu: 800m
memory: 200Mi
root@lixd-dev-2:~/k8s2# k get po
NAME READY STATUS RESTARTS AGE
resize-demo 1/1 Running 0 2m43s
🎉 结果分析:
spec 和 status 中的 CPU 资源均已成功更新为 800m。
- 最关键的是:RESTARTS 次数依然为 0。这表明容器没有重启,实现了真正的原地、零中断 CPU 资源扩容!
验证:查看 Pod 事件
root@lixd-dev-2:~/k8s2# k describe po resize-demo
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Normal ResizeStarted 20s kubelet Pod resize started: {"containers":[{"name":"pause","resources":{"limits":{"cpu":"800m","memory":"200Mi"},"requests":{"cpu":"800m","memory":"200Mi"}}}],"generation":2}
Normal ResizeCompleted 19s kubelet Pod resize completed: {"containers":[{"name":"pause","resources":{"limits":{"cpu":"800m","memory":"200Mi"},"requests":{"cpu":"800m","memory":"200Mi"}}}],"generation":2}
事件日志清晰显示了 ResizeStarted 和 ResizeCompleted,整个过程快速完成。
4.3 🧠 内存调整:需要重启但依然高效!
接下来,尝试将内存从 200Mi 提升到 300Mi。
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"memory":"300Mi"}, "limits":{"memory":"300Mi"}}}]}}'
验证:查看 Pod 状态
root@lixd-dev-2:~/k8s2# k get po resize-demo -oyaml|grep "resources:" -A 6
resources:
limits:
cpu: 700m
memory: 300Mi
requests:
cpu: 700m
memory: 300Mi
--
resources:
limits:
cpu: 700m
memory: 300Mi
requests:
cpu: 700m
memory: 300Mi
root@lixd-dev-2:~/k8s2# k get po
NAME READY STATUS RESTARTS AGE
resize-demo 1/1 Running 1 (83s ago) 118s
📊 结果分析:
- 内存资源已成功更新为 300Mi。
- RESTARTS 次数变为 1。这完全符合我们预设的
RestartContainer 策略,即调整内存需要重启容器。虽然有一次重启,但相比传统的删除重建 Pod 方式,其影响更小、速度更快。
验证:查看 Pod 事件
root@lixd-dev-2:~/k8s2# k describe po resize-demo
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Normal ResizeStarted 2m30s kubelet Pod resize started: {"containers":[{"name":"pause","resources":{"limits":{"cpu":"700m","memory":"300Mi"},"requests":{"cpu":"700m","memory":"300Mi"}}}],"generation":2}
Normal Killing 2m30s kubelet spec.containers{pause}: Container pause resize requires restart
Normal Pulled 2m (x2 over 2m52s) kubelet spec.containers{pause}: Container image "registry.cn-shanghai.aliyuncs.com/kubeclipper/busybox:1.36.0" already present on machine and can be accessed by the pod
...
Normal ResizeCompleted 119s kubelet Pod resize completed: {"containers":[{"name":"pause","resources":{"limits":{"cpu":"700m","memory":"300Mi"},"requests":{"cpu":"700m","memory":"300Mi"}}}],"generation":2}
事件序列明确展示了过程:ResizeStarted -> Killing (因为需要重启) -> 容器重启 -> ResizeCompleted。
4.4 🚫 资源不足场景:调整请求被拒绝
最后,我们测试一个异常场景:申请远超节点可用量的 CPU 资源(1000个核心)。
kubectl patch pod resize-demo --subresource resize --patch \
'{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"1000"}, "limits":{"cpu":"1000"}}}]}}'
验证:查看 Pod 状态与资源
root@lixd-dev-2:~/k8s2# k get po resize-demo -oyaml|grep "resources:" -A 6
resources:
limits:
cpu: 1k
memory: 200Mi
requests:
cpu: 1k
memory: 200Mi
--
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
可以看到,spec 中的期望资源被更新了,但 status 中的实际资源仍然是旧的 700m,说明调整并未生效。
验证:查看 Pod 状态条件
root@lixd-dev-2:~/k8s2# k get po resize-demo -oyaml|grep "conditions:" -A 10
conditions:
- lastProbeTime: "2026-01-20T14:03:38Z"
lastTransitionTime: "2026-01-20T14:03:38Z"
message: 'Node didn''t have enough capacity: cpu, requested: 1000000, capacity:
16000'
observedGeneration: 2
reason: Infeasible
status: "True"
type: PodResizePending
Pod 进入了 PodResizePending 状态,原因 (reason) 是 Infeasible,消息 (message) 明确告诉我们:“节点没有足够的容量:CPU”。
验证:查看 Pod 事件
root@lixd-dev-2:~/k8s2# k describe po resize-demo
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Warning ResizeInfeasible 3m23s kubelet Pod resize Infeasible: {"containers":[{"name":"pause","resources":{"limits":{"cpu":"1k","memory":"200Mi"},"requests":{"cpu":"1k","memory":"200Mi"}}}],"generation":2,"error":"Node didn't have enough capacity: cpu, requested: 1000000, capacity: 16000"}
事件日志中也记录了 ResizeInfeasible 警告,并给出了详细的错误信息。这体现了该功能良好的安全性和可观测性。
5. 🎯 总结与最佳实践
5.1 功能价值总结
In-Place Pod Resize 的 GA 无疑是 Kubernetes 资源管理领域的一次重要演进。
核心价值:
- 最小化中断:CPU 调整无需中断服务,内存调整的影响也远小于重建 Pod。
- 提升响应速度:资源调整几乎实时生效,能更快应对流量波动。
- 增强稳定性:避免了因 Pod 重建导致的服务发现延迟、连接中断等问题。
- 优化资源效率:使基于实际负载的动态、细粒度资源调整变得可行,减少资源浪费。
5.2 最佳实践建议
生产环境应用建议:
- CPU 优先使用:充分利用 CPU 原地调整零中断的优势,这是该功能目前最大的亮点。
- 审慎调整内存:
- 对于大多数应用,使用默认的
RestartContainer 策略是安全的选择。
- 对于有状态或对重启敏感的应用,调整内存前务必评估影响。如果应用支持,可尝试配置
NotRequired 策略,但需经过严格测试。
- 保持 QoS 一致性:确保调整后的资源请求和限制关系不会改变 Pod 原有的 QoS 类别,以免引发意料之外的调度或驱逐行为。
- 强化监控与告警:对资源调整操作及调整后的资源使用率进行密切监控,设置合理告警,以便及时发现配置错误或资源不足等问题。
配置模板参考:
# 推荐的 resizePolicy 配置
spec:
containers:
- name: app
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # CPU 调整无需重启
- resourceName: memory
restartPolicy: RestartContainer # 内存调整需要重启(除非应用明确支持热更新)
集成与展望:
- 与 VPA 结合:垂直 Pod 自动扩缩器(VPA)可利用此功能,实现更智能、更平滑的垂直扩缩容。
- 赋能平台工程:在多租户 K8s 平台或内部开发者平台中,可以此为基石,为用户提供更灵活、更高效的自助资源调整能力。
- 未来扩展:期待未来对 GPU、存储等扩展资源的支持,以及更多容器运行时对内存热更新的支持。
In-Place Pod Resize 让 Kubernetes 的资源管理从“静态预设”迈向了“动态响应”。对于追求极致可用性与资源效率的团队而言,现在正是开始探索和利用这一强大功能的好时机。
