一个很好的解决方案是让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
今天一样使用它,这一事实使它开始使用起来很容易。