Как сделать определенные службы зависимыми от определенных интерфейсов?

Как сделать определенные службы зависимыми от определенных интерфейсов?

Как с помощью SystemD сделать определенные службы зависимыми от работоспособности определенных сетевых интерфейсов?

Например, предположим, что у меня есть интерфейс связи 802.1ad, и мне нужно дождаться доступа к моему SAN/NAS, прежде чем я подниму libvirtd, даже если у меня может быть сетевой доступ через другой интерфейс. Или, предположим, у меня есть крепление, sshfsкоторое я хочу автоматически поднять (и автоматически отключить) в зависимости от VPN-подключения?

Каков идиоматический способ обработки детальных зависимостей на сетевых интерфейсах?

В настоящее время я использую NetworkManager на Ubuntu и CentOS7, но я открыт для других механизмов управления состоянием сети, подходящих для других платформ.

решение1

Я не думаю, что существует какой-то стандартный встроенный подход, но есть несколько вещей, которые вы можете использовать systemd.

ExecStartPre=

Дополнительные команды, которые выполняются перед [...] командой в ExecStart=, соответственно. Синтаксис такой же, как для ExecStart=, за исключением того, что допускается несколько командных строк, и команды выполняются одна за другой, последовательно.

Если какая-либо из этих команд (не имеющая префикса «-») не выполняется, остальные не выполняются, и устройство считается неисправным.

Перезапуск=при сбое

Настраивает, будет ли служба перезапущена при завершении процесса службы, его завершении или достижении тайм-аута.

Если установлено значение «on-failure», служба будет перезапущена, когда процесс завершается с ненулевым кодом выхода, завершается сигналом (включая дамп ядра, но за исключением четырех вышеупомянутых сигналов), когда истекает время ожидания операции (например, перезагрузки службы) и когда срабатывает настроенный тайм-аут сторожевого таймера.


Команды считаются невыполненными, если они возвращают ненулевые коды завершения, поэтому, установив значение ExecStartPre, подтверждающее работоспособность вашего интерфейса, вы можете быть уверены, что это потребуется вашей службе.

Некоторые примеры:

ExecStartPre=/usr/bin/ping -c 1 ${SAN_IP}

ExecStartPre=/usr/sbin/iscsiadm -m session

Мне лично нравится iscsiadmвариант для вашего варианта использования. Если есть соединения iscsi, возвращаемое значение равно 0, в противном случае возвращается 21 (что приведет к сбою службы). Вариант pingможет работать для большего разнообразия применений, но я бы сказал, что в большинстве случаев вам может понадобиться найти более подходящую команду для проверки состояния сети. Вы даже можете попробовать использовать, sshесли у вас есть настройка ключей, чтобы проверить что-то на другом хосте.

Суть в том, что это ExecStartPreможет позволить вам сделать так, чтобы ваша служба перестала работать на основе любых команд. Просто проверьте, что любая используемая вами команда будет возвращать ненулевые коды выхода, когда вы этого хотите (например, cating пустого файла возвращает 0, тогда как cating несуществующего файла возвращает 1)


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

Создайте новую службу, которая использует команду для проверки статуса как ExecStart. Дайте ей Restart=on-failure. Затем создайте свою оригинальную службу Requireи Afterее.

Пример ExecStartPre, который я использовал выше, как бы искажает его изначальную цель, которая заключалась в настройке всего для правильной работы сервиса. Его все еще можно применять, и знания все еще полезны, поэтому я оставляю его нетронутым.

Связанный контент