Kubernetes教程(五十)---K8s 1.35:In-Place Pod Resize 正式 GA,实现 Pod 资源零中断调整

in-place-pod-resize-ga.jpeg 想象一下这样的场景:你的生产系统突然流量激增,某个 Pod 的 CPU 使用率已经飙升到 90%,传统做法是重建整个 Pod,导致服务中断 30 秒以上。而现在,只需一行命令,CPU 资源瞬间调整完毕,服务零中断!

这就是 Kubernetes 1.35 带来的重磅功能:原地 Pod 资源调整(In-Place Pod Resize)正式 GA!🎉

1. 什么是 In-Place Pod Resize?

原地 Pod 资源调整(In-Place Pod Resize) 是 Kubernetes 的一项革命性特性,允许直接修改正在运行的 Pod 的 CPU 和内存资源配置,而无需重建 Pod。

1.1 核心意义

In-Place Pod Resize 是一个基础构建块,可解锁无缝、垂直的自动缩放功能,并提高工作负载效率。

🎯 核心优势

  • ⚡ 零中断调整:CPU 调整无需重启,内存调整仅在必要时重启

    • 对延迟或重启敏感的工作负载可以在不停机或状态丢失的情况下就地修改其资源
  • ⚙️ 即时生效:调整立即见效,无需等待 Pod 重建

  • 🛡️ 高稳定性:告别重建导致的网络抖动和服务中断

  • 🎛️ 简化运维:资源调优从"重型手术"变为"日常微调"

🚀 解锁新能力

更强大的自动缩放功能:自动缩放器现在可以调整资源,影响更小。例如,垂直Pod自动缩放器(VPA)的 InPlaceOrRecreate 更新模式利用了这一特性,现已升级到 beta 版。这使得资源可以根据使用情况自动无缝地调整,并将中断降至最低。

解决临时资源需求:可以快速调整临时需要更多资源的工作负载。这将启用 CPU 启动加速(AEP-7862)等功能,应用程序可以在启动期间请求更多 CPU,然后自动缩减。

1.2 发展历程

这个功能可不是一蹴而就的!从 Kubernetes v1.27 开始作为 Alpha 版本引入,经过社区反复打磨:

  • v1.27: 🧪 Alpha 版本,基础功能验证
  • v1.33: 🏗️ Beta 版本,稳定性大幅提升
  • v1.35: 🎉 正式 GA,生产环境完全就绪!

经过多次迭代,现在你可以放心大胆地在生产环境中使用这个强大的功能了!

2. ⚠️ 重要限制和注意事项

2.1 💚 支持的资源类型

资源类型支持程度重启要求说明
CPU✅ 完全支持🚫 无需重启最常用,零中断调整
内存✅ 支持⚠️ 通常需要重启大多数应用不支持热更新内存
存储❌ 不支持-技术限制,未来可能支持
GPU 等扩展资源❌ 不支持-仍在开发中

2.2 🏷️ QoS 类限制

Pod 的 QoS(服务质量)类调整有严格要求,调整后必须保持原有 QoS 类不变:

  • 🛡️ Guaranteedrequests = limits,最高优先级
  • ⚖️ Burstablerequests < limits,中等优先级
  • 🎲 BestEffort:无资源限制,最低优先级

⚠️ 重要提醒:无法通过资源调整改变 Pod 的 QoS 类!

2.3 🐳 容器类型支持情况

容器类型支持程度说明
普通容器✅ 完全支持最常见的应用场景
Sidecar 容器✅ 支持调整适用于服务网格等场景
Init 容器⚠️ 条件支持仅支持调整尚未执行的Init容器
Ephemeral 容器❌ 不支持临时调试容器不支持

2.4 🖥️ 节点和运行时限制

环境/配置支持程度影响范围
Windows Pod❌ 不支持整个 Windows 环境
静态 CPU 管理器❌ 不支持CPU 亲和性场景
内存管理器❌ 部分不支持特定内存策略
Swap 内存⚠️ 条件支持仅特定配置下可用

2.5 🛡️ 安全和稳定性保证

