如何使 systemd 服务“跟随”另一个服务的状态?

如何使 systemd 服务“跟随”另一个服务的状态?

我有一个使用 systemd-networkd 设置的“虚拟”网络接口;默认情况下,界面保持“向下”状态。

有一个服务单元运行一个应用程序,该应用程序绑定到该接口上的地址(使用非本地绑定,以便即使接口关闭也可以绑定)。当且仅当服务正在运行时,网络接口才应处于“启动”状态。

我希望的结果是,如果服务重新启动,或者崩溃并且无法恢复,接口将保持“关闭”状态,并且机器上的路由守护程序(使用 OSPF 的bird2)将停止广播到该地址的路由,因此对该服务的请求将被路由到其他可用实例。

我可以使用ExecStartPostExecStopPost来运行“ip link set up/down”或“networkctl up/down”命令(事实上这是我的第一次尝试),但该服务的单元文件在非常严格的沙盒环境中运行它作为非特权用户,因此无法执行这些命令,因为它们将在没有 CAP_NET_ADMIN 的环境中运行。服务单元文件的示例是这里

我还尝试创建一个单独的服务来运行这些命令,该服务将以“root”身份正常运行,并且不会受到这种方式的限制。但是,我还没有找到会导致第二个服务的依赖项规范的组合跟随第一个服务的状态。

如果我在服务B中使用After=and BindsTo=,指向服务A,那么在系统启动过程中,服务B会在服务A之后正确启动。如果服务 A 停止,服务 B 也会停止。如果 systemd 重新启动服务 A,那么服务 B 也会重新启动。

但是,如果服务 A 停止,然后再次启动,服务 B不是开始了。

我能想到的唯一其他选择是创建一个结合了这两个服务的新目标,并以某种方式限制服务 A,使其无法手动启动,并以这种方式提醒管理员他们需要启动目标而不是服务。但我不清楚如何使这个新目标自动依赖multi-user.target

答案1

好的,使用其他答案中的位,这就是我最终得到的结果:

对于 systemd 版本 248 及更低版本

anycast-dns.target(任意播送 DNS 目标):

[Unit]
Description=Manage anycast DNS resolver and its network link

[Install]
WantedBy=multi-user.target

dns-link-manager.service:

[Unit]
BindsTo=pdns-recursor.service
After=pdns-recursor.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/networkctl up dns
ExecStop=/usr/bin/networkctl down dns

[Install]
WantedBy=anycast-dns.target

pdns-recursor.service.d/anycast-dns.conf:

[Unit]
RefuseManualStart=yes

[Install]
WantedBy=
RequiredBy=anycast-dns.target

systemctl enable为他们每个人运行。

这得到了想要的结果:

  • 启动时,anycast-dns.target 启动 pdns-recursor.service;如果成功,则 dns-link-manager.service 将打开网络链接。

  • 如果 pdns-recursor.service 停止(手动,或者崩溃且无法重新启动),则 dns-link-manager.service 会断开网络链接。

  • 管理员无法手动启动(或重新启动)pdns-recursor.service,他们必须启动anycast-dns.target作为代理,以确保网络链接也能启动。

对于 systemd 版本 249 及更高版本

dns-link-manager.service:

[Unit]
Requisite=pdns-recursor.service
After=pdns-recursor.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/networkctl up dns
ExecStop=/usr/bin/networkctl down dns

pdns-recursor.service.d/anycast-dns.conf:

[Unit]
Upholds=dns-link-manager.service
PropagatesStopTo=dns-link-manager.service

这得到了想要的结果:

  • 启动时,multi-user.target 启动 pdns-recursor.service;如果成功,则 dns-link-manager.service 将打开网络链接(由于依赖性Upholds

  • 如果 pdns-recursor.service 停止(手动,或者崩溃且无法重新启动),则 dns-link-manager.service 将断开网络链接(由于依赖性PropagatesStopTo)。

  • 管理员无法手动启动 dns-link-manager.service,除非 pdns-recursor.service 正在运行(在这种情况下 dns-link-manager.service 将已经在运行)。

相关内容