我正在尝试使用Docker在我运行的CentOS映像上列出服务
systemctl list-units
但我收到此错误消息:
Failed to get D-Bus connection: Operation not permitted
有什么建议可能是什么问题?
systemd
使用CentOS,请使用此图像: FROM centos/systemd
我正在尝试使用Docker在我运行的CentOS映像上列出服务
systemctl list-units
但我收到此错误消息:
Failed to get D-Bus connection: Operation not permitted
有什么建议可能是什么问题?
systemd
使用CentOS,请使用此图像: FROM centos/systemd
Answers:
我的猜测是您正在运行一个non-privileged
容器。systemd需要CAP_SYS_ADMIN功能,但Docker会在非特权容器中删除该功能,以增加安全性。
systemd还要求RO可以访问容器内的cgroup文件系统。您可以添加–v /sys/fs/cgroup:/sys/fs/cgroup:ro
因此,以下是有关如何在Docker容器中使用systemd运行CentOS的一些步骤:
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"]
docker build --rm -t centos7-systemd - < mydockerfile
运行一个容器 docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init
您应该在容器中放入系统
[ 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.
Failed to get D-Bus connection: Operation not permitted
/bin/bash
以获取外壳。但是,这给了我前面提到的错误。当我/usr/sbin/init
按照建议运行它,然后附加一个外壳时,一切运行顺利。显然,我缺少关于的细微差别/usr/sbin/init
。这个答案值得一些实质性的批评。
/sys/fs/cgroup:/sys/fs/cgroup
知道它是什么或它来自哪里...我知道如何将来宾文件夹安装到hist这样:/src/:/var/www
但是您的文件来自哪里?因为粘贴了代码,这导致了很多错误,我想应该在某个地方创建这些代码
这不是您问题的直接答案,但实际上可能更重要,在阅读其他答案时,我体会到了这一认识。
我有一些将一些复杂的系统迁移到Docker的经验,而我获得的重要认识之一是,理想情况下,每个应用程序/服务或“每个守护程序”都应该有一个Docker容器。
造成这种情况的一个非常重要的原因是,Docker不会彻底关闭以systemctl开头的服务,实际上,您可能会因意外停电而遭受同样的数据库损坏。
更深入地探讨这一点:当Docker向容器发出“停止”命令时,它仅向SIGTERM信号发送以CMD / ENTRYPOINT启动的单个进程,而不是向所有服务和守护程序发送。这样一来,该服务就会发出警告,要求您彻底关闭,而其他所有服务都将被正常终止。
如果您绝对必须将两个服务打包在同一个容器中(即您的应用程序和PostgreSQL数据库或类似的东西),则需要让CMD / ENTRYPOINT是捕获SIGTERM的脚本,然后将其重新广播到那些已知的服务。可以做到,但是如果有机会,请重新考虑解决方案,然后尝试将其分解为多个容器。
如果您绝对需要在同一个容器中运行多个服务,则在Docker站点上有一个有趣的说明/页面关于使用超级用户。
我已经设法在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
生成此特定错误。
我不想以init / PID 1的身份启动systemd。完成其他人提到的清理步骤后,我从启动脚本中以方式启动systemd /usr/lib/systemd/systemd --system &
。
这允许systemd启动和启动注册的服务,但是systemctl失败,并出现D-Bus错误。
对我来说,缺少的链接是缺少/ run / systemd / system目录,这是strace
通过systemctl 发现的。
在运行systemctl之前手动创建此目录使systemctl可以为我工作。
sudo
吗?