systemd: o serviço dependente opcional não-executado inesperado é iniciado quando o pai é reiniciado

2

Eu tenho 3 serviços:

  1. ParentService, que fornece o volume do meu aplicativo
  2. DependentServiceA, que é strongmente dependente (ou seja, é efetivamente inútil sem) ParentService em execução. Quando o DependentServiceA está em execução, seu ciclo de vida deve ser vinculado ao ParentService (reiniciado junto, parado juntos).
  3. DependentServiceB, que é pouco dependente (ou seja, a maior parte da funcionalidade está vinculada ao ParentService, mas ainda é útil sem) ParentService. O ciclo de vida de DependentServiceB não deve ser afetado por ParentService (ou DependentServiceA, naturalmente). Deve preferir iniciar após o ParentService.

Comportamento esperado

  • Se o ParentService for iniciado a frio (ou seja, não reiniciado)
    • Não inicie serviços dependentes
  • Se o ParentService for reiniciado
    • Reinicie o DependentServiceA se já estiver em execução; caso contrário, não inicie
    • Não faça nada para DependentServiceB
  • Se ParentService estiver parado
    • Pare o DependentServiceA se já estiver em execução
    • Não faça nada para DependentServiceB

Tudo isso funciona bem em:

  • CentOS 6 (com scripts de inicialização chamados pelo SysVinit)
  • CentOS 7 (com systemd 219)
  • RedHat 7 (com systemd 219)
  • Ubuntu 16.04 LTS (com systemd 229)

O problema

Isso faz não funcionar em:

  • Debian 8 / Jessie (com systemd 215)

No Debian 8, se eu re iniciar o ParentService quando DependentServiceA estiver não em execução, o DependentServiceA será iniciado assim mesmo. Este comportamento não ocorre quando apenas iniciar ParentService.

Eu anexei meus arquivos systemd abaixo para revisão. Tenho quase certeza de que é um problema no arquivo unitário do DependentServiceA, mas admito que não entendo completamente todas as diferenças entre as diretivas de dependência do systemd (por exemplo, BindsTo, PartOf, WantedBy).

ParentService

[Unit]
Description=Parent service
BindsTo=network.target
After=network.target
Before=soss_svc_rest.service dependent_service_b.service

[Service]
Type=forking
ExecStart=/usr/local/foobar/parent_service
KillMode=process
Restart=on-failure
PIDFile=/var/run/parent_service.pid

[Install]
WantedBy=multi-user.target
WantedBy=dependent_service_a.service

DependentServiceA

[Unit]
Description=Dependent Service A
BindsTo=network.target
After=network.target
After=parent_service.service
BindsTo=parent_service.service
PartOf=parent_service.service

[Service]
Type=forking
PIDFile=/var/run/dependent_service_a.pid
ExecStart=/usr/local/foobar/dependent_service_a
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

DependentServiceB

[Unit]
Description=Dependent Service B
BindsTo=network.target
After=network.target
After=parent_service.service

[Service]
Type=forking
PIDFile=/var/run/dependent_service_b.pid
ExecStart=/usr/local/foobar/dependent_service_b
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

Se for relevante, ParentService e DependentServiceB serão marcados como ativados (quero que eles sejam iniciados na inicialização do sistema), mas DependentServiceA é definido como desativado por padrão e deve ser explicitamente iniciado e / ou definido como ativado pelo usuário para iniciar na inicialização do sistema.

O que configurei incorretamente em meus arquivos unitários do systemd que faz com que DependentServiceA seja iniciado quando não estava em execução quando o ParentService é reiniciado? E por que isso só acontece no Debian 8, mas nenhum deles as outras distribuições que testei? É um bug no systemd do Debian 8 (release 215) que foi corrigido entre as versões 216 e 219? (Eu não vi nada relevante no histórico de lançamentos do systemd.)

    
por Aaron Burke 19.04.2018 / 02:26

0 respostas