systemctl无法连接到总线 - docker ubuntu:16.04容器

我正在尝试在一个 ubuntu:16.04 的 Docker 容器中使用 systemctl 命令。我正在运行以下命令...
systemctl status ssh

然而,我遇到了一个错误...
Failed to connect to bus: No such file or directory

为什么这个不工作?这与在 Docker 容器中运行的 Ubuntu 有关吗?我如何使 systemctl 正确工作?

6使用service ssh start - Bidyut
3对于那些在使用 sudo systemctl --user 时遇到相同问题的人...只需移除 sudo 即可! - 56ka
天啊,我把systemctl设置成了sudo systemctl --no-pager的别名。谢谢你的建议。 - Paul
8个回答

我假设你是通过类似以下方式启动 Docker 容器的
docker run -t -i ubuntu:16.04 /bin/bash

现在的问题是你的init进程PID 1是/bin/bash,而不是systemd。 用ps aux确认一下。
除此之外,你还缺少dbus,这是通信的方式。你的错误信息就是来自这里。但由于你的PID 1不是systemd,安装dbus也无济于事。
最好重新考虑一下你计划使用docker的方式。不要依赖systemd作为进程管理器,而是让docker容器在前台运行你想要的应用程序。

像openssh-server这样的服务被配置为记录到默认的syslog设施。我如何在不依赖systemctl的情况下获取sshd日志? - Parth Shah
@ParthShah 请查看sshd man页面。我的选项如下:通过使用-D参数,您可以将其保持在前台运行。使用-e参数可以直接打印日志。然后可以使用“docker log”以Docker的方式进行检查。 - user228505
[知情] 在 /sbin/init 进程中出现了 PID=1 的错误。根据 @sonjaya sonjaya 的建议,添加 --privileged=true 解决了这个问题。 - DimG
漂亮的答案!! - Sachin Verma

其他人也报告了类似的问题。启动终端并输入以下命令:
$ env

你有看到像这样的环境变量吗?
XDG_RUNTIME_DIR=/run/user/`id -u`

在反引号而不是单引号中括起来的地方,id -u 表示一个变量。这个变量通常被重新解释为一个数字,对于普通用户来说是 1000,对于超级用户(sudo)来说是 0

如果环境变量 XDG_RUNTIME_DIR 不存在,则需要创建它。完整的讨论在launchpad systemd answers中。


2我尝试了但没有成功。由于我的Ubuntu 16.04实例是一个Docker容器,并且我没有设置任何用户,所以我以root身份工作,因此我使用了变量XDG_RUNTIME_DIR=/run/root/0,但没有成功。然后我检查了文件夹/run,发现没有子文件夹/run/root。有没有办法可以获得更详细的错误信息?我查看了systemctl --help,但没有找到获取详细错误消息的方法。 - Duncan Gravill
1我遇到了同样的问题,这个方法也没有解决我的问题。你最后解决了这个问题吗 @DuncanGravill - Roeland
3@Roeland 是的。我在 Stack Overflow 上提出了一个类似的问题,得到了更强烈的回应。我还推荐观看 Docker 网站上的自学教程。在那些视频中,稍微模糊地解释了在 Docker 容器中如何用容器的入口点替换通常为 systemdPID 1 - Duncan Gravill
太棒了,谢谢!我需要这个来启动/管理一个用户单元从一个系统单元。 - Adrian Günter
@DuncanGravill 那是因为目录应该是 /run/user/0 而不是 /run/root/0 - am70

只需启动dbus服务即可:
/etc/init.d/dbus start

1我正在构建一个定制的容器解决方案,遇到了一个问题,即pihole无法安装,因为它抱怨没有使用systemd作为init系统。手动启动dbus解决了这个问题 :) - Tox

如果您在Windows子系统中遇到此错误(WSL),我发现这是因为不支持Docker。这是由于缺乏cgroups和其他先决条件所致。

试试这个:

docker run -ti -d --privileged=true images_docker  "/sbin/init"

或者

docker run -ti -d --privileged=true images_docker

结果将会是一样的。

这里是我从 Docker文档中获取的:

默认情况下,Docker容器是“非特权”的,不能在Docker容器内部运行Docker守护程序。这是因为默认情况下,容器不被允许访问任何设备,但是“特权”容器被赋予对所有设备的访问权限(请参阅cgroups设备的文档)。

当操作员执行docker run --privileged命令时,Docker将允许访问主机上的所有设备,并在AppArmor或SELinux中设置一些配置,以使容器几乎具有与主机上运行在容器外部的进程相同的访问权限。关于使用--privileged运行的其他信息,请参阅Docker博客。


2你能解释一下你的命令以及与已接受的问题之间的区别吗? - Melebius
欢迎来到AskUbuntu!感谢您的帮助尝试!对文档进行了快速检查后,我认为您在这个命令中可能出错了一两处。如果您能友善地[编辑]它,并解释您在做什么以及如何解决问题,请@我,我将回来给您点赞! - Elder Geek
当你说 "images_docker" 时,你是指纯净的 ubuntu:16.04 吗?还是其他的东西? - Parth Shah

我之前也遇到了完全相同的错误,然后我使用sudo成功地运行了它。
sudo systemctl status ssh

1你不需要使用 sudo。这似乎是巧合。请再次测试一下? - Zanna
2@Zanna saif@sr-server:~$ systemctl status ssh 无法连接到总线:没有这样的文件或目录 saif@sr-server:~$ sudo systemctl status ssh [sudo] saif 的密码: ● ssh.service - OpenBSD 安全 Shell 服务器 已加载:/lib/systemd/system/ssh.service;启用;供应商预设:已启用 活动状态:自从 2018-01-19 23:38:14 PKT 运行中;4 分钟 4 秒前 主 PID:18222 (sshd) 任务数:15 内存:32.7M CPU:488ms - Saif
为什么是-1?我只是发表了对我有效的内容。 - Saif
不是我点的踩... - Zanna
1问题是关于在ubuntu:16.04的Docker容器中运行systemctl status ssh命令。默认情况下,该容器中没有安装SSH。在Docker容器中运行这些命令时,不需要使用sudo。权限管理的正常最佳实践在Docker容器和普通操作系统之间有所不同。我假设你的回答是针对普通的Ubuntu安装。 - Dan

你可能没有运行systemd,这是16.04上默认的init实现。如果你从14.04升级过来,很可能仍在运行upstart,并且运行systemctl命令的结果就是你得到的输出。
更多信息请参考我的回答systemctl : comand not found 16.04 server

但这是一个Ubuntu容器,默认情况下没有systemd,也不会有upstart。 - Stefan Lasiewski
什么?Ubuntu默认使用systemd。 - knocte
1斯特凡:我相信你在Docker的情况下是正确的。 - Hugh Buntu
我的评论涵盖了从14.04(Upstart)升级到16.04(systemd)的情况。在进行版本升级时,出于可理解的原因(如:不破坏系统),Upstart 不会被 systemd 替换。回顾起来,我意识到发行版升级过程在 Docker 中不会被使用。请看我提到的链接。我注意到有一些答案和评论没有考虑到 Docker 的特定情况,以后我在回答问题时会考虑这一点。 - Hugh Buntu

在Docker容器内,如果你仍然与systemd有困扰,我认为你可以使用update-rc.d来进行更新。我尝试了update-rd.c并且它有效。

这是为了 System V 而不是 systemd。 - Efren