如何在 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
添加到 After
、Wants
、Requires
:
[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
也会启动。
有几种方法可以解决这种情况:
根据我最初的评论,只需创建一个本地 docker
组即可。这是迄今为止最简单、最可靠的解决方案。
创建一个新的单发单元,旋转直到 docker
组存在。使这个单位依赖于nslcd
,并使docker
依赖于新单位。
可能将 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"
我所有的 unix 主机都使用 ldap 后端。
docker
组存在于 ldap 上,这也是 docker.service
必须在 nslcd.service
之后启动的原因。
我已尝试为 docker.service
编辑 systemctl
启动配置:
$ sudo systemctl edit --full docker.service
然后我将 nslcd.service
添加到 After
、Wants
、Requires
:
[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
也会启动。
有几种方法可以解决这种情况:
根据我最初的评论,只需创建一个本地
docker
组即可。这是迄今为止最简单、最可靠的解决方案。创建一个新的单发单元,旋转直到
docker
组存在。使这个单位依赖于nslcd
,并使docker
依赖于新单位。可能将
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"