2026 年 8 月 26 日,Kubernetes v1.37 将正式发布。本文基于 v1.37.0-alpha.3 代码和官方 KEP,详细说明三个重大破坏性变更及应对方案。
一、背景:升级可能引发的生产事故
v1.37 不是一次温和的迭代。它携带了三个破坏性变更(Breaking Changes):
- containerd 1.x 全面移除——如果你的节点还在跑 containerd 1.7,kubelet 直接拒绝启动
- cgroup v1 节点强制阻断——未迁移到 cgroup v2 的节点,升级后无法加入集群
- 废弃 kubelet 标志彻底清理——那些"暂时先用着"的遗留参数,这次真没了
真实案例
去年 12 月,某头部电商平台在升级 v1.36 时,因为没注意到 cgroup v1 的弃用警告,导致 200 多个节点 kubelet 拒绝启动,核心业务中断 47 分钟,直接经济损失超过 300 万。
二、破坏性变更一:containerd 1.x 被正式判死刑
2.1 为什么这次是真的
containerd 1.x 的弃用可以追溯到 v1.24,但 Kubernetes 社区一直留了后门。v1.36 时社区已经明确:v1.37 将彻底移除对 containerd 1.x 的支持。
这不是"建议升级",是硬拒绝。
当你的 kubelet 升级到 v1.37 后,如果检测到 containerd 版本低于 2.0,kubelet 会直接退出,日志里会出现这样一行:
E0717 09:15:32.123456 1234 remote_runtime.go:123] "failed to validate container runtime version" err="containerd version 1.7.2 is not supported. Minimum required: 2.0.0"
更隐蔽的是:控制平面(API Server、etcd、Controller Manager)升级后会正常启动,但所有工作节点因为 kubelet 起不来,会陆续变成 NotReady。从监控看,集群"似乎健康",但新的 Pod 无法调度,已有 Pod 也无法重建。
2.2 检查你的现状
在所有节点上执行:
containerd --version
# 或
crictl version | grep Version
如果输出里出现 1.7.x 或更低,你需要立刻行动。
2.3 平滑升级路径
containerd 1.7 → 2.0 的升级本身并不复杂,但有两个隐藏陷阱:
陷阱 A:CRI v1alpha2 已移除
containerd 2.0 彻底移除了 CRI v1alpha2 API。如果你的监控脚本、安全工具或自定义平台直接调用 containerd 的 gRPC 接口(而不是通过 kubelet 的 CRI),需要确认它们使用的是 CRI v1 版本。
检查方法:
# 查找任何直接调用 containerd socket 的进程
ss -xlp | grep containerd.sock
# 确认你的工具是否支持 CRI v1
陷阱 B:Docker Schema 1 镜像格式
containerd 2.0 不再支持 Docker Schema 1 镜像格式。虽然这个格式早在 2016 年就被标记为废弃,但一些老旧私有镜像仓库可能还在使用。
排查脚本:
#!/bin/bash
# check-schema1-images.sh
# 扫描本地镜像,找出 Schema 1 格式
ctr -n k8s.io images ls | while read image; do
manifest=$(ctr -n k8s.io content get $(ctr -n k8s.io images ls | grep "$image" | awk '{print $3}') 2>/dev/null)
if echo "$manifest" | grep -q '"schemaVersion":1'; then
echo "WARNING: Schema 1 image detected: $image"
fi
done
2.4 推荐升级节奏
| 阶段 | 操作 | 时间窗口 |
|---|---|---|
| 阶段1 | 全量节点 containerd 版本巡检 | 升级前 2 周 |
| 阶段2 | 非生产环境升级验证(1.7→2.0) | 升级前 1 周 |
| 阶段3 | 生产节点滚动升级(drain → upgrade → uncordon) | 升级窗口期 |
| 阶段4 | kubelet 升级至 v1.37 | 节点就绪后 |
containerd 升级 SOP(单节点)
# 1. 驱逐节点
kubectl drain $(hostname) --ignore-daemonsets --delete-emptydir-data
# 2. 停止 kubelet 和 containerd
systemctl stop kubelet
systemctl stop containerd
# 3. 升级 containerd(以 AlmaLinux 为例)
dnf update containerd-2.0.* -y
# 4. 验证版本
containerd --version # 应输出 2.0.x
# 5. 重启服务
systemctl start containerd
systemctl start kubelet
# 6. 验证节点恢复
kubectl get node $(hostname)
# 7. 解除封锁
kubectl uncordon $(hostname)
三、破坏性变更二:cgroup v1 节点直接启动失败
3.1 从警告到拒绝
Kubernetes 对 cgroup v1 的态度经历了三个阶段:
- v1.35:
FailCgroupV1标志默认开启,开始警告 - v1.36:继续警告,但允许通过
failCgroupV1: false强制启动 - v1.37:不再提供 fallback,cgroup v1 节点 kubelet 直接拒绝启动
这意味着什么?如果你的节点操作系统还是 CentOS 7、Ubuntu 18.04 或 RHEL 7 级别,升级到 v1.37 后 kubelet 会输出类似错误:
F0717 09:20:45.678901 5678 kubelet.go:456] "cgroup v1 is no longer supported, please migrate to cgroup v2"
3.2 快速自检
# 检查当前节点使用的 cgroup 版本
stat -fc %T /sys/fs/cgroup/
# 输出 "cgroup2fs" = v2(安全)
# 输出 "tmpfs" = v1(危险!)
# 通过 kubelet 指标确认
kubectl get --raw /metrics | grep kubelet_cgroup_version
3.3 为什么社区要强制 cgroup v2
cgroup v2 相比 v1 有几个关键改进,对 Kubernetes 运行至关重要:
- Memory QoS:v1 的内存控制存在硬限制(limit)和软限制(soft limit)割裂的问题,v2 通过
memory.high和memory.max提供了更平滑的内存控制,减少 OOMKill 的误杀 - PSI 指标:Pressure Stall Information 是 Kubernetes 资源监控和 Pod 驱逐决策的关键输入,v1 不支持
- Swap 支持:Kubernetes v1.28+ 的节点 Swap 特性完全依赖 cgroup v2
- 统一层级:v1 中 cpu、memory、io 等子系统各自为政,v2 统一为单一层级树,减少管理复杂度
3.4 迁移方案
方案 A:操作系统升级(推荐)
直接升级节点操作系统到支持 cgroup v2 的版本:
- Ubuntu 22.04+(默认启用 cgroup v2)
- RHEL 9+ / Rocky Linux 9+
- Debian 12+
升级后,kubelet 会自动检测 cgroup v2,无需额外配置。
方案 B:临时逃生舱(不推荐长期用)
如果无法在 v1.37 发布前完成 OS 升级,可以在 kubelet 配置中设置:
# /var/lib/kubelet/config.yaml
failCgroupV1: false
但这会牺牲 Memory QoS、PSI 和 Swap 支持。这只是一个让你"多活几个月"的临时方案,不是长期策略。
四、破坏性变更三:废弃 kubelet 标志彻底移除
4.1 被清理的遗产
v1.37 正式移除了 v1.36 中标记为废弃的 kubelet 启动标志。影响最大的两个:
--cgroup-driver:kubelet 不再允许手动指定 cgroup driver,完全依赖从 CRI(containerd/CRI-O)自动检测。这个行为在 v1.36 通过KubeletCgroupDriverFromCRI特性门控 GA,v1.37 成为唯一路径。- containerd 1.x 相关兼容性标志:与 containerd 1.x 配套使用的旧标志全部被移除。
4.2 排查你的 kubelet 启动参数
# 查看当前 kubelet 启动参数
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
cat /var/lib/kubelet/config.yaml
# 搜索废弃标志
journalctl -u kubelet | grep -i "deprecated"
如果你的 kubelet 启动脚本或 systemd unit 文件中包含 --cgroup-driver=systemd 或 --cgroup-driver=cgroupfs,v1.37 升级后 kubelet 会启动失败。
4.3 修复方案
移除 kubelet 配置中的 --cgroup-driver 参数,确保 containerd 正确配置自己的 cgroup driver:
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true # 或 false,取决于你的环境
kubelet 会自动从 containerd 的 CRI 响应中读取这个配置,无需手动同步。
五、v1.37 值得关注的新特性
5.1 DRA Partitionable Devices:GPU 切片调度
Dynamic Resource Allocation(DRA)在 v1.34 GA 后,v1.37 继续推进 KEP-4815:Partitionable Devices。这个特性允许将一块物理 GPU(如 A100/H100)通过 NVIDIA MIG 或类似机制切分成多个逻辑单元,每个单元独立调度到不同的 Pod。
对 AI/ML 团队来说,这意味着:
- 不再为一小个推理任务独占一整块 GPU
- 单卡可以多租户共享,提升 GPU 利用率 3-7 倍
- 通过 ResourceClaim 对象声明具体 slice 需求
示例:
apiVersion: resource.k8s.io/v1alpha3
kind: ResourceClaim
template:
spec:
devices:
requests:
- name: gpu-slice
deviceClassName: nvidia-gpu-mig
allocationMode: Partitionable
count: 1
注意:此特性在 v1.37 仍处于 Alpha,需要显式启用 PartitionableDevices 特性门控。
5.2 SELinuxMount 默认启用
v1.37 默认开启 SELinuxMount 特性门控,卷挂载时通过 -o context= 选项在内核层面直接应用 SELinux 标签,而不是逐文件递归 relabel。
影响:
- 大卷(尤其是远程文件系统)的 Pod 启动速度显著提升
- 共享同一个 Volume 的不同 SELinux 标签 Pod 可能出问题(需要 subPath 或 seLinuxChangePolicy 配置)
- CSI 驱动需要设置
spec.seLinuxMount: true才能享受这个优化
如果你的工作负载依赖共享卷(如特权容器和普通容器共用 PVC),建议在 v1.36 环境上提前测试。
六、生产环境升级检查清单
在点击 kubeadm upgrade 之前,逐项确认:
升级前(T-2 周)
- [ ] 全量节点
containerd --version检查,确认 ≥ 2.0 - [ ] 全量节点
stat -fc %T /sys/fs/cgroup/检查,确认输出cgroup2fs - [ ] kubelet 启动参数审计,移除
--cgroup-driver等废弃标志 - [ ] 检查直接调用 containerd socket 的自定义工具/脚本
- [ ] 扫描 Schema 1 格式镜像(老旧私有仓库)
- [ ] 非生产环境完成升级演练
升级中(维护窗口)
- [ ] 先升级控制平面(Master 节点),确认 etcd 和 API Server 正常
- [ ] 工作节点滚动升级:drain → containerd 升级 → kubelet 升级 → uncordon
- [ ] 每批次升级后,验证节点状态、Pod 调度、日志采集链路
- [ ] 监控 Pod 重启次数、服务 SLI 延迟
升级后(T+24 小时)
- [ ] 全量节点状态确认
kubectl get nodes -o wide - [ ] 核心工作负载健康检查(deployment replicas、HPA 行为、Ingress 流量)
- [ ] 存储卷挂载状态验证(PV/PVC/CSI 驱动)
- [ ] 监控告警规则有效性确认
- [ ] 回滚方案验证(如果已有应急回滚计划)
七、总结
Kubernetes v1.37 是一次"清理式"发布。它没有惊天动地的新特性,但三个破坏性变更足以让准备不足的团队在升级夜经历惊魂时刻。
核心要点:
- containerd 2.0 是底线,1.7 节点必须提前升级
- cgroup v2 是默认,v1 节点要么升级 OS,要么配置逃生舱(但不推荐长期用)
- kubelet 标志不要再用手动设置,交给 CRI 自动检测
- DRA GPU 切片是 AI 基础设施的看点,但还在 Alpha,生产环境谨慎启用
距离 8 月 26 日正式发布还有 40 天。现在就开始检查你的节点,比升级当夜凌晨 3 点排查 kubelet 崩溃日志要舒服得多。
本文基于 Kubernetes v1.37.0-alpha.3 源码及官方 KEP 文档整理,所有命令和配置均经过验证。