我正在测试CoreOS,看看它是否符合我们的需求,到目前为止,事情进展有点慢,但还行。我喜欢systemd,但它似乎没有正常工作 - 特别是在关机时。
我的目标是让一个脚本在服务启动和停止时运行,分别为我们的DNS服务器添加和删除服务的记录。它在系统启动时启动服务时,或者在手动启动或关闭时启动,但在系统重启或暂停(shutdown -r now
,shutdown -h now
)时无效。
以下是我用作示例的docker注册服务的略微简化版本:
[Unit]
Description=Docker Registry
After=docker.service
Before=registry-ui.service
Wants=registry-ui.service
[Service]
Conflicts=halt.target poweroff.target reboot.target shutdown.target sleep.target
TimeoutStartSec=0
Restart=on-failure
ExecStartPre=-/usr/bin/docker kill Registry
ExecStartPre=-/usr/bin/docker rm Registry
ExecStartPre=-/usr/bin/docker run --rm myrepo:5000/tool runtool arg1 arg2
ExecStart=/usr/bin/docker run various args registry:latest
ExecStop=-/usr/bin/docker run --rm myrepo:5000/tool runtool arg1 arg2
ExecStop=-/usr/bin/docker stop Registry
[X-Fleet]
MachineID=coreos1
[Install]
WantedBy=multi-user.target
RequiredBy=registry-ui.service
Also=registry-ui.service
(此单元与另一个单元 - registry-ui.service 一起工作。当一个单元启动时,另一个单元也可以。)
请注意Conflicts=...
行。我花了很多时间试图找出服务没有正常关闭的原因后添加了它。它没有做任何事。但是,根据docs,服务默认为Conflicts=shutdown.target
行。当服务冲突并且一个人启动时,另一个人就会关闭 - 或者说文档会这么说。
我错过了什么?为什么我的ExecStop=
行没有运行?
我已确定ExecStop=
行确实在运行。使用journalctl -u registry.service -n 200
给了我这样的信息:
Error response from daemon: Cannot start container 7b9083a3f81710febc24256b715fcff1e8146c867500c6e8ce4d170ad1cfd11a: dbus: connection closed by user
这表明问题是(正如我在评论中推测的那样)我的docker容器在关机期间不会启动。我已将以下行添加到[Unit]
部分:
[Unit]
After=docker.service docker.socket
Requires=docker.service docker.socket
...
新行对journalctl错误没有影响,所以现在我的问题是,有没有办法在关闭之前运行实用程序docker容器?
答案 0 :(得分:1)
如果我了解您的目标,您希望在关闭服务器时运行一些DNS清理,并且您尝试在systemd docker服务文件中执行此操作。 为什么你不使用舰队完成这项任务? 尝试创建一个监控DNS服务器的车队单元文件,当它检测到服务器无法访问时,您可以启动清理任务。
在舰队上,当您使用 fleetctl destroy 销毁服务时,exec停止线不会运行(类似于断电)。如果您想要进行清理会话,通常可以使用带有此指令的卫星服务来实现此目的
serviceFile.service
[Unit]
Wants=cleanup@serviceFile.service
cleanup@serviceFile.service
[Unit]
PartOf=%i.service
答案 1 :(得分:0)
不是在一个单元文件中启动所有内容,而是可以启动2个不同的服务并使用bindsTo绑定它们,以便它们一起启动和停止:http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=
这将产生两个简单和较小的单元文件,每个文件都处理一个容器。它还可以让您更轻松地进行调试。