systemd-networkd-wait-online

May 17, 2024 18:27


... Уже несколько раз сталкивался с ситуацией, при которой одновременно выполняются три условия.
  • В сетевом демоне явно прописан unicast bind address (не [::] и не 0.0.0.0).
  • Используется конфигуратор сети, отличный от systemd (например, netplan или ifupdown2).
  • Демон успевает стартовать раньше, чем закончится конфигурация сетевых интерфейсов ("race condition").

В таком случае демон просто вывалится с ошибкой и не запустится, потому что не сможет выполнить bind() на запрошенный адрес.

Есть четыре способа решения разной степени упоротости.
  1. Самый очевидный: использовать в конфигурации демонов bind to all interfaces ("0.0.0.0"). Прекрасно, но не всегда приемлемо.
  2. Очевидный: использовать systemd-networkd для конфигурации сетевых интерфейсов. Прямолинейно, кондово, надежно, но далеко не всегда удобно.
  3. Сказать ядру, чтобы разрешало приложениям вызовы bind() для адресов, которых не существует. Есть там такие параметры в sysctl. Теоретически можно, но не рекомендуется так делать.
  4. Использовать специально обученный сервис "systemd-networkd-wait-online.service". На мой взгляд, самый оптимальный вариант.

Для этого нужно сделать два шага.

Первый:

systemctl enable systemd-networkd-wait-online

Второй: дописать в systemd-юнит интересующего нас демона вот такое.

[Unit]
Wants=systemd-networkd-wait-online.service
After=systemd-networkd-wait-online.service

Собственно, всё. После перезагрузки системы какой-нибудь условный NginX стартует с некоторой задержкой, зато без вот этих приколов типа "nginx: [emerg] bind() to [2001:41d0:601:1100::5e]:443 failed (99: Cannot assign requested address)".

UPDATE. Некоторое время спустя дед Сергеич понял, что написал выше полную брехню. Скоро выйдет псто с опровержением / уточнением. Сорян, так тоже бывает.

hints, linux, сети, памятка

Previous post Next post
Up