在docker容器中启动服务失败,出现错误:无法获得D-Bus连接:没有连接到服务pipe理器
我安装了docker镜像并成功构build了一个镜像。
当我SSH容器并运行命令service xxx start
,一个错误popup:
服务nginfra开始
redirect到/ bin / systemctl启动nginfra.service / sbin / service:第79行:/ bin / systemctl:没有这样的文件或目录
实际上, fakesystemd
安装在容器中而不是systemd
。
所以我删除了fakesystemd
并安装了systemd
命令:yum swap – 删除fakesystemd – 安装systemd systemd-libs
但我仍然无法启动服务:
服务nginfra开始
redirect到/ bin / systemctl start nginfra.service获取D-Bus连接失败:没有连接到服务pipe理器。
有没有人遇到过这个问题?
这是Docker容器中基于systemd
的操作系统的已知问题 。
简短的回答:以及用systemd
replacefakesystemd
,你需要将/sys/fs/cgroup
作为只读卷添加到容器中,构build映像然后在“特权”模式下运行。
这是我find的最好的指南 。 它使用Centos作为例子,但应该与任何基于systemd
的操作系统一起工作。
我已经设法在CentOS:7 Docker容器中解决这个问题。 我主要关注CentOS Docker映像项目指南 。
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/*; # Install anything. The service you want to start must be a SystemD service. CMD ["/usr/sbin/init"]
现在,构build镜像,并使用docker run
命令至less运行以下参数: -v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro
那么要点就是/usr/sbin/init
必须是Docker容器中的第一个进程。
因此,如果要在运行/usr/sbin/init
之前使用执行某些命令的自定义脚本,请使用exec /usr/sbin/init
(在bash脚本中)在脚本末尾启动它。
这里是一个例子:
ADD cmd.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/cmd.sh CMD ["/usr/local/bin/cmd.sh"]
这里是cmd.sh
的内容:
#!/bin/bash # Do some stuffs exec /usr/sbin/init # To correctly start D-Bus thanks to https://forums.docker.com/t/any-simple-and-safe-way-to-start-services-on-centos7-systemd/5695/8
你可以让System is booting up. See pam_nologin(8)
如果使用PAM系统, System is booting up. See pam_nologin(8)
,在这种情况下,请删除Dockerfile
/usr/lib/tmpfiles.d/systemd-nologin.conf
,因为它会创build生成此特定错误的文件/var/run/nologin
。