Kubernetes 中 cgroup v1 到 v2 的迁移

Kubernetes 中 cgroup v1 到 v2 的迁移

在不断发展的 Kubernetes 容器编排领域,变化是常态。其中一项最重要的变革就是从 cgroup v1 过渡到 cgroup v2。如果您正在管理 Kubernetes 集群,这不仅仅是一个技术细节,而是一项影响资源管理、安全性和整体性能的根本性变革。

Kubernetes 1.35 带来了一个不小的变化:kubelet 默认拒绝在 cgroup v1 节点上启动。这可不是简单的功能弃用,而是整个 Linux 生态在资源管理架构上的一次集体转向。

生态系统的连锁反应

这次变化特殊在哪?它不是某个项目的孤立决定,而是整个生态在同步行动:

  • systemd v256 开始默认拒绝 cgroup v1,v258 会完全移除支持。
  • RHEL 9.4 废弃 cgroup v1,RHEL 10 只支持 v2。
  • Fedora 的时间表更激进:41/42 版本默认不启动 v1,43 会完全移除。
  • Ubuntu 22.04 LTS 及更高版本默认使用 cgroup v2。
  • Debian Trixie 使用 systemd 257,默认不支持 v1。

这种同步性背后有技术原因。cgroup v1 的混合层级架构在设计上就存在复杂性问题:每个资源控制器(CPU、内存、IO)都有独立的层级树,同一个进程在不同控制器中可能处于不同位置。这种设计在容器密度增加、资源管理需求变复杂后,维护成本越来越高。

cgroup v2 的统一层级架构从根本上解决了这个问题。所有资源控制器在同一个层级树中管理,进程在所有控制器中的位置一致。这不仅简化了管理,还让内核能做更多优化。systemd 作为现代 Linux 发行版的核心组件,与 cgroup 紧密集成,它的转向直接影响了整个生态。

坑一 应用兼容性的问题

Java 应用就是个典型例子。OpenJDK 早期版本对 cgroup v2 支持不完整,得用 8u372、11.0.16 或 15+ 版本才能正确识别资源限制。要是集群里跑着老版本 Java 应用,直接切到 cgroup v2 可能导致容器内存限制失效。

Node.js 的情况类似,需要 20.3.0+ 版本。

这些版本要求看起来不高,但实际环境中,很多应用因为各种原因(依赖兼容性、测试成本、业务优先级)一直在用老版本。

监控和安全 Agent 也是个问题。很多 Agent 直接读取 cgroup 文件系统来获取容器资源使用情况,cgroup v1 和 v2 的文件路径和格式完全不同。如果 Agent 没有更新,切换后监控数据会丢失或错误。

坑二 kubelet 直接起不来

从 1.35 开始,kubelet 配置里有个参数叫 FailCgroupV1,默认值是 true。这意味着只要检测到节点是 cgroup v1,kubelet 就拒绝启动。你可能想说:”那我把这个参数改成 false 不就行了?”技术上可以,但这是饮鸩止渴。官方明确说了,这个参数只是给你一个过渡期,到 1.38 版本连这个参数都没了,cgroup v1 的代码会被彻底删除。你现在不迁移,以后还是要迁移,而且时间更紧迫。

迁移指南

步骤 1:检查当前 cgroup 版本

检查cgroup版本

# 检查挂载的 cgroup 版本mount | grep cgroup
## 对于 cgroup v1,您会看到多个挂载,如:
## cgroup on /sys/fs/cgroup/cpu type cgroup (...)
## cgroup on /sys/fs/cgroup/memory type cgroup (...)
# 对于 cgroup v2,您会看到单一的统一挂载:
## cgroup2 on /sys/fs/cgroup type cgroup2 (...)
# 或检查文件系统类型stat -fc %T /sys/fs/cgroup/
## cgroup2fs 表示 v2,tmpfs 表示 v1

图片[1]-Kubernetes 中 cgroup v1 到 v2 的迁移-废柴阿尤 の 博客

步骤 2:验证 Linux 发行版支持

发行版 默认启用 cgroup v2 的版本
Debian 11
openSUSE 15.6及以后、Tumbleweed
Fedora  
Ubuntu 21.10
RHEL 9

步骤 3:升级容器运行时依赖

迁移到 cgroup v2 时,Kubernetes 建议升级您的容器运行时依赖:

  • runc 升级到 1.3.2 或更高版本
  • crun 升级到 1.23 或更高版本

步骤 4:启用 cgroup v2

如果您的系统未启用 cgroup v2,使用以下方式开启

方式一:基于 GRUB 的系统(推荐)

# 编辑 /etc/default/grub
GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"
# 更新 GRUB
sudo update-grub  # Debian/Ubuntu
# 或
sudo grub2-mkconfig -o /boot/grub2/grub.cfg  # RHEL/CentOS

方式二:内核启动参数中添加以下内容

systemd.unified_cgroup_hierarchy=1

步骤 5:验证 Kubernetes 兼容性

确保您的 Kubernetes 组件兼容:

  • kubelet 必须配置为使用 cgroup v2
  • 容器运行时(containerd、CRI-O)必须支持 cgroup v2
  • 所有节点组件应更新到兼容版本

总之一句话

cgroup v2 让 Kubernetes 的资源模型更一致、更可靠、更可观测,也更容易与现代 Linux 内核和容器生态对齐。

参考

© 版权声明
THE END
喜欢就支持一下吧
点赞6赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容