Systemd:在另一个单元真正启动后启动一个单元

Systemd:在另一个单元真正启动后启动一个单元

在我的特定情况下,我想在一切完全启动remote-fs后启动单元。glusterfs

我的 systemd 文件:

glusterfs目标:

node04:/usr/lib/systemd/system # cat glusterfsd.service 
[Unit]
Description=GlusterFS brick processes (stopping only)
After=network.target glusterd.service

[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
ExecStop=/bin/sh -c "/bin/killall --wait glusterfsd || /bin/true"
ExecReload=/bin/sh -c "/bin/killall -HUP glusterfsd || /bin/true"

[Install]
WantedBy=multi-user.target

remote-fs目标:

node04:/usr/lib/systemd/system # cat remote-fs.target 
[Unit]
Description=Remote File Systems
Documentation=man:systemd.special(7)
Requires=glusterfsd.service
After=glusterfsd.service remote-fs-pre.target
DefaultDependencies=no
Conflicts=shutdown.target

[Install]
WantedBy=multi-user.target

好的,所有 Gluster 守护进程都启动成功,我想通过 NFS 挂载 Gluster 文件系统,但是 Gluster 的 NFS 共享在glusterfs.service启动后不是立即准备好,而是几秒钟后,因此通常remote-fs无法挂载它,即使考虑到RequiresAfter指令。

我们看一下日志:

Apr 14 16:16:22 node04 systemd[1]: Started GlusterFS, a clustered file-system server.
Apr 14 16:16:22 node04 systemd[1]: Starting GlusterFS brick processes (stopping only)...
Apr 14 16:16:22 node04 systemd[1]: Starting Network is Online.
Apr 14 16:16:22 node04 systemd[1]: Reached target Network is Online.
Apr 14 16:16:22 node04 systemd[1]: Mounting /stor...

这里一切正常,远程文件系统(/stor)似乎在 glusterfs 启动后挂载,正如单元文件所言......但接下来的几行是:

//...skipped.....
Apr 14 16:16:22 node04 systemd[1]: Started GlusterFS brick processes (stopping only).

什么?GlusterFS 只为这一刻做好了准备!然后我们看到:

//...skipped.....
Apr 14 16:16:23 node04 mount[2960]: mount.nfs: mounting node04:/stor failed, reason given by server: No such file or directory
Apr 14 16:16:23 node04 systemd[1]: stor.mount mount process exited, code=exited status=32
Apr 14 16:16:23 node04 systemd[1]: Failed to mount /stor.
Apr 14 16:16:23 node04 systemd[1]: Dependency failed for Remote File Systems.
Apr 14 16:16:23 node04 systemd[1]: Unit stor.mount entered failed state.

当 systemd 尝试挂载存储时,挂载失败,因为 NFS 服务器尚未准备好。

由于 systemd 启动过程的不确定性,有时(大约 10 次启动中有 1 次)在启动时挂载此文件系统会成功。

如果启动时挂载不成功,我可以登录服务器并手动挂载 /stor 目录,因此 Gluster 的 NFS 服务似乎运行良好。

那么在日志中出现该行remote-fs之后如何启动呢?glusterfsdStarted GlusterFS brick processes

remote-fs似乎是最后几个目标之一,所以我无法让它在另一个实际上不需要的“解决方法”目标之后启动remote-fs

答案1

您可以通过以下命令分析 systemd 启动顺序。使用支持 SVG 的 Web 浏览器查看输出文件。

systemd-analyze plot > test.svg

该绘图将为您提供上次启动的时间统计数据,这将为您提供更清晰的问题观点。

mount我通过在 中添加命令解决了 NFS 安装问题/etc/rc.local。但是我不确定它是否适用于 glusterd 集成,值得一试以快速解决问题。为了让 systemd 运行 rc.local,您应该满足以下条件:

# grep Condition /usr/lib/systemd/system/rc-local.service
ConditionFileIsExecutable=/etc/rc.d/rc.local

答案2

正如其他人所建议的那样;我不确定它是否实际上依赖于“glusterfsd”,而不是其他东西的一般延迟,例如需要成功的 DNS 查找才能解析“node4”并成功挂载 NFS 共享。

我们遇到这种延迟是因为我们的大多数设置都使用本地验证解析器,该解析器需要在其他依赖 DNS 的服务成功启动之前可用。

解决这个问题的方法是使用一个“ExecStartPre”脚本,该脚本基本上反复测试特定依赖项的可用性,直到成功(退出 0)或尝试超时(退出 1)。

如果可以,请确保在主 systemd lib 目录之外进行自定义。更改软件包文件意味着它们可能会在下一次更新时被覆盖。

答案3

也许你可以将其添加到remote-fs目标:

[Unit]
...
ConditionPathExists=/stor

答案4

也许一些轮询会有所帮助。这与 systemd 无关。例如,mysql -e ';'在使用 mysql 执行一些有用的操作之前,我会使用循环。

相关内容