Como faço para que determinados serviços dependam de determinadas interfaces?

Como faço para que determinados serviços dependam de determinadas interfaces?

Com o SystemD, como posso tornar determinados serviços dependentes da ativação de determinadas interfaces de rede?

Por exemplo, digamos que eu tenha uma interface bond 802.1ad e preciso aguardar o acesso ao meu SAN/NAS antes de abrir libvirtd, mesmo que eu possa ter acesso à rede disponível por meio de uma interface diferente. Ou digamos que eu tenha uma sshfsmontagem que desejo montar automaticamente (e ser desmontada automaticamente) dependendo de uma conexão VPN?

Qual é a maneira idiomática de lidar com dependências refinadas em interfaces de rede?

No momento, estou usando o NetworkManager no Ubuntu e no CentOS7, mas estou aberto a outros mecanismos apropriados à plataforma para gerenciar o estado da rede.

Responder1

Acho que não existe realmente um padrão integrado, mas há algumas coisas que você pode aproveitar systemd.

ExecStartPre=

Comandos adicionais que são executados antes [...] do comando em ExecStart=, respectivamente. A sintaxe é a mesma de ExecStart=, exceto que múltiplas linhas de comando são permitidas e os comandos são executados um após o outro, em série.

Se algum desses comandos (não prefixados com "-") falhar, os demais não serão executados e a unidade será considerada com falha.

Reiniciar = em caso de falha

Configura se o serviço deve ser reiniciado quando o processo do serviço é encerrado, encerrado ou quando o tempo limite é atingido.

Se definido como em caso de falha, o serviço será reiniciado quando o processo terminar com um código de saída diferente de zero, for encerrado por um sinal (inclusive no core dump, mas excluindo os quatro sinais mencionados acima), quando uma operação (como serviço reload) expira e quando o tempo limite do watchdog configurado é acionado.


Os comandos são considerados falhados se retornarem códigos de saída diferentes de zero; portanto, ao definir o ExecStartPrecomo algo que prova que sua interface está ativa, você pode ter certeza de que seu serviço exigirá isso.

Alguns exemplos:

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

ExecStartPre=/usr/sbin/iscsiadm -m session

Pessoalmente, gosto da iscsiadmvariante para o seu caso de uso. Se houver conexões iscsi, o valor de retorno será 0; caso contrário, retornará 21 (o que causaria falha no serviço). A pingvariante pode funcionar para uma variedade maior de usos, mas eu diria que na maioria dos casos você pode querer encontrar um comando mais adequado para verificar o status da rede. Você pode até tentar usar sshse tiver chaves configuradas para verificar coisas em outro host.

A questão é que ExecStartPrevocê pode fazer seu serviço falhar com base em qualquer comando. Apenas verifique se qualquer comando usado retornará códigos de saída diferentes de zero quando você desejar (por exemplo, catexecutar um arquivo vazio retorna 0, enquanto catexecutar um arquivo inexistente retorna 1)


Depois de alguma consideração e do comentário do autor da pergunta, eu diria que omelhorUma maneira de definir uma condição complexa para um serviço é criar outro serviço do qual ele dependa.

Crie um novo serviço que use o comando para verificar o status do arquivo ExecStart. Dê o Restart=on-failure. Então faça seu serviço original Requiree Afterpronto.

O ExecStartPreexemplo que usei acima está distorcendo seu propósito original, que era configurar as coisas para que o serviço funcionasse corretamente. Ele ainda pode ser aplicado e o conhecimento ainda é útil, então estou deixando-o intacto.

informação relacionada