请教一个 docker+systemd 的问题
在 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 去掉,但是这个成本比较高。
我解释一下,因为这产品最初是在虚拟机里跑的,它的升级方式用到了 systemctl restart service, 而且前端的升级是利用后端的服务实现的,这个容器中不但用到了 systemctl ,还有多个服务在跑(tomcat/nginx)。现在在进行重构,分离服务,去掉对 systemd 的依赖,但是因为涉及到系统的升级,没那么快。
至于在容器中跑 systemd ,hub.docker.com 就有现成的,只不过用的确实不多。
我现在主要的问题是,ubuntu 升了个版本就出问题了,按道理说 docker 应该跟宿主机的系统没关系才对。
我只能建议你把问题描述丢给 deepseek R1
遇到技术问题就去问 AI 。论坛是吹牛逼的地方,你想把论坛当 AI 用?
镜像中增加 systemd 听上去有点奇怪啊, 作用是什么? "Failed to get D-Bus connection: No such file or directory" 看上去像是 systemctl 跟 systemd daemon 之类的东西无法通信. 容器内一般不用进程管理器了, 一个进程一个容器由外面的 docker 来管理, 自动重启什么的就行.
我说几点:
- 首先,Docker 是应用容器( Application Container ),应用容器的设计理念就是「一个容器 = 一个应用主进程」。如果你需要在容器里塞很多平行的进程,那么已经在逆设计理念硬用了。等于是反天道而行,有问题是自然的。所以要么 (1) 拆分应用成多容器,用 TCP 交流;(2) 换成系统容器( System Container ),比如 LXD ;
抛开第一点不谈,如果你只是要编排任务,也不应该让本来用来管理系统资源和内核的 systemd 硬上(虽然它确实有编排服务的功能,但它还有很多别的职能啊),你需要的是「 systemctl 独立绿色版」,我推荐 Supervisord: supervisord.org/ 。
#4 补充一下:
- 既然楼主没说清楚为什么要用 systemctl ,我再预判一下楼主的实际问题:是不是有应用文档里只教了怎么用 systemctl 启动,所以离了 systemctl 就不知道怎么启了?
如果是这样,我建议仔细学一下 systemd.service 的工作方式,去掉这东西的成本可能没你想得那么高。
请教一下,如果是 dev container 的话,一个 dev container 同时启动后端服务与 PostgreSQL 如何?还是说依然需要用 docker compose 的形式?
如果非要多个服务塞同一个容器,不要用很依赖系统的 systemd ,用 openrc 或 supervisor
#6 生产和开发是不一样的,因为不用考虑服务启停状态这些东西,dev container 里你怎么折腾都可以,怎么方便怎么来。上面说的这些只适用于生产部署。
把数据库和 app 都装进一个容器里当然可以,你试试就知道了,不要照本宣科。
没太看懂楼主的问题,如果容器的基础镜像用的是 ubuntu ,那默认就是 systemd 在管理进程啊,当然 init.d 也能用。
另外 centos 7.9 也是用的 systemd 吧?没记错的话
就先检查是不是真的拉起来了 systemd ,以及 dbus.socket/service 有没有跑起来(文件位置和进程)
systemd 默认在容器里跑不了啊,再说了 systemd 这么臃肿的玩意儿就不是在容器里用的
其实能跑,只是容器运行时要给点额外的处理(挂载一些需要的文件系统),容器管理器可能自动做了这些事情
比如 podman 的 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...
与 root 权限有关?
- Dockerfile entrypoint PID 1 需要是 systemd 或者 init
/sbin/init -> /lib/systemd/systemd
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很早之前这么跑过, 要挂一堆 hostfs 进去, 上面已经有人给了参考链接, 另外镜像也要装很多东西, 而且 systemd 很多包的安装脚本没考虑在容器里面, 安装时候也有不小的问题, 总之一句话, 能跑但不建议, 会有奇奇怪怪的问题, 尤其是版本升级之类的时候, 如果是跑单进程, 建议找个 dockerfile 参考一下在容器里面怎么跑, 如果是多进程, 优先考虑 compose 之类的多容器方案, 其次是单容器多进程的 tinit/supervisor 这种方案
放 systemd 进去根本不是最佳实践,必须去掉
Docker 直接 entrypoint 运行就是,套 systemd 是个傻情况?
之前遇到一次这种情况是 CentOS user ,用 root 才行,的确是 DBus socket 连不上
#10 没拉起来,拉起来后会有一个/usr/lib/systemd/systemd-journald 进程,我尝试手动运行,没反应。github 上有个 python 版的 systemctl ,我准备替换一下试试。
容器的 entrypoint 得是 systemd ,可以检查一下
用于接口验签 客户端有数据 d 需要校验 通过算法 H(d) = sign, 比如这个 H 算法每次计算耗费 1G Ram,10M 条指令。总之就是消耗资源,耗时 100 毫秒…
用 django celery 可以实现吗 有多少 xlsx 要读, 还需要高并发 实际不需要多少,但是要处理并发 不是很懂什么叫高并发读取 xlsx 文件,你一个…
经过测试,香港腾讯轻量云的 IP 出现了大量随机高 Ping 和丢包行为,通过路由追踪查看,一直到香港的骨干都是 0 丢包,延迟也很低的状态,只有到最后一跳延迟突然随机增高。 …