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


3

我正在从“ systemd --user”单元文件中启动Docker容器(可能与我刚刚发现的https://github.com/ibuildthecloud/systemd-docker一起)。我希望它们在启动时启动。

问题是您无法执行操作After=docker.service,因为systemd用户模式单位看不到systemd系统模式单位。

有人有解决此问题的好方法吗?

到目前为止,我“最好的”想法是让一个运行一次的systemd单元运行一个脚本,该脚本进入睡眠循环,直到“ docker info”返回合理的值,然后执行After = that,但这似乎很糟糕方式。

Answers:


2

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

这样,当您启动docker命令(例如从用户 systemd单元)时,它将有一个要连接的套接字,但是它将阻塞直到Docker守护程序实际上已准备好为它服务。

这篇文章在systemd博客中描述了套接字激活以消除显式依赖关系的基本思想,该文章讨论了传统上通过显式依赖关系处理的四种服务,但是使用套接字激活不再需要对其进行配置。这是节选(很长,但确实很重要):

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

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

检查您的发行版是否发货docker.socket,在这种情况下,只需启用它。

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


要考虑的另一种选择是从Docker切换到podman

Podman试图成为Docker的嵌入式兼容替代产品(因此您可以使用相同的命令行,只需将其替换docker为即可podman。)

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


1
噢,波德曼看起来很可爱;去年,我实际上一直在与Dan Walsh谈论这些问题,但是我不知道他们已经提出了解决方案。谢谢!
rlpowell

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.