能不能在容器里跑完整的 systemd?它需要什么条件、启动后有多重、怎么停?这篇用 debian:12-slim 装上 systemd,逐种选项试能不能启动,并量停止信号的差别。
默认(什么选项都不加):exited exit=255;systemctl is-system-running = -;控制台最后几行:[!!!!!!] Failed to mount API filesystems. | Exiting PID 1... --tmpfs /run --tmpfs /tmp:exited exit=255;systemctl is-system-running = -;控制台最后几行:[!!!!!!] Failed to mount API filesystems. | Exiting PID 1... --tmpfs /run --tmpfs /run/lock --tmpfs /tmp:exited exit=255;systemctl is-system-running = -;控制台最后几行:[!!!!!!] Failed to allocate manager object. | Exiting PID 1... --cap-add SYS_ADMIN:exited exit=255;systemctl is-system-running = -;控制台最后几行:[!!!!!!] Failed to allocate manager object. | Exiting PID 1... --cap-add SYS_ADMIN --security-opt seccomp=unconfined:exited exit=255;systemctl is-system-running = -;控制台最后几行:[!!!!!!] Failed to allocate manager object. | Exiting PID 1... --cap-add SYS_ADMIN + seccomp=unconfined + --tmpfs /run /run/lock /tmp:exited exit=255;systemctl is-system-running = -;控制台最后几行:[!!!!!!] Failed to allocate manager object. | Exiting PID 1... --privileged:running exit=0;systemctl is-system-running = running;控制台最后几行:[ OK ] Finished systemd-update-ut… - Record Runlevel Change in UTMP. | Debian GNU/Linux 12 4bea387ff94e console
systemd 当 PID 1 要挂载 /run、/run/lock 等 tmpfs、管理 cgroup。非特权容器里这些操作被拒绝,结果是 255 退出;我试的 --cap-add SYS_ADMIN 加 seccomp=unconfined 加 tmpfs 都还是 Failed to allocate manager object。另一种常被提到的做法是让 cgroup 以可写方式挂入(-v /sys/fs/cgroup:/sys/fs/cgroup:rw --cgroupns=host);我最初探索时带这些选项的 docker run 没有成功创建出容器(原因没有看),所以没有纳入最终的矩阵,不能下结论。
PID 1 的名字:systemd systemctl is-system-running:running 运行中的服务:console-getty.service getty@tty1.service getty@tty2.service getty@tty3.service getty@tty4.service getty@tty5.service getty@tty6.service systemd-journald.service 进程(按名字统计 systemd / systemd-journald / agetty):systemd=2 systemd-journal=1 agetty=7 docker top 看到的进程数:9
systemd 容器像一台小机器:journald、getty 一组服务,9 个进程。这和「一个容器一个进程」的惯例相反,通常只在需要测试 systemd 服务单元的场景里用。
镜像里 STOPSIGNAL SIGRTMIN+3(c30):docker stop -t 10 用时 0.2 秒,ExitCode=130 --stop-signal SIGTERM:docker stop -t 10 用时 10.2 秒,ExitCode=137(SIGTERM 没能让它关机,等满宽限期后被 SIGKILL)
systemd 通过 SIGRTMIN+3 关机(这也是 jrei/systemd-debian 这类镜像设 STOPSIGNAL 的原因),SIGTERM 对它无效,docker stop 就会等满宽限期再 SIGKILL。
从 docker run 到 systemctl is-system-running 返回 running 用了 0.5 秒 docker stats 的 MemUsage:15.25MiB / 7.748GiB PIDs=9
空闲时 15.25MiB、0.5 秒到 running。服务多了会更重,没有测。