-
问题重现
最近公司产品业务需求,需要对一个需要用到Linux内核的引擎进行容器化封装,并部署在ubuntu22.04的服务器环境上。
由于引擎只能在centos7上部署,因此docker容器化的基础镜像,我选择的也是centos:centos7。然后我就在自己的测试服务器(宿主机也为centos7)上完成容器化测试后,打包移植到ubuntu22.04上,想要启动容器时,发现内部报错
一开始,我以为是容器特权(privileged)或者或者cgroup目录挂载的问题,但是用以下指令启动也同样报错:
docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup --privileged=true --name test centos:centos7 /usr/sbin/init
报错内容一直是以下类似的问题:
Failed to allocate manager object: No such file or directory[!!!!!!]
Failed to allocate manager obj
-
问题原因
于是,我在云平台上租了个云服务器,开始各种实验,废话不多说,直接上结果:
-
宿主机centos7,docker 18.03:可运行
-
宿主机centos7,docker 20.10:可运行
-
宿主机ubuntu18.04,docker 20.10:可运行
-
宿主机ubuntu20.04,docker 20.10:可运行
-
宿主机ubuntu22.04,docker20.10:无法正常运行
看到这里,我相信聪明的小伙伴肯定觉察到问题出在哪里了。不错,正是ubuntu版本的问题所导致的。这边贴上几个社区和github的讨论链接:
[Solved: Not a bug] Strange cgroups bug(?) on Ubuntu 21.10 - LXD - Linux Containers Forum
看了这些之后,再深入分析一下,会发现ubuntu自21.04版本后的版本(不包含21.04)linux内核改用了cgroup v2版本,而容器镜像环境(centos7)需要的还是cgroup v1版本且centos7由于几乎不更新维护,因此后续小概率会支持cgroup v2。同时由于cgroup v2和v1不能兼容,因此导致容器启动后,内置的病毒沙箱引擎和相关服务无法正常启动。
(ps.cgroup是Linux内核允许将流程组织为分层的功能,然后可以限制其使用各种类型资源的组并进行监控。)
-
解决方案
那既然知道了问题出在哪里,那就对症下药。既然docker容器只支持cgroup v1版本,那么我们就把宿主机(host)的cgroup版本改成v1就行了。修改方式如下:
在/etc/default/grub文件中,GRUB_CMDLINE_LINUX参数中添加 systemd.unified_cgroup_hierarchy=0,如下图所示:
(ps,如果值为1,就是cgroup v2)
然后更新grub,重启:
sudo update-grub
sudo reboot
重启后,重新部署docker容器,服务可正常运行。
-
小结
其实,在排查问题过程中,会发现很多人不建议docker直接挂载cgroup目录,因为docker设计的初衷就是避免后台服务运行。但是有时候在实际工作学习中,会碰到很多特殊的情况,此时也就只能特殊处理。