请教一个 docker+systemd 的问题

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

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

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

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

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

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


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