首页 > 解决方案 > 如何在 nslcd.service 之后启动 docker.service?

问题描述

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

dockergroup 存在于 ldap 上,这也是为什么docker.service必须在nslcd.service.

我试图编辑systemctl启动配置docker.service

$ sudo systemctl edit --full docker.service

我添加nslcd.serviceAfter, 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登录的。

标签: linuxdockerunixservicesystemctl

解决方案


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

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

我将 nslcd.service 添加到 After, Wants, Requires

同时指定 aWants=和 aRequires=关系是多余的。这种Requires=关系只是Wants=: using的一个更强大的版本,Requires=意味着如果您启动docker服务,并且nslcd尚未运行,它也会启动。Wants=在相同的情况下使用,docker将在没有启动的情况下启动nslcd

我仍然无法让 docker 在该服务之后运行

完全有可能nslcd需要一些时间来连接到目录服务。在这种情况下,该过程可能已启动,它满足After=依赖关系,因此docker即使您的组尚不可用,也会启动。

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

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

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

  3. 可能用nslcd实现本地缓存的东西(例如sssd)替换也可以解决这个问题。

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

更新

选项 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"

推荐阅读