如何在systemd用户mod中等待docker?

如何在systemd用户mod中等待docker?

我正在启动 Docker 容器(可能是https://github.com/ibuildthecloud/systemd-docker,我刚刚发现)来自“systemd --user”单元文件。我希望他们一开始就启动。

问题是你不能这样做After=docker.service,因为 systemd 用户模式单元看不到 systemd 系统模式单元。

有没有人有好方法来解决这个问题?

到目前为止,我的“最好”想法是制作一个运行一次的 systemd 单元,该单元运行一个睡眠循环的脚本,直到“docker info”返回一些合理的内容,然后 After= 那,但这看起来很糟糕。方式。

答案1

解决这个问题的一个好方法是让 Docker 守护进程(运行在系统systemd 的实例)使用套接字激活。

这样,当您启动 docker 命令时(比如从用户systemd 单元),它将有一个套接字可以连接,但它会阻塞,直到 Docker 守护进程真正准备好为其提供服务。

套接字激活以消除显式依赖关系的基本思想描述于systemd 博客中的这篇文章,它讨论了传统上通过显式依赖关系处理的四种服务,但通过套接字激活,不再需要配置它们。摘录如下(虽然很长,但很能说明问题):

套接字激活使得可以完全同时启动所有四个服务,而无需任何顺序。由于侦听套接字的创建已移至守护进程本身之外,因此我们可以同时启动它们,并且它们能够立即连接到彼此的套接字。即,在一个步骤中创建了/dev/log/run/dbus/system_bus_socket套接字,并且在下一步中同时生成了所有四个服务。当 D-Bus 想要记录到 syslog 时,它只需将其消息写入/dev/log.只要套接字缓冲区未满,它就可以立即继续执行其他初始化操作。一旦系统日志服务赶上,它将处理排队的消息。如果套接字缓冲区已满,则客户端日志记录将暂时阻塞,直到套接字再次可写,并在可以写入日志消息时继续。这意味着我们服务的调度完全由内核完成:从用户空间的角度来看,所有服务都是同时运行的,当一个服务无法跟上其他需要它的服务时,它会暂时阻止它们的请求,但一旦有服务就会继续运行。这些请求已被发送。所有这些都是完全自动的并且对用户空间不可见。因此,套接字激活使我们能够极大地并行化启动,从而能够同时启动以前被认为严格需要序列化的服务。大多数 Linux 服务使用套接字作为通信通道。套接字激活允许同时启动这些通道的客户端和服务器。

Docker 守护进程支持套接字激活自2014年起,因此您使用的版本可能已经支持该功能。

检查您的发行版是否附带了一个docker.socket单元,在这种情况下,您所需要做的就是启用它。

如果您的 Docker 守护进程支持套接字激活,但您的发行版不包含该docker.socket单元,请查看本教程有关如何设置的说明。


另一种值得考虑的选择是从 Docker 切换到播客

Podman 试图成为 Docker 的直接兼容替代品(因此您可以使用相同的命令行,只需替换dockerpodman.)

它们之间的主要区别是 podman 不需要守护进程,因此您无需等待守护进程启动即可启动容器。 Podman 在最新版本的 Linux 发行版中作为软件包提供。而且您可以像今天一样使用它,这一事实docker应该会让您很容易开始使用它。

答案2

顺便说一下,我没有使用 systemd 运行容器,而是使用docker-systemctl-替换完全脚本。

在这种情况下,用户模式具有不同的含义,因为容器使用“USER=”设置运行,将所有进程推送给非 root 所有者。这是一些 docker-cloud 实现的要求 - 示例可以在docker-systemctl-图像

相关内容