为什么你的K8s集群必须用systemd而不是cgroupfs?
搭建Kubernetes集群时,不管你是看新手教程还是生产环境部署文档,总能看到这么一步:修改containerd配置,把SystemdCgroup = false改成true。
很多人照做了,但未必明白为什么。有些人甚至觉得不改也能启动集群,抱着侥幸心理跳过了这步。等到集群跑起来,各种稀奇古怪的故障接二连三出现,排查起来让人摸不着头脑。今天咱们就聊聊这背后的逻辑,说清楚为什么K8S配合containerd必须把cgroup驱动换成systemd。
资源管理的根基
Kubernetes的核心功能之一就是对资源进行精细化管理。无论是限制Pod的CPU和内存用量、实现资源隔离、控制OOM,还是Pod驱逐、HPA自动扩缩容,这些功能的底层支撑都离不开Linux cgroup。
cgroup全称Control Groups,是Linux内核提供的一种进程资源管控机制。它能精确限制、统计和隔离进程对CPU、内存、IO等系统资源的使用。容器本质上就是“进程+namespace+cgroup”,所以容器的资源管控完全依赖cgroup,这也让cgroup成了K8S资源管理体系的基石。
现代Linux系统(比如CentOS 7、Ubuntu 16.04及更高版本)中,cgroup主要由systemd接管,而且普遍采用cgroup v2统一层级。systemd成了整个系统cgroup树的唯一管理者。你可以通过下面这个命令来确认:
mount | grep cgroup
如果看到这样的输出:
cgroup2 on /sys/fs/cgroup type cgroup2
那就说明系统确实由systemd主导cgroup管理。

containerd的默认配置
问题出在containerd的默认设置上。作为K8S的主流容器运行时,containerd默认把SystemdCgroup设成了false。这意味着它不会通过systemd创建和管理cgroup,而是自己在/sys/fs/cgroup目录下新建文件夹,独立管理容器的cgroup。
这么一来,系统里就有了两套cgroup管理者:一边是systemd,负责管理系统进程和kubelet的cgroup;另一边是containerd,自己管着容器的cgroup。这两套体系互不沟通,各管各的,结果就是K8S的资源管理体系彻底失效。
不改驱动的后果
有些人觉得“不改驱动集群也能起来”,但这种侥幸心理往往会埋下隐患。下面这几种故障,基本都是驱动不匹配引起的:
1. 资源限制失效:就算给Pod设了内存、CPU限制,服务器资源还是会被打满,因为containerd创建的容器cgroup不受kubelet管控;
2. 节点频繁OOM:系统内存溢出会杀掉进程,但K8S完全感知不到,因为systemd统计不到containerd自建cgroup的资源数据;
3. 监控数据不准:metrics-server采集的CPU、内存使用率会有偏差,导致集群调度失去依据;
4. Pod驱逐机制失灵:节点资源不足时,K8S的Eviction Manager无法触发驱逐,集群稳定性大打折扣;
5. kubelet日志报错:经常看到“failed to find cgroup”、“cgroup driver mismatch”这类驱动不匹配的错误信息。
有人可能会问:为什么以前用Docker的时候很少遇到这个问题?其实很简单,Docker从1.12版本开始就默认使用systemd cgroup驱动了,kubelet和Docker的驱动保持一致,自然不会有冲突。而containerd保留了cgroupfs作为默认配置,这也是K8S切换容器运行时后,这个问题集中爆发的主要原因。
正确修改驱动
Kubernetes官方对此有明确要求:kubelet和容器运行时必须使用相同的cgroup驱动。在现代Linux系统中,官方唯一推荐的就是systemd驱动。
把SystemdCgroup改成true,本质上是让containerd的cgroup纳入systemd的统一管理,确保驱动一致,这样K8S的资源管控、监控、调度等核心功能才能正常运作。
具体操作很简单,三步就能搞定:
1. 执行containerd config default > /etc/containerd/config.toml,生成默认配置文件;
2. 编辑配置文件,找到SystemdCgroup配置项,把值从false改成true;
3. 重启containerd服务(systemctl restart containerd),让配置生效。

写在最后
cgroup驱动不匹配,算是K8S部署里一个挺隐蔽的底层“坑”——它不会阻止集群启动,却会在运行过程中引发各种看似无规律的故障,严重影响生产环境的稳定性。做运维不能只停留在“照着做”的层面,理解背后的原理,才能真正规避风险、高效排查问题。
按照官方规范,把containerd的cgroup驱动改成systemd,看似只是改了一行配置,实际上是保障K8S集群稳定运行的基础操作。这也是每个K8S运维都应该掌握的核心知识点。欢迎关注我的小绿书《老卢聊运维》
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)