我所有的Unix主机都使用ldap后端。
docker
组已存在于ldap上,这也是docker.service
必须在nslcd.service
之后开始的原因。
我尝试编辑systemctl
的{{1}}启动配置:
docker.service
然后将$ sudo systemctl edit --full docker.service
添加到nslcd.service
,After
,Wants
:
Requires
在该服务之后,我仍然无法让docker运行:
[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
启动后手动启动容器没有问题,因为我是通过ldap登录的。
答案 0 :(得分:2)
在ldap上存在docker组,这也是为什么docker.service必须在nslcd.service之后启动的原因。
让系统服务依赖远程目录服务中的用户和组通常是一个坏主意(因为目录服务的问题可能会影响主机上的服务可用性)。
然后我将nslcd.service添加到After,Wants,Requires
同时指定Wants=
和Requires=
关系是多余的。 Requires=
关系只是Wants=
的更强版本:使用Requires=
意味着如果启动docker
服务,而nslcd
尚未运行,则它也将开始。在相同情况下使用Wants=
,docker
会在不启动nslcd
的情况下启动。
在该服务之后,我仍然无法让docker运行
nslcd
很有可能需要一段时间才能连接到目录服务。在这种情况下,进程可能已经启动,可以满足After=
依赖性,因此即使您的组尚不可用,docker
也会启动。
有几种方法可以解决这种情况:
根据我的初始评论,只需创建一个本地docker
组即可。这是迄今为止最简单,最可靠的解决方案。
创建一个新的oneshot单位,该单位旋转直到存在docker
组。使 this 单位依赖于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"