Systemd - 仅在 DNS 可用后启动服务

Systemd - 仅在 DNS 可用后启动服务

我有几个服务,最明显的是 nginx 和 ntpd,它们依赖于有效的 DNS 解析才能正常启动。目前,这两个服务在启动时都无法正常启动,但在机器启动后手动干预时可以正常启动,但日志中有一些关于无法解析名称的消息。

这让我相信我与 systemd 之间存在竞争条件。我的服务器将其名称服务器指向 127.0.0.1。绑定到 localhost:53 的是 pdns-recursor。我已在其单元文件中将 ntp 和 nginx 设置为 WantedBy pdns-recursor,如下所示

[Unit]
WantedBy=pdns-recursor.service

但是我仍然在 nginx 和 ntp 中收到有关启动时无法解析名称的日志消息。

在这些服务尝试启动之前,如何验证 DNS 是否完全启动?我使用的是 Ubuntu 16.04

Aug 09 22:35:25 host.blah ntpd[3574]: restrict: ignoring line 21, address/host 'ntp.blah' unusable.
Aug 09 22:35:26 host.blah ntpd[3574]: restrict: ignoring line 23, address/host 'ntp.blah' unusable.
Aug 09 22:35:28 host.blah ntpd[3574]: restrict: ignoring line 25, address/host 'ntp.blah' unusable.
Aug 09 22:35:29 host.blah ntpd[3574]: restrict: ignoring line 27, address/host 'ntp.blah' unusable.

答案1

ExecStartPre在我的 ntp 和 nginx 单元文件中放置了一个,以便在继续之前继续尝试解析名称。

这可以正常工作。正常的 systemd 构造(例如等待其他服务上线)是不可靠的,因为 pdns 守护进程启动并不意味着它一定能够在启动后的最初几毫秒内回答查询。

ExecStartPre=/bin/sh -c 'until host example.com; do sleep 1; done'

答案2

尝试使用:

[Unit]
After=network-online.target
Wants=network-online.target

有一篇完整的文章Unix 和 Linux以及免费桌面地点。

答案3

systemd 足够灵活,可以做到这一点:

[Unit]
Description=Wait for DNS to come up using 'host'
After=nss-lookup.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'until host yourhost.com; do sleep 1; done'

[Install]
WantedBy=multi-user.target

然后您可以在需要 dns 挂载的单元文件中依赖此单元:

[Unit]
Description=mount nfs
After=dns-ready.service

答案4

我同意您对竞争条件的诊断...除非明确配置了依赖项,否则 systemd 将尝试并行启动这些服务。但我不认为 WantedBy 指令会对您有所帮助,因为它会影响安装依赖项,而不是启动依赖项,本手册页

我认为您要寻找的是 Wants 指令和 After 指令的组合。对于 ntp 和 nginx,我认为您需要将以下内容添加到您的单元文件中:

Wants=pdns-recursor.service
After=pdns-recursor.service

这两个选项应该可以确保 DNS 服务在 ntp/nginx 服务之前启动,这有望解决您的竞争问题。

作为一个谨慎小心的人,我实际上建议将您的名称/IP 映射放入您的 /etc/hosts 文件中;这样,即使您的 DNS 失败,其他服务也可以启动。如果您真的想尝试使用 DNS 而不是静态文件,您可以切换解析顺序。

相关内容