Systemd - inicia o serviço somente depois que o DNS estiver disponível

1

Eu tenho alguns serviços, principalmente nginx e ntpd, que dependem de ter uma resolução de DNS em funcionamento para iniciar corretamente. No momento, nenhum desses serviços é iniciado corretamente no momento da inicialização, mas é iniciado corretamente quando intervêm manualmente quando a máquina é ativada, com algumas mensagens nos logs sobre a impossibilidade de resolver nomes.

Isso me leva a acreditar que estou tendo uma condição de corrida com systemd. Meus servidores apontam para 127.0.0.1 para seus servidores de nomes. Ligado ao localhost: 53 é o pdns-recursor. Eu configurei o ntp e o nginx como WantedBy pdns-recursor em seus arquivos unitários da seguinte forma

[Unit]
WantedBy=pdns-recursor.service

No entanto, ainda recebo mensagens de log em nginx e ntp sobre a falha em resolver nomes no momento da inicialização.

Como posso verificar se o DNS está completamente ativo antes que esses serviços tentem iniciar? Estou usando o Ubuntu 16.04

Aug 09 22:35:25 host.blah ntpd[3574]: restrict: ignoring line 21, address/host 'ntp.blah' unusable.
Aug 09 22:35:26 host.blah ntpd[3574]: restrict: ignoring line 23, address/host 'ntp.blah' unusable.
Aug 09 22:35:28 host.blah ntpd[3574]: restrict: ignoring line 25, address/host 'ntp.blah' unusable.
Aug 09 22:35:29 host.blah ntpd[3574]: restrict: ignoring line 27, address/host 'ntp.blah' unusable.
    
por Brando__ 10.08.2017 / 00:58

4 respostas

1

Não é uma solução adequada para o meu problema e quase certamente não passará na revisão do meu código, mas talvez seja útil para outra pessoa.

Eu coloquei um pré-requisito de exec exec em meus arquivos de unidade ntp e nginx para continuar tentando resolver um nome antes de continuar.

ExecStartPre=/bin/bash -c 'until host example.com; do sleep 1; done'
    
por 10.08.2017 / 04:35
2

Tente usar:

[Unit]
After=network-online.target
Wants=network-online.target

Há um artigo completo em Unix & ; Linux , bem como no site FreeDesktop .

    
por 10.08.2017 / 05:33
1

Portanto, tenho o mesmo dilema com uma unidade cifs de montagem remota que precisa ser montada via FQDN do DNS em vez de IP. Eu tentei um monte de coisas, mas até agora eu tenho que concordar com a solução de Brando (curto de escrever um serviço Systemd inteiro e puxá-lo antes do .mount ou network-online.target).

A única alternativa para Brando que eu encontrei (que realmente funciona na prática, ao invés de apenas em teoria nas man pages) é golpear a mosca com uma marreta, e colocar um ExecStartPre = em systemd-networkd-wait-online.service:

[Service]
...
ExecStartPre=/bin/sleep 15

Se você estiver interessado, você também pode acrescentar ao ExecStart = usando - interface = nome_da_interface (e opcionalmente --timeout = ). Isso ajuda porque eu tenho uma sub-interface vlan, mas o wait-online estava apenas rastreando o primeiro de qualquer interface (excluindo o loop) que viria online. Por si só, não resolveu o problema.

Eu pensei em usar -o _netdev dentro da definição de montagem do / etc / fstab que iria consertar (e em teoria nas unidades remotas do Systemd esperar pela rede online. alvo por padrão), mas, infelizmente, não há dados. Listar as dependências do arquivo mnt-remote.mount resultante mostra que network-online.target é um precursor, mas o DNS ainda falha. A execução manual da inicialização do posto de serviço funciona bem, estou apenas me ferrando com algum tipo de condição de corrida entre o destino chegando e o DNS realmente resolvendo antes do processo de montagem acontecer. Isso e o fato de que a definição de uma interface 'online' varia de pessoa para pessoa e caso a caso (meu caso de uso requer DNS, outros obviamente não o são - um tópico que é amplamente abordado no FreeDesktop: link ).

A solução de Brando é mais elegante. Este também precisa testar um erro para minimizar o tempo de inatividade, mas ainda assim ele funcionará de forma confiável, sujeito ao tempo que o DHCP / DNS / NIC demora para resolver tudo.

Eu uso isso como uma solução inferior, para o caso do Brando não funcionar para você por algum motivo.

Outra solução seria digitar uma entrada no arquivo de hosts locais, mas eu não estava interessado em fazer isso para um caso em que o IP para o FQDN muda em uma base relativamente freqüente (problema semelhante com apenas montá-lo usando o IP em primeiro lugar).

    
por 28.09.2018 / 15:59
0

Concordo com o seu diagnóstico de condição de corrida ... a menos que as dependências sejam explicitamente configuradas, o systemd tentará iniciar esses serviços em paralelo. Mas eu não acho que a diretiva WantedBy irá ajudá-lo, já que isso afeta as dependências de instalação, não as dependências de inicialização, por esta página de manual .

Acho que o que você está procurando é uma combinação da diretiva Wants e da diretiva After. Para cada ntp e nginx, acho que você deseja adicionar o seguinte ao seu arquivo de unidade:

Wants=pdns-recursor.service
After=pdns-recursor.service

Essas duas opções devem garantir que o serviço DNS seja iniciado antes do serviço ntp / nginx, que deve resolver sua corrida.

Sendo um tipo de cinto e suspensórios, eu recomendaria colocar seu nome / mapeamento IP em seu arquivo / etc / hosts; Dessa forma, os outros serviços podem ser iniciados mesmo que seu DNS falhe. Se você realmente quiser tentar usar o DNS em vez de arquivos estáticos, poderá alternar a ordem de resolução.

    
por 10.08.2017 / 03:08