🚨 重要风险提醒

  • 💥 内存减少风险:降低内存限制时,如果当前使用量超过新限制,可能会触发 OOM!
  • ✅ 调整验证:Kubelet 会严格验证调整请求的可行性,确保安全
  • 🔄 回滚保护:调整失败时自动保持原有配置,不会破坏运行状态

💡 最佳实践:调整内存前务必检查当前使用量,避免意外 OOM

3. 🔧 核心修改,一探究竟

3.1 📊 资源字段重构

In-Place Pod Resize 对 Kubernetes API 做了精妙的设计:

🎯 资源分为两层

  • 期望资源spec.containers[*].resources - 你想要的资源配置
  • 实际资源status.containerStatuses[*].resources - 容器真正获得的资源

✨ 关键变化spec.containers[*].resources 现在支持运行时修改!requestslimits 都可以动态调整。

3.2 📋 新增 Pod 状态

为了让调整过程透明可观测,Kubernetes 引入了三个新的 Pod 状态:

状态含义常见原因
PodResizePending⏳ 调整请求待处理资源不足、节点压力大等
PodResizeInProgress🔄 正在执行调整Kubelet 正在处理调整请求
PodResizeStatusInfeasible❌ 无法调整(不符合策略)违反QoS类限制、容器类型不支持等

通过 kubectl get podkubectl describe pod,你可以实时监控调整进度!

3.3 ⚙️ resizePolicy 配置

新增 resizePolicy 字段,让你精确控制每种资源的调整行为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 # Default, but explicit here
    - resourceName: memory
      restartPolicy: RestartContainer
    resources:
      limits:
        memory: "200Mi"
        cpu: "700m"
      requests:
        memory: "200Mi"
        cpu: "700m"
EOF

✨ 注意这里的 resizePolicy 配置:

  • resourceName:指定要控制的资源类型(cpumemory
  • restartPolicy:决定调整时是否需要重启容器

🎯 配置解读

  • CPU 设置为 NotRequired:调整时零中断
  • 内存设置为 RestartContainer:调整时会重启容器(这是默认行为)

💡 为什么内存需要重启? 大多数应用程序和容器运行时不支持动态调整内存分配,所以需要重启来生效。

1
kubectl apply -f pod-resize.yaml

4.2 ⚡ CPU 调整:真正的零中断体验!

1
2
kubectl patch pod resize-demo --subresource resize --patch \
  '{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'

🎯 操作目标:将 CPU 从 700m 提升到 800m,看看会发生什么?

验证:查看 Pod 状态

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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

🎉 结果惊艳

  • CPU 成功更新到 800m ✅
  • restart count 依然是 0(没有重启!)✅
  • In-Place Resize 完美生效! 🚀

验证:查看 Pod Event

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
root@lixd-dev-2:~/k8s2# k describe po resize-demo

Events:
  Type    Reason           Age   From               Message
  ----    ------           ----  ----               -------
  Normal  Scheduled        57s   default-scheduler  Successfully assigned default/resize-demo to lixd-dev-2.taiko.local
  Normal  Pulled           56s   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  Created          56s   kubelet            spec.containers{pause}: Container created
  Normal  Started          56s   kubelet            spec.containers{pause}: Container started
  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}

可以看到 Event 里面可以看到 ResizeStarted 和 ResizeCompleted 事件。

4.3 🧠 内存调整:需要重启但依然高效!

1
2
kubectl patch pod resize-demo --subresource resize --patch \
  '{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"memory":"300Mi"}, "limits":{"memory":"300Mi"}}}]}}'

🎯 操作目标:将内存从 200Mi 提升到 300Mi,观察重启行为。

验证:查看 Pod 状态

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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#
root@lixd-dev-2:~/k8s2# k get po
NAME          READY   STATUS    RESTARTS      AGE
resize-demo   1/1     Running   1 (83s ago)   118s

📊 结果分析

  • 内存成功更新到 300Mi ✅
  • Restart Count 变为 1(预期的重启)✅
  • 符合 RestartContainer 策略! 🎯

