无法获得D-Bus连接:不允许操作


29

我正在尝试使用Docker在我运行的CentOS映像上列出服务

systemctl list-units  

但我收到此错误消息:

Failed to get D-Bus connection: Operation not permitted

有什么建议可能是什么问题?


1
你没用sudo吗?
迈克尔·汉普顿

如果不需要,则不应使用systemd。尝试在CMD或RUN中启动应用程序,或者使用包装脚本启动该应用程序。
nelaaro

如果您需要systemd使用CentOS,请使用此图像: FROM centos/systemd
james.garriss

Answers:


24

我的猜测是您正在运行一个non-privileged容器。systemd需要CAP_SYS_ADMIN功能,但Docker会在非特权容器中删除该功能,以增加安全性。

systemd还要求RO可以访问容器内的cgroup文件系统。您可以添加–v /sys/fs/cgroup:/sys/fs/cgroup:ro

因此,以下是有关如何在Docker容器中使用systemd运行CentOS的一些步骤:

  1. 拉centos图像
  2. 设置一个如下所示的docker文件:
FROM centos
MAINTAINER "Yourname" <youremail@address.com>
ENV container docker
RUN yum -y update; yum clean all
RUN yum -y install systemd; yum clean all; \
(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"]
  1. 建立它- docker build --rm -t centos7-systemd - < mydockerfile
  2. 运行一个容器 docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. 您应该在容器中放入系统


挺整洁的!但是,至少我现在回来了。这是我记录的内容:[ INFO ] Update UTMP about System Boot/Shutdown is not active. [DEPEND] Dependency failed for Update UTMP about System Runlevel Changes. Job systemd-update-utmp-runlevel.service/start failed with result 'dependency'. [ OK ] Started Journal Service. [ OK ] Reached target System Initialization. [ OK ] Reached target Timers. [ OK ] Listening on D-Bus System Message Bus Socket.
Snowcrash

1
万一我不清楚!我仍然遇到错误Failed to get D-Bus connection: Operation not permitted
Snowcrash

您已经从我的答案中复制的Dockerfile中构建了自己的映像,并从该映像运行了一个容器,但是仍然会收到错误消息?
13dimitar'1

4
答对了!我正在运行容器/bin/bash以获取外壳。但是,这给了我前面提到的错误。当我/usr/sbin/init按照建议运行它,然后附加一个外壳时,一切运行顺利。显然,我缺少关于的细微差别/usr/sbin/init。这个答案值得一些实质性的批评。
Snowcrash

我已经呆了两天了,但我仍然不/sys/fs/cgroup:/sys/fs/cgroup知道它是什么或它来自哪里...我知道如何将来宾文件夹安装到hist这样:/src/:/var/www但是您的文件来自哪里?因为粘贴了代码,这导致了很多错误,我想应该在某个地方创建这些代码
samayo

4

这不是您问题的直接答案,但实际上可能更重要,在阅读其他答案时,我体会到了这一认识。

我有一些将一些复杂的系统迁移到Docker的经验,而我获得的重要认识之一是,理想情况下,每个应用程序/服务或“每个守护程序”都应该有一个Docker容器。

造成这种情况的一个非常重要的原因是,Docker不会彻底关闭以systemctl开头的服务,实际上,您可能会因意外停电而遭受同样的数据库损坏。

更深入地探讨这一点:当Docker向容器发出“停止”命令时,它仅向SIGTERM信号发送以CMD / ENTRYPOINT启动的单个进程,而不是向所有服务和守护程序发送。这样一来,该服务就会发出警告,要求您彻底关闭,而其他所有服务都将被正常终止。

如果您绝对必须将两个服务打包在同一个容器中(即您的应用程序和PostgreSQL数据库或类似的东西),则需要让CMD / ENTRYPOINT是捕获SIGTERM的脚本,然后将其重新广播到那些已知的服务。可以做到,但是如果有机会,请重新考虑解决方案,然后尝试将其分解为多个容器。

附录

如果您绝对需要在同一个容器中运行多个服务,则在Docker站点上有一个有趣的说明/页面关于使用超级用户


2

我已经设法在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"]

现在,构建映像,并至少使用以下docker run命令参数运行它:-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系统,在这种情况下,删除/usr/lib/tmpfiles.d/systemd-nologin.conf你的Dockerfile,因为它创建的文件/var/run/nologin生成此特定错误。


systemd-nologin.conf/ nologin获胜,因为CentOS / RHEL 7声明UsePAM no不受支持,因此会在日志中抱怨。不知道RH openssh便携式修补程序是否被打碎/以某种方式破坏了它,或者他们正试图降低新手客户的支持面。

1

我不想以init / PID 1的身份启动systemd。完成其他人提到的清理步骤后,我从启动脚本中以方式启动systemd /usr/lib/systemd/systemd --system &

这允许systemd启动和启动注册的服务,但是systemctl失败,并出现D-Bus错误。

对我来说,缺少的链接是缺少/ run / systemd / system目录,这是strace通过systemctl 发现的。

在运行systemctl之前手动创建此目录使systemctl可以为我工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.