Sno*_*ash 56 centos systemd systemctl docker
我正在尝试使用在 Docker 中运行的 CentOS 映像列出服务
systemctl list-units
Run Code Online (Sandbox Code Playgroud)
但我收到此错误消息:
Failed to get D-Bus connection: Operation not permitted
Run Code Online (Sandbox Code Playgroud)
任何建议可能是什么问题?
13d*_*tar 43
我的猜测是您正在运行一个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"]
Run Code Online (Sandbox Code Playgroud)
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
您应该在容器中安装 systemd
Mur*_*ams 13
这不是您问题的直接答案,但实际上可能更重要,我在阅读此处的其他答案时发现了这一点。
我有一些将一些复杂系统迁移到 Docker 的经验,我的一个重要认识是,理想情况下,每个应用程序/服务或“每个守护程序”应该有一个 Docker 容器。
一个非常重要的原因是Docker 不会干净地关闭您使用 systemctl 启动的服务,事实上,您最终可能会因意外断电而导致相同类型的数据库损坏。
更深入地研究一下:当 Docker 向容器发出“停止”命令时,它仅向使用 CMD/ENTRYPOINT 启动的单个进程发送 SIGTERM 信号,而不是向所有服务和守护进程发送。这样,一项服务就会得到彻底关闭的警告,而所有其他服务都会被毫不客气地终止。
如果你绝对必须在同一个容器中打包两个服务(即你的应用程序和一个 PostgreSQL 数据库或类似的东西),那么你需要让你的 CMD/ENTRYPOINT 是一个捕获 SIGTERM 然后将它重新广播到那些已知服务的脚本。这是可以做到的,但如果有机会,请重新考虑您的解决方案并尝试将其分解为多个容器。
如果您绝对需要在同一个容器中运行多个服务,Docker 站点上有一个关于使用 supervisord的有趣注释/页面。
我已经在 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"]
Run Code Online (Sandbox Code Playgroud)
现在,构建映像,并至少使用以下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"]
Run Code Online (Sandbox Code Playgroud)
这是内容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
Run Code Online (Sandbox Code Playgroud)
你可以有System is booting up. See pam_nologin(8),如果您使用PAM系统,在这种情况下,删除/usr/lib/tmpfiles.d/systemd-nologin.conf你的Dockerfile,因为它创建的文件/var/run/nologin生成此特定错误。
| 归档时间: |
|
| 查看次数: |
153264 次 |
| 最近记录: |