请教一个 docker+systemd 的问题

2025 年 2 月 19 日
 catamaran

在 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 去掉,但是这个成本比较高。

3558 次点击
所在节点    Linux
26 条回复
vincentWdp
2025 年 2 月 19 日
我只能建议你把问题描述丢给 deepseek R1
Chaidu
2025 年 2 月 19 日
遇到技术问题就去问 AI 。论坛是吹牛逼的地方,你想把论坛当 AI 用?
snowfuck
2025 年 2 月 19 日
镜像中增加 systemd 听上去有点奇怪啊, 作用是什么? "Failed to get D-Bus connection: No such file or directory" 看上去像是 systemctl 跟 systemd daemon 之类的东西无法通信. 容器内一般不用进程管理器了, 一个进程一个容器由外面的 docker 来管理, 自动重启什么的就行.
w568w
2025 年 2 月 19 日
我说几点:

1. 首先,Docker 是应用容器( Application Container ),应用容器的设计理念就是「一个容器 = 一个应用主进程」。如果你需要在容器里塞很多平行的进程,那么已经在逆设计理念硬用了。等于是反天道而行,有问题是自然的。所以要么 (1) 拆分应用成多容器,用 TCP 交流;(2) 换成系统容器( System Container ),比如 LXD ;

2. 抛开第一点不谈,如果你只是要编排任务,也不应该让本来用来管理系统资源和内核的 systemd 硬上(虽然它确实有编排服务的功能,但它还有很多别的职能啊),你需要的是「 systemctl 独立绿色版」,我推荐 Supervisord: https://supervisord.org/
w568w
2025 年 2 月 19 日
@w568w #4 补充一下:

3. 既然楼主没说清楚为什么要用 systemctl ,我再预判一下楼主的实际问题:是不是有应用文档里只教了怎么用 systemctl 启动,所以离了 systemctl 就不知道怎么启了?

如果是这样,我建议仔细学一下 systemd.service 的工作方式,去掉这东西的成本可能没你想得那么高。
superhot
2025 年 2 月 19 日
@w568w 请教一下,如果是 dev container 的话,一个 dev container 同时启动后端服务与 PostgreSQL 如何?还是说依然需要用 docker compose 的形式?
sagaxu
2025 年 2 月 19 日
如果非要多个服务塞同一个容器,不要用很依赖系统的 systemd ,用 openrc 或 supervisor
w568w
2025 年 2 月 19 日
@superhot #6 生产和开发是不一样的,因为不用考虑服务启停状态这些东西,dev container 里你怎么折腾都可以,怎么方便怎么来。上面说的这些只适用于生产部署。
memorycancel
2025 年 2 月 19 日
@superhot 把数据库和 app 都装进一个容器里当然可以,你试试就知道了,不要照本宣科。


没太看懂楼主的问题,如果容器的基础镜像用的是 ubuntu ,那默认就是 systemd 在管理进程啊,当然 init.d 也能用。
另外 centos 7.9 也是用的 systemd 吧?没记错的话
yanqiyu
2025 年 2 月 19 日
就先检查是不是真的拉起来了 systemd ,以及 dbus.socket/service 有没有跑起来(文件位置和进程)
Nitroethane
2025 年 2 月 19 日
systemd 默认在容器里跑不了啊,再说了 systemd 这么臃肿的玩意儿就不是在容器里用的
yanqiyu
2025 年 2 月 19 日
@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...
zbinlin
2025 年 2 月 19 日
与 root 权限有关?
feedcode
2025 年 2 月 20 日
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
my3157
2025 年 2 月 20 日
很早之前这么跑过, 要挂一堆 hostfs 进去, 上面已经有人给了参考链接, 另外镜像也要装很多东西, 而且 systemd 很多包的安装脚本没考虑在容器里面, 安装时候也有不小的问题, 总之一句话, 能跑但不建议, 会有奇奇怪怪的问题, 尤其是版本升级之类的时候, 如果是跑单进程, 建议找个 dockerfile 参考一下在容器里面怎么跑, 如果是多进程, 优先考虑 compose 之类的多容器方案, 其次是单容器多进程的 tinit/supervisor 这种方案
defunct9
2025 年 2 月 20 日
放 systemd 进去根本不是最佳实践,必须去掉
Ipsum
2025 年 2 月 20 日
Docker 直接 entrypoint 运行就是,套 systemd 是个傻情况?
palytoxin
2025 年 2 月 20 日
之前遇到一次这种情况是 CentOS user ,用 root 才行,的确是 DBus socket 连不上
catamaran
2025 年 2 月 20 日
@yanqiyu #10 没拉起来,拉起来后会有一个/usr/lib/systemd/systemd-journald 进程,我尝试手动运行,没反应。github 上有个 python 版的 systemctl ,我准备替换一下试试。
yanqiyu
2025 年 2 月 20 日
@catamaran 容器的 entrypoint 得是 systemd ,可以检查一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1112743

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX