如何在 nslcd.service 之后开始 docker.service?

How can I start docker.service after nslcd.service?

我所有的 unix 主机都使用 ldap 后端。

docker 组存在于 ldap 上,这也是 docker.service 必须在 nslcd.service 之后启动的原因。

我已尝试为 docker.service 编辑 systemctl 启动配置:

$ sudo systemctl edit --full docker.service

然后我将 nslcd.service 添加到 AfterWantsRequires:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service nslcd.service
Wants=network-online.target nslcd.service
Requires=docker.socket nslcd.service

在那项服务之后我仍然无法 docker 到 运行:

sudo service docker status
● docker.service - Docker Application Container Engine
   Loaded: loaded (/etc/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: https://docs.docker.com

Oct 10 19:35:02 dev-08 systemd[1]: Dependency failed for Docker Application Container Engine.

启动后手动启动容器没有问题,因为我是通过ldap登录的。

docker group is existing on the ldap, this is also why docker.service must start after nslcd.service.

让系统服务依赖于远程目录服务中的用户和组通常不是一个好主意(因为目录服务的问题会影响主机上的服务可用性)。

And I add nslcd.service to After, Wants, Requires

同时指定 Wants=Requires= 关系是多余的。 Requires= 关系只是 Wants= 的更强版本:使用 Requires= 意味着如果您启动 docker 服务,并且 nslcd 还没有 运行,它也会被启动。在相同情况下使用 Wants=docker 将在不启动 nslcd 的情况下启动。

I still can't get docker to run after that service

很可能 nslcd 需要一些时间才能连接到目录服务。在这种情况下,进程 可能已启动,这满足了 After= 依赖性,因此即使您的组尚不可用,docker 也会启动。

有几种方法可以解决这种情况:

  1. 根据我最初的评论,只需创建一个本地 docker 组即可。这是迄今为止最简单、最可靠的解决方案。

  2. 创建一个新的单发单元,旋转直到 docker 组存在。使这个单位依赖于nslcd,并使docker依赖于新单位。

  3. 可能将 nslcd 替换为实现本地缓存的内容(例如 sssd)也可以解决此问题。

另一方面,像您在本例中所做的那样直接编辑单元文件是个坏主意,因为如果您已经通过打包工具 (apt/yum/etc) 安装了 Docker ,您的修改将在您下次升级包时被覆盖。更好的解决方案是创建 drop-in files 来扩充单元配置。

更新

选项 2 可能如下所示:

[Unit]
Requires=nslcd.service docker.service
After=nslcd.service
Before=docker.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c "while ! getent group docker; do sleep 1; done"