在 docker 镜像中增加了 systemd 的功能,一直没啥问题,最近在 ubuntu 22.04 LTS 中出现了问题,
在 docker 容器中运行 systemctl ,显示Failed to get D-Bus connection: No such file or directory
,而在 ubuntu 20.0 4LTS 中就正常。镜像系统是 centos 7.9.
不知道该从哪入手去找原因,哪位有相关的经验提示一下。现在只能想办法把 systemctl 去掉,但是这个成本比较高。
1
vincentWdp 2 天前
我只能建议你把问题描述丢给 deepseek R1
|
2
Chaidu 2 天前 ![]() 遇到技术问题就去问 AI 。论坛是吹牛逼的地方,你想把论坛当 AI 用?
|
3
snowfuck 1 天前
镜像中增加 systemd 听上去有点奇怪啊, 作用是什么? "Failed to get D-Bus connection: No such file or directory" 看上去像是 systemctl 跟 systemd daemon 之类的东西无法通信. 容器内一般不用进程管理器了, 一个进程一个容器由外面的 docker 来管理, 自动重启什么的就行.
|
4
w568w 1 天前 ![]() 我说几点:
1. 首先,Docker 是应用容器( Application Container ),应用容器的设计理念就是「一个容器 = 一个应用主进程」。如果你需要在容器里塞很多平行的进程,那么已经在逆设计理念硬用了。等于是反天道而行,有问题是自然的。所以要么 (1) 拆分应用成多容器,用 TCP 交流;(2) 换成系统容器( System Container ),比如 LXD ; 2. 抛开第一点不谈,如果你只是要编排任务,也不应该让本来用来管理系统资源和内核的 systemd 硬上(虽然它确实有编排服务的功能,但它还有很多别的职能啊),你需要的是「 systemctl 独立绿色版」,我推荐 Supervisord: https://supervisord.org/ 。 |
5
w568w 1 天前
@w568w #4 补充一下:
3. 既然楼主没说清楚为什么要用 systemctl ,我再预判一下楼主的实际问题:是不是有应用文档里只教了怎么用 systemctl 启动,所以离了 systemctl 就不知道怎么启了? 如果是这样,我建议仔细学一下 systemd.service 的工作方式,去掉这东西的成本可能没你想得那么高。 |
![]() |
6
superhot 1 天前
@w568w 请教一下,如果是 dev container 的话,一个 dev container 同时启动后端服务与 PostgreSQL 如何?还是说依然需要用 docker compose 的形式?
|
![]() |
7
sagaxu 1 天前
如果非要多个服务塞同一个容器,不要用很依赖系统的 systemd ,用 openrc 或 supervisor
|
8
w568w 1 天前
@superhot #6 生产和开发是不一样的,因为不用考虑服务启停状态这些东西,dev container 里你怎么折腾都可以,怎么方便怎么来。上面说的这些只适用于生产部署。
|
![]() |
9
memorycancel 1 天前
@superhot 把数据库和 app 都装进一个容器里当然可以,你试试就知道了,不要照本宣科。
没太看懂楼主的问题,如果容器的基础镜像用的是 ubuntu ,那默认就是 systemd 在管理进程啊,当然 init.d 也能用。 另外 centos 7.9 也是用的 systemd 吧?没记错的话 |
10
yanqiyu 1 天前
就先检查是不是真的拉起来了 systemd ,以及 dbus.socket/service 有没有跑起来(文件位置和进程)
|
![]() |
11
Nitroethane 1 天前
systemd 默认在容器里跑不了啊,再说了 systemd 这么臃肿的玩意儿就不是在容器里用的
|
12
yanqiyu 1 天前
@Nitroethane 其实能跑,只是容器运行时要给点额外的处理(挂载一些需要的文件系统),容器管理器可能自动做了这些事情
比如 podman 的 https://docs.podman.io/en/v5.1.1/markdown/podman-run.1.html#systemd-true-false-always 甚至还有 registry.access.redhat.com/ubi9-init:latest 这种镜像就用来跑 systemd 不过我的电脑上 centos7 的容器是跑不了的,因为老的 systemd 要求 cgroupv1... |
13
zbinlin 1 天前
与 root 权限有关?
|
14
feedcode 1 天前
1. Dockerfile entrypoint PID 1 需要是 systemd 或者 init
/sbin/init -> /lib/systemd/systemd 2. Host 如果是 cgroupv1 可以 bind mount -v /sys/fs/cgroup:/sys/fs/cgroup 如果是 v2 的话要 --cap-add SYS_ADMIN, 然后 systemd 会自己 mount cgroup fs, sample docker run -d --name test1 --tmpfs /run --tmpfs /tmp --cap-add SYS_ADMIN image |
![]() |
15
my3157 1 天前
很早之前这么跑过, 要挂一堆 hostfs 进去, 上面已经有人给了参考链接, 另外镜像也要装很多东西, 而且 systemd 很多包的安装脚本没考虑在容器里面, 安装时候也有不小的问题, 总之一句话, 能跑但不建议, 会有奇奇怪怪的问题, 尤其是版本升级之类的时候, 如果是跑单进程, 建议找个 dockerfile 参考一下在容器里面怎么跑, 如果是多进程, 优先考虑 compose 之类的多容器方案, 其次是单容器多进程的 tinit/supervisor 这种方案
|
![]() |
16
defunct9 1 天前 via iPhone
放 systemd 进去根本不是最佳实践,必须去掉
|
![]() |
17
Ipsum 1 天前
Docker 直接 entrypoint 运行就是,套 systemd 是个傻情况?
|
![]() |
18
palytoxin 1 天前
之前遇到一次这种情况是 CentOS user ,用 root 才行,的确是 DBus socket 连不上
|
![]() |
19
catamaran OP @yanqiyu #10 没拉起来,拉起来后会有一个/usr/lib/systemd/systemd-journald 进程,我尝试手动运行,没反应。github 上有个 python 版的 systemctl ,我准备替换一下试试。
|
21
julyclyde 1 天前
理论上不应该“一直没啥问题”的啊
你看看你容器里 systemd 依赖的 dbus.service 和 dbus.socket 到底启动了没 在前后两个环境里分别看一下 |
![]() |
22
guanzhangzhang 1 天前
你的 n 个进程不会互相之间调用 systemctl 拉起其他服务和做其他服务健康检查吧,是的话写个 shell 或者轮子把 docker.sock 挂载进去伪装成 systemctl 的输出
|
23
Maxwellwenjie 1 天前
我好像遇到过 Dbus 报错,不知道是不是同一个问题;是 systemctl restart service 有问题;我先把 restart 关掉了“docker update --restart no <container_id_or_name>”,然后 reboot 两遍(因为第一遍还是会调用 restart );第二遍启动后 Dbus 就不报错了;希望对你有帮助
|
![]() |
24
ruanimal 22 小时 7 分钟前
考虑换成 lxc 试试
|
![]() |
25
catamaran OP 最后采用开源的一个 python 脚本替换 systemctl ,https://github.com/gdraheim/docker-systemctl-replacement 。就一个文件,直接把 systemctl 替换掉。跟之前的区别是原来服务是通过 systemd 自启的,现在必须写在 docker 的 entrypoint 中,用 systemctl start service 来启动。长期方案还是不要依赖 systemd ,一个容器只纳管一个服务。
|