systemd: how to make sure a service is started only after another service is up and running

На сервере Ubuntu 20.04.2 TLS мне нужно запустить службу после того, как другая служба полностью запущена. В частности, служба openvpn-server создает интерфейс tun0 с IP-адресом 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 под названием openvpn-server@server.service. Расширение строки Required-Start в /etc/init.d/rinetd, чтобы сказать:

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

должным образом переводится systemd-sysv-generator в дополнительную строку

After=openvpn-server@server.service

в /run/systemd/generator.late/rinetd.service. Но systemd игнорирует это. rinetd все еще показывает то же сообщение журнала и сбой, доказывая, что он все еще запущен до того, как openvpn-server встал.

Как заставить systemd надежно запускать службу rinetd только после того, как служба openvpn-server выполнила свою часть работы и создала интерфейс?

0
задан 14 May 2021 в 12:47

2 ответа

Если мы сначала возьмем systemd, я думаю, будет лучше, если вы обратитесь непосредственно к интерфейсу. Устройства в дереве dev и sysfs открыты для systemd и могут быть использованы для создания зависимостей с другими устройствами.

Начните с маскировки исходного сценария запуска.

systemctl mask --now rinetd.service

С помощью инстанцированного .service, например, rinetd-daemon@.service, вы можете запустить один или несколько экземпляров, если потребуется, чтобы иметь более одного устройства (при условии, что 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 rinetd-daemon@tun0.service
1
ответ дан 28 July 2021 в 11:40

Новый файл .service, вероятно, нуждается

[Unit]
After=openvpn-server@server.service
Requires=openvpn-server@server.service

Опции могут быть запутанными, но есть тонна других ресурсов, которые охватывают аналогичную тему.

0
ответ дан 28 July 2021 в 11:40

Другие вопросы по тегам:

Похожие вопросы: