... Уже несколько раз сталкивался с ситуацией, при которой одновременно выполняются три условия.
- В сетевом демоне явно прописан unicast bind address (не [::] и не 0.0.0.0).
- Используется конфигуратор сети, отличный от systemd (например, netplan или ifupdown2).
- Демон успевает стартовать раньше, чем закончится конфигурация сетевых интерфейсов ("race condition").
В таком случае демон просто вывалится с ошибкой и не запустится, потому что не сможет выполнить bind() на запрошенный адрес.
Есть четыре способа решения разной степени упоротости.
- Самый очевидный: использовать в конфигурации демонов bind to all interfaces ("0.0.0.0"). Прекрасно, но не всегда приемлемо.
- Очевидный: использовать systemd-networkd для конфигурации сетевых интерфейсов. Прямолинейно, кондово, надежно, но далеко не всегда удобно.
- Сказать ядру, чтобы разрешало приложениям вызовы bind() для адресов, которых не существует. Есть там такие параметры в sysctl. Теоретически можно, но не рекомендуется так делать.
- Использовать специально обученный сервис "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. Некоторое время спустя дед Сергеич понял, что написал выше полную брехню. Скоро выйдет псто с опровержением / уточнением. Сорян, так тоже бывает.