我问这个问题 我认为 systemd-udev-trigger 不应该在 docker 容器中执行,无论它是什么 --privileged 或不是。
是否有一些场景必须需要在docker容器中执行systemd-udev-trigger?
答案1
第一个也是最不具体的答案是 systemd-udev 并不是设计来在容器内运行的。 Docker 并不打算在其中运行 systemd,而只是运行一个守护进程。
您提到的容器映像确实有运行 systemd 的说明。它们涉及删除将在非特权容器内运行的 udev 服务。这在 Docker 容器内有效,因为在构建过程之后您永远不应该使用包管理器。
在特权容器中,我认为这些指令也应该足以禁用 udev。在我的 Fedora 26 系统上,这是静态的sysinit.target
.请注意代码如何删除sysinit.target
除 之外的所有静态需求systemd-tmpfiles-setup.service
。
系统集成
Systemd 现在包含在 centos:7 和 centos:latest 基础容器中,但默认情况下它不处于活动状态。为了使用 systemd,您需要包含类似于下面示例 Dockerfile 的文本:
systemd 基础镜像的 Dockerfile
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 删除了许多可能导致问题的单元文件。从这里开始,您就可以构建基础映像了。
console $ docker build --rm -t local/c7-systemd .
启用 systemd 的应用程序容器示例
为了使用上面创建的启用 systemd 的基本容器,您需要创建
Dockerfile
类似于下面的容器。
dockerfile FROM local/c7-systemd RUN yum -y install httpd; yum clean all; systemctl enable httpd.service EXPOSE 80 CMD ["/usr/sbin/init"]
构建这个图像:
console $ docker build --rm -t local/c7-systemd-httpd .
运行启用 systemd 的应用程序容器
为了使用 systemd 运行容器,您需要从主机挂载 cgroups 卷。下面是一个示例命令,它将运行之前创建的启用了 systemd 的 httpd 容器。
console $ docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd
该容器在有限的上下文中使用 systemd 运行,并安装了 cgroups 文件系统。有报告称,如果您使用的是 Ubuntu 主机,则
-v /tmp/$(mktemp -d):/run
除了 cgroups 之外还需要添加安装。