Вопрос или проблема
У меня есть сценарий upstart, который я конвертирую в systemd. Чтобы этот сервис запустился, необходимо, чтобы определенный сетевой интерфейс был доступен.
Вот что я использую в своем сценарии upstart:
start on (local-filesystems and net-device-added INTERFACE=tun0)
Какой эквивалент в systemd?
Вы должны иметь немного сломанную версию того, что у вас было в сценарии upstart, с чем-то вроде:
Wants=sys-devices-virtual-net-tun0.device
After=sys-devices-virtual-net-tun0.device
systemd должен генерировать файл ‘device’ для tun0
. Единственная проблема в том, что если устройство tun0
не создается openvpn достаточно быстро, запуск вашего сервиса попробует ‘запустить’ sys-devices-virtual-net-tun0.device
, что приведет к сбою времени ожидания (по умолчанию указанному в DefaultTimeoutStartSec
как 90 секунд, обычно в /etc/systemd/system.conf
). Поэтому, возможно, лучше иметь что-то, что зависит от openvpn, а затем явно проверять наличие устройства tun0
, перезапуская, если оно не найдено:
# Ждать нестабильно на сервис openvpn
Wants=openvpnxxxx.service
After=openvpnxxx.service
# Убедитесь, что tun0 активен
ExecStartPre=/bin/bash -c "systemctl is-active sys-devices-virtual-net-tun0.device"
# Продолжайте перезапуск до тех пор, пока tun0 не будет активен
Restart=on-failure
Ответ или решение
Для реализации зависимости вашего сервиса от доступности сетевого интерфейса tun0
в системе systemd
потребуется ввести несколько правил в конфигурацию вашего сервиса. В отличие от Upstart, где вы могли использовать команды вроде start on (local-filesystems and net-device-added INTERFACE=tun0)
, в systemd
этот процесс включает более детальный подход к зависимостям и управлению услугами.
Шаги для настройки сервиса
-
Создание конфигурационного файла сервиса
Определите конфигурационный файл для вашего сервиса в директории
/etc/systemd/system/
, например,myservice.service
. В этом файле вам нужно будет указать зависимости от интерфейсаtun0
. -
Добавление зависимостей от устройства
Для того чтобы ваш сервис ждал, пока интерфейс
tun0
станет доступен, можно использовать следующие директивы:[Unit] Description=Мой сервис, зависящий от интерфейса tun0 Wants=openvpnxxxx.service After=openvpnxxxx.service After=sys-devices-virtual-net-tun0.device [Service] Type=simple ExecStart=/usr/bin/myservice ExecStartPre=/bin/bash -c "while [ ! -e /sys/class/net/tun0 ]; do sleep 1; done" Restart=on-failure [Install] WantedBy=multi-user.target
Объяснение директив
-
Wants и After: Указывают на зависимость вашего сервиса от
openvpn
и гарантируют, что ваш сервис запустится только после того, какopenvpn
будет активен. -
ExecStartPre: Эта директива используется для предварительной проверки существования интерфейса
tun0
. С помощью циклаwhile
мы можем постоянно проверять наличие устройства, что обеспечивает надежность старта вашего сервиса. -
Restart: Указывает, что сервис должен автоматически перезапускаться в случае ошибки, что полезно, если интерфейс временно недоступен.
Оптимизация процесса
Важно понимать, что время ожидания на создание интерфейса может варьироваться в зависимости от системы и сети. По умолчанию systemd
может давать тайм-аут в 90 секунд для запуска сервиса. Вы можете настроить этот параметр с помощью директивы TimeoutStartSec
в самом сервисе или в общем конфигурационном файле systemd
.
Заключение
Такой подход обеспечивает необходимую связь между вашим сервисом и сетевым интерфейсом tun0
. Не забывайте протестировать конфигурацию после внесенных изменений и активировать ваш сервис командой:
sudo systemctl daemon-reload
sudo systemctl enable myservice
sudo systemctl start myservice
Таким образом, вы сможете гарантировать, что ваш сервис стартует только после завершения и активации соответствующего сетевого интерфейса, что соответствует вашим требованиям и обеспечивает стабильную работу системы.