我正在覆盖/usr/lib/systemd/system/docker.service
启动脚本以使用环境文件扩展它。我已经定义了我的配置文件,/etc/systemd/system/docker.service.d/docker.conf
如下所示:
test -d /etc/systemd/system/docker.service.d || \
mkdir /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/docker.conf <<EOF
[Service]
EnvironmentFile=/etc/sysconfig/docker
ExecStartPre=-/usr/local/sbin/generate-docker-config
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --dns=\${LOCAL_IPV4}
EOF
systemctl daemon-reload
我正在运行上面的脚本包装机AMI 的构建步骤。
当我启动 AMI 时,我看到 SystemD 中有关 Docker 服务的以下状态输出:
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/docker.service.d
└─docker.conf
Active: active (running) since Mon 2016-03-28 21:16:11 UTC; 6min ago
Docs: https://docs.docker.com
Main PID: 858 (docker)
CGroup: /system.slice/docker.service
├─ 858 /usr/bin/docker daemon -H fd:// --dns=10.224.4.178 --log-driver=syslog --log-opt tag={{.ImageName}}
ExecStartPre
如输出所示,它尚未运行 my 。如果我执行以下操作,我做看到它现在已经运行了启动脚本:
# systemctl daemon-reload && systemctl restart docker.service && \
systemctl status docker.service
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/docker.service.d
└─docker.conf
Active: active (running) since Mon 2016-03-28 22:05:24 UTC; 24ms ago
Docs: https://docs.docker.com
Process: 1873 ExecStartPre=/usr/local/sbin/generate-docker-config (code=exited, status=0/SUCCESS)
Main PID: 1876 (docker)
CGroup: /system.slice/docker.service
└─1876 /usr/bin/docker daemon -H fd:// --dns=10.224.4.178 --log-driver=syslog --log-opt tag={{.ImageName}}
ExecStartPre
请注意它现在如何在状态输出中显示?
除了daemon-reload
导致 SystemD 加载和运行新的服务配置文件和ExecStartPre
脚本之外,我还应该在 Packer 构建中运行一个命令吗?我应该只使用restart
Packer 构建中的服务,还是有更好、更适合该问题的解决方案?
注意:我的脚本需要可用于 EC2 实例标签的ExecStartPre
网络。 curl
Docker 服务文件确实指定了After=network.target docker.socket
,所以我假设它将在网络启动后运行。
答案1
嗯,这是预期的行为。如果您打算在覆盖 docker 单元文件后重新启动 docker 服务,则应该在脚本中调用systemctl restart docker.service
after 。systemctl daemon-reload
如果您还想仅在已运行的情况下重新启动 dokett,请改为调用systemctl try-restart docker.service
。
命令的目的systemctl daemon-reload
是告诉systemd
守护进程重新加载其所有配置、重新加载单元文件并重新生成服务依赖关系树。但是,即使磁盘上的单元文件发生更改,它也不会影响系统中的任何其他服务。
答案2
假设网络“在线”后network.service
并不是 100% 可靠。这就是为什么有一个network-online.target
.
如果您依赖于curl并且希望在服务启动之前绝对确定网络已启动,DNS工作等,那么将其添加到您的docker.conf
可能会有所帮助...
[Unit]
After=network-online.target
...并且由于您正在执行所有这些启动后操作,为了让新功能ExecStartPre
正常工作,那么您应该在 Packer 构建脚本中添加systemctl daemon-reload && systemctl restart docker.service
或。systemctl stop docker.service && systemctl daemon-reload && systemctl start docker.service
后者最为可靠。
在修改和daemon-reload
完成之前停止服务将确保整个单元按指定重新加载。我可以在您提供的输出的第三位中看到ExecStart
fordocker.service
确实不是包含您在 Packer 构建脚本中指定的参数。这是因为systemctl restart docker.service
(与停止、守护进程重新加载和启动)。