💡 进阶技巧:如果你的应用程序和运行时支持热更新内存,可以将 restartPolicy 设置为 NotRequired,实现内存调整的零中断!

验证:查看 Pod Event

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
root@lixd-dev-2:~/k8s2# k describe po resize-demo
Events:
  Type    Reason           Age                   From               Message
  ----    ------           ----                  ----               -------
  Normal  Scheduled        2m53s                 default-scheduler  Successfully assigned default/resize-demo to lixd-dev-2.taiko.local
  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  Created          2m (x2 over 2m52s)    kubelet            spec.containers{pause}: Container created
  Normal  Started          119s (x2 over 2m52s)  kubelet            spec.containers{pause}: Container started
  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,这也符合内存调整的 RestartContainer 重启策略。

4.4 🚫 资源不足场景:调整请求被拒绝

1
2
kubectl patch pod resize-demo --subresource resize --patch \
  '{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"1000"}, "limits":{"cpu":"1000"}}}]}}'

🎯 操作目标:故意申请超出节点容量的 CPU(1000 core),看看系统如何处理?

验证:查看 Pod 状态

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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)CPU 更新为 1000 core ✅
  • 实际资源(status)仍为 700m(未生效)❌
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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

显示 PodResizePending 状态,错误信息清晰明了:“Node didn’t have enough capacity”!

有一个 PodResizePending 状态,因为资源不足,所以一直 pending。

验证:查看 Pod Event

1
2
3
4
5
6
7
8
9
root@lixd-dev-2:~/k8s2# k describe po resize-demo
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Normal   Scheduled         3m29s  default-scheduler  Successfully assigned default/resize-demo to lixd-dev-2.taiko.local
  Normal   Pulled            3m28s  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   Created           3m28s  kubelet            spec.containers{pause}: Container created
  Normal   Started           3m27s  kubelet            spec.containers{pause}: Container started
  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"}

Event 里面也可以看到具体问题,ResizeInfeasible 事件。

5. 🎯 总结:资源管理的革命性突破

5.1 💎 功能价值,一目了然

In-Place Pod Resize GA 是 Kubernetes 资源管理领域的一次革命!

🚀 四大核心优势

  • ⚡ 零中断:CPU 调整无需重启,内存调整仅在必要时重启
  • ⚙️ 即时生效:调整立即见效,无需等待 Pod 重建
  • 🛡️ 高稳定性:告别重建导致的网络抖动和服务中断
  • 🎛️ 简化运维:资源调优从"重型手术"变为"日常微调"

🔄 技术革新

  • 破坏性重建非破坏性调整
  • 静态配置动态优化
  • 人工运维智能自动化

5.2 最佳实践建议

生产环境应用建议

  1. CPU 优先使用:优先使用 CPU 的原地调整能力,避免不必要的容器重启
  2. 内存调整策略:根据应用特性选择合适的 restartPolicy
    • 对延迟敏感的应用:评估是否支持热更新内存
    • 普通应用:使用默认的 RestartContainer 策略
  3. QoS 类保持:确保调整后 Pod 的 QoS 类不变,避免调度问题
  4. 资源监控:密切监控调整后的资源使用情况,及时发现和处理异常

配置建议

1
2
3
4
5
6
7
8
9
# 推荐的 resizePolicy 配置
spec:
  containers:
  - name: app
    resizePolicy:
    - resourceName: cpu
      restartPolicy: NotRequired      # CPU 调整无需重启
    - resourceName: memory
      restartPolicy: RestartContainer # 内存调整需要重启(除非应用支持热更新)

集成场景

  • VPA 集成:结合 Vertical Pod Autoscaler 实现智能资源调整
  • 自定义控制器:开发基于业务指标的自动扩缩容控制器
  • 多租户平台:为平台用户提供动态资源调整能力

In-Place Pod Resize 让 Kubernetes 的资源管理变得更加现代化和智能化。现在就开始体验这个强大的功能,让您的应用资源管理更上一层楼吧!

6. 参考

Kubernetes 1.35: In-Place Pod Resize Graduates to Stable

Configure Pod Container Resources In-Place

0%