我在Docker容器中搭建了一个可以使用Systemd的CentOS
首先
CentOS容器默认情况下不能使用Systemd,但在DockerHub的页面上有记录如何启用Systemd的方法,我尝试了一下。
执行环境
操作系统:MacOS Monterey 12.4
Docker:Docker版本20.10.14
Docker桌面版(适用于Mac):版本4.7.1
Docker镜像:CentOS 7
获取CentOS7的Docker镜像
% docker pull centos:7
创建基于Systemd的映像
创建Dockerfile
因为在DockerHub页面上有示例,所以我们可以参考它们来创建Dockerfile。
% vim ~/workspace/docker/centos/systemd-base/Dockerfile
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
构建图像
根据 Dockerfile 构建镜像。
% docker build --rm -t centos-systemd ~/workspace/docker/centos/systemd-base/
[+] Building 0.1s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.0s
=> [1/2] FROM docker.io/library/centos:7 0.0s
=> CACHED [2/2] RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:ddbe5f1f9b13355b0558d857948f089860b0e4393ec6a40b9 0.0s
=> => naming to docker.io/library/centos-systemd 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
在构建完之后,可以使用docker命令来查看镜像列表。
% docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-systemd latest ddbe5f1f9b13 2 days ago 204MB
centos 7 eeb6ee3f44bd 8 months ago 204MB
启动容器
1. 第一次尝试失败了
参考DockerHub页面,使用以下命令启动容器。
% docker run --name centos-systemd-container -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -d centos-systemd
f27733e900c6cc99ed9aa3e046c72773cf87cef580b8b8c27d5610d39b35e4f6
我将在已启动的容器中尝试运行Systemd以进行确认。
sh-4.2# systemctl list-units --type=service
Failed to get D-Bus connection: Operation not permitted
似乎没有权限获取D-Bus连接。
在 Docker 文档中查找权限相关信息,发现 Docker 容器在默认情况下缺乏权限,无法连接到设备,因此需要将其设置为特权容器。
因此,我们将尝试使用”privileged”选项作为特权容器来启动。
失败2
% docker run --name centos-systemd-container --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -d centos-systemd
e3de98766ea9b4a181eb9fde99040c0093514e25bb0e72f55bd412717b2e8422
sh-4.2# systemctl list-units --type=service
Failed to get D-Bus connection: No such file or directory
这次好像找不到文件目录,所以失败了。在搜索消息时,我找到了这个页面。
由于Docker Desktop开始使用cgroupv2,所以systemd也需要支持cgroupv2,至少需要systemd247以上的版本。
我会确认一下自己的环境。
sh-4.2# journalctl --version
systemd 219
+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN
版本不够,请参考同一页面中的信息,看看是否有使用cgroupv1参数来使用DockerDesktop的选项。我将尝试进行设置。
设置文件位于~/Library/Group Containers/group.com.docker/settings.json。
"deprecatedCgroupv1": true, // trueに変更します
更改了settings.json后,请重新启动并再次尝试。
取决于个人的定义和努力水平。
sh-4.2# systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
systemd-journald.service loaded active running Journal Service
systemd-tmpfiles-setup.service loaded active exited Create Volatile Files and D
ir
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
2 loaded units listed. Pass --all to see loaded but inactive units, too
.
To show all installed unit files use 'systemctl list-unit-files'.
没问题,现在systemctl命令开始有响应了。
文献引用