在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的操作系统的已知问题 。

简短的回答:以及用systemdreplacefakesystemd ,你需要将/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