Как гарантировать запуск сервиса после полной инициализации сети в Linux (systemd)

Оцените статью

Вы настроили сервис так, чтобы он запускался после network.target, но он всё равно стартует до полной готовности сети? Разберёмся, почему так происходит и как это исправить.

Почему «сеть готова» — понятие неоднозначное

В скриптах LSB (Linux Standard Base) используется понятие $network — условный маркер готовности сети. Однако его трактовка крайне расплывчата. Разные системы могут считать «готовность сети» выполненной при следующих условиях:

  • запущен софт для управления сетью;
  • все настроенные сетевые интерфейсы активны и имеют IP‑адреса;
  • доступен DNS‑сервер;
  • доступен определённый сервер (специфичный для конкретной инфраструктуры);
  • есть выход в Интернет;
  • настроен хотя бы один глобальный IPv4‑ или IPv6‑адрес и т. д.

Из‑за такой неоднозначности $network не может служить универсальным критерием.

Динамичность современных сетей

Современные сетевые среды крайне динамичны:

  • устройства перемещаются между сетями;
  • конфигурация сети меняется;
  • добавляется и удаляется оборудование;
  • создаются и удаляются виртуальные сети.

Поэтому ПО должно уметь работать с изменяющейся конфигурацией:

  • реагировать на изменения настроек сети;
  • повторять попытки подключения при временных сбоях;
  • корректно обрабатывать потерю соединения.

Хорошо написанное ПО стартует в любое время и адаптируется к текущим условиям.

Как работает сеть в systemd: три ключевых target

В systemd роль $network выполняют три целевых юнита:

  1. network.target
  • Суть: сигнализирует, что стек управления сетью запущен.
  • Важно: не гарантирует, что интерфейсы настроены и имеют IP‑адреса.
  • Назначение: упорядочивание остановки сервисов при выключении системы. Сервисы с After=network.target останавливаются до отключения сети, что позволяет корректно завершить соединения.
  • Особенности: пассивный юнит — его нельзя запустить напрямую. Сервисы должны указывать After=network.target, но не Wants= или Requires=.
  1. network-online.target
  • Суть: активно ждёт, пока сеть не будет «готова» (определение «готовности» зависит от ПО управления сетью, обычно это наличие настроенного маршрутизируемого IP‑адреса).
  • Назначение: задержка активации сервисов до полной настройки сети.
  • Особенности: активный юнит — может быть вызван сервисами, которым нужна готовая сеть. По умолчанию его используют удалённые монтирования из /etc/fstab. Не рекомендуется для серверного ПО, которое может работать с локальными подключениями.
  • Таймаут: 90 секунд.
  1. network-pre.target
  • Суть: позволяет запускать сервисы до настройки сетевых интерфейсов.
  • Назначение: используется, например, для фаерволов, которые нужно настроить до активации интерфейсов.
  • Особенности: пассивный юнит. Сервисы, которые должны стартовать до настройки сети, указывают Before=network-pre.target и Wants=network-pre.target.

Как заставить сервис стартовать после полной готовности сети

Чтобы сервис запускался только после того, как сеть полностью настроена, добавьте в его .service-файл следующие строки:

After=network-online.target
Wants=network-online.target

Это гарантирует, что все настроенные сетевые устройства активны и имеют IP‑адреса до старта сервиса.

Важно: также нужно активировать соответствующий «ожидающий» сервис:

  • NetworkManager-wait-online.service — если используется NetworkManager;
  • systemd-networkd-wait-online.service — если используется systemd-networkd.

Проверить активацию можно командой:

# systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service

Рекомендации для разработчиков

Вместо того чтобы полагаться на network.target, лучше сделать ваше ПО устойчивым к динамическим изменениям сети. Это:

  • повысит удовлетворённость пользователей;
  • сократит количество отчётов об ошибках;
  • ускорит загрузку системы.

Возможные подходы:

  1. Отслеживать изменения сети через rtnetlink. Это наиболее элегантное, но не всегда простое решение.
  2. Для серверного ПО: слушать псевдоадреса [::], [::1], 0.0.0.0 и 127.0.0.1. Они всегда доступны, поэтому код не нужно адаптировать под изменения сети.
  3. Использовать IP_FREEBIND. Этот механизм ядра Linux позволяет привязываться к адресу, даже если он ещё не настроен локально. Это делает код устойчивым к изменениям конфигурации сети.

Вывод

В современных динамических сетях лучше писать ПО, которое адаптируется к изменениям, а не ждёт фиксированного состояния «сеть готова». Если же требуется явная задержка старта сервиса, используйте network-online.target с соответствующим «ожидающим» сервисом.

Related Posts

Отправка сообщений из Zabbix в VK Teams

Так получилось, что этих самых мессенджеров развелась уже целая куча и только ленивый не написал свой и в текущем моем проекте в качестве корп-мессенджера используется VK Teams. Встроенного плагина для…

Настройка SoftEther VPN Bridge

Для объединения нескольких географически распределенных подсетей при помощи SoftEther используется компонент SoftEther VPN Bridge и сегодня мы в краце рассмотрим как настроить объединение несколько виртуальных сетей (LXD хост). Подготовка сети…

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

You Missed

Отправка сообщений из Zabbix в VK Teams

Отправка сообщений из Zabbix в VK Teams

Как гарантировать запуск сервиса после полной инициализации сети в Linux (systemd)

Как гарантировать запуск сервиса после полной инициализации сети в Linux (systemd)
Настройка SoftEther VPN Bridge

Установка и настройка Zabbix-Proxy

Установка и настройка Zabbix-Proxy
NetPlan работа с сетевыми мостами
Проект Rain (Часть первая)