systemd:如何确保一项服务仅在另一个服务启动并运行后才启动

systemd:如何确保一项服务仅在另一个服务启动并运行后才启动

在 Ubuntu 20.04.2 TLS 服务器上,我需要在另一个服务完全启动后启动一个服务。具体来说,该openvpn-server服务会创建一个tun0IP 地址为 10.87.0.1 的接口,rinetd然后该服务会绑定到该接口。因此,该rinetd服务应该只在openvpn-server服务已创建该接口。

rinetd附带一个 sysvinit 服务脚本,/etc/init.d/rinetd内容如下:

# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog

这将导致rinetd在系统启动期间启动 openvpn-server已创建接口。然后它发出日志消息:

rinetd[792]: couldn't bind to address 10.87.0.1 port 873 (Cannot assign requested address)

并且不接受连接,直到我用手动重新启动它sudo systemctl restart rinetd,之后它就可以正常运行了。

根据服务器sudo systemctl status进程openvpn由名为的 systemd 服务运行[email protected]。扩展该Required-Start/etc/init.d/rinetd以说明:

# Required-Start:    $remote_fs $syslog openvpn-server@server

被适当地翻译systemd-sysv-generator为附加行

[email protected]

/run/systemd/generator.late/rinetd.service。但是 systemd 忽略了这一点。rinetd仍然显示相同的日志消息和故障,证明它在openvpn-server启动之前仍然启动了。

我怎样才能让 systemd 可靠地启动rinetd服务服务openvpn-server是否已完成其部分并创建了界面?

答案1

如果我们首先使用 systemd,我认为最好直接处理接口。dev 和 sysfs 树中的设备暴露给 systemd,可用于与其他设备建立依赖关系单位

首先屏蔽原始启动脚本。

systemctl mask --now rinetd.service

实例化.service,例如[email protected],如果需要,您可以启动一个或多个实例,如果我们有多个设备(提供rinetd可以绑定到多个接口)。

[Unit]
Description=Rinetd connection forwarding service (%I)
  After=sys-subsystem-net-devices-%i.device
BindsTo=sys-subsystem-net-devices-%i.device

[Service]
Type=forking
ExecStart=/usr/sbin/rinetd
PIDFile=/var/run/rinetd.pid
ExecReload=kill -HUP $MAINPID

[Install]
WantedBy=sys-subsystem-net-devices-%i.device

然后您可以将该服务与设备名称一起实例化:

systemctl enable --now [email protected]

答案2

相关内容