systemd a unidade pára quando a unidade necessária é interrompida, mas depois não inicia novamente quando a unidade necessária é iniciada

2

Eu tenho uma unidade que só vou chamar eth-service que requer outra unidade que eu chamarei eth-server . No arquivo unitário de eth-service tenho

Requires=eth-server.service
After=eth-server.service

Agora, quando executo systemctl stop eth-server , o eth-service também é interrompido, como deveria. No entanto, mais tarde, quando eu executar systemctl start eth-server , infelizmente, eth-service permanecerá inativo, então tenho que lembrar de reiniciá-lo.

Estou tentando tornar a configuração do meu arquivo de unidade o mais idiota possível (especialmente contra mim) - é possível configurar meus arquivos de unidade para que, quando o servidor for iniciado, o serviço também o faça? Se eu fosse colocar no meu arquivo eth-server unit:

Requires=eth-service.service
Before=eth-service.service

para que eles mutuamente requeiram um ao outro, isso faria com que o serviço fosse inicializado quando o servidor o fizesse, mas também significa que quando eu executo systemctl stop eth-service , então eth-server também pára, já que agora requer o serviço, que não é desejável.

    
por jcarpenter2 29.05.2018 / 00:09

2 respostas

2

Deixe-me ver se entendi o caso de uso:

  1. A partir de eth-service , você deve iniciar os dois eth-server e eth-service .
  2. A partir de eth-server , você deve iniciar os dois eth-server e eth-service .
  3. Parar eth-server deve parar os dois eth-server e eth-service .
  4. Parar eth-service deve APENAS parar eth-service e deixar eth-server em execução.

Você pode conseguir isso adicionando WantedBy=eth-server.service à seção [Install] do arquivo eth-service.service ou Wants=eth-service.service à seção [Unit] do eth-server.service .

De acordo com a documentação do systemd Wants é uma versão mais fraca do Requires , e parece que se Wanted unit for interrompida, a unidade que solicitou não é afetada. Mas pode haver um efeito colateral indesejável nessa configuração, em que eth-server será iniciado, não importando se eth-service não inicia ou não.

Exemplos de arquivos da unidade

Os arquivos da unidade de amostra a seguir podem ser salvos no diretório inicial ( ~/.config/systemd/user ) e usados com o parâmetro systemctl --user .

Os serviços descritos por esses arquivos de unidade não fazem nada, mas o RemainAfterExit=yes força o sistema a assumir que o serviço ainda está em execução, mesmo que o comando /bin/true não permaneça ativo depois de ser executado.

etc-service.service

[Unit]
Description=eth Service
Requires=eth-server.service

[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes

[Install]
WantedBy=eth-server.service

eth-server.service

[Unit]
Description=eth Server

[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes

Ative o módulo eth-service.service com systemctl --user enable eth-service.service .

A seguir, a saída de testes com serviços de início / parada:

Estado inicial

$> systemctl --user status eth-service
● eth-service.service - eth Service
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
   Active: inactive (dead)

$> systemctl --user status eth-server
● eth-server.service - eth Server
  Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
  Active: inactive (dead)

O sistema é retornado ao estado inicial antes que os comandos nas próximas duas seções sejam executados.

systemctl --user inicia o eth-service.service

Ambos server e service são iniciados (ignore as linhas exited : tanto o servidor quanto o serviço são execuções de / bin / true, que sai assim que é concluído, mas os arquivos da unidade são gravados para que acho que os serviços estão em execução até que eles parem)

$> systemctl --user start eth-service.service 
$> systemctl --user status eth-service
● eth-service.service - eth Service
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
   Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 28s ago
  Process: 1578 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1578 (code=exited, status=0/SUCCESS)

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
  Active: active (exited) since Tue 2018-05-29 20:50:01 IST; 2min 59s ago
 Process: 1579 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1579 (code=exited, status=0/SUCCESS)

systemctl --user start eth-server.service

Ambos os serviços são iniciados:

$> systemctl --user start eth-server.service
$> systemctl --user status eth-service
● eth-service.service - eth Service
  Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
  Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 7s ago
 Process: 1681 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1681 (code=exited, status=0/SUCCESS)

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
   Active: active (exited) since Tue 2018-05-29 20:56:03 IST; 12s ago
  Process: 1680 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1680 (code=exited, status=0/SUCCESS)

Os comandos das duas seções a seguir são executados quando os dois serviços estão em execução:

systemctl --user stop eth-server.service

$> systemctl --user status eth-service
● eth-service.service - eth Service
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
   Active: inactive (dead)

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
   Active: inactive (dead)

Você pode ver que ambos os serviços foram interrompidos

systemctl --user stop eth-service

$> systemctl --user stop eth-service
$> systemctl --user status eth-service
● eth-service.service - eth Service
  Loaded: loaded (/home/ektich/.config/systemd/user/eth-service.service; enabled; vendor preset: enabled)
  Active: inactive (dead) since Tue 2018-05-29 21:05:25 IST; 34s ago
 Process: 1800 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1800 (code=exited, status=0/SUCCESS)

May 29 21:04:23 ektich systemd[479]: Starting eth Service...
May 29 21:04:23 ektich systemd[479]: Started eth Service.
May 29 21:05:25 ektich systemd[479]: Stopped eth Service.

$> systemctl --user status eth-server
● eth-server.service - eth Server
   Loaded: loaded (/home/ektich/.config/systemd/user/eth-server.service; static; vendor preset: enabled)
   Active: active (exited) since Tue 2018-05-29 21:04:23 IST; 2min 58s ago
  Process: 1799 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 1799 (code=exited, status=0/SUCCESS)

May 29 21:04:23 ektich systemd[479]: Starting eth Server...
May 29 21:04:23 ektich systemd[479]: Started eth Server.

Você pode ver que eth-service foi interrompido ( Active: inactive (dead) ), mas o eth-server ainda está "em execução" ( Active: active )

O comando de status para etc-service produziu mais resultados em comparação com outros casos, estou assumindo que a "transação" ainda não foi concluída ( etc-server ainda está em execução). As linhas extras de journalctl mostram que, no que diz respeito ao systemd, um dos serviços foi interrompido e o outro ainda está em execução.

PS de acordo com a página inicial do systemd está escrito systemd , não < strong> SystemD (apenas sendo pedante)

    
por 29.05.2018 / 22:17
0

O systemctl start xxx geralmente não reverte os efeitos de um systemctl stop xxx anterior.

Os administradores precisam aprender isso no curso de sua carreira de uma forma ou de outra. A boa notícia é que é muito fácil aprender, porque o feedback é imediato.

Uma maneira de reverter paradas manuais e iniciações manuais é:

systemctl default 

Mas este caminho dificilmente é à prova de erros, pois interrompe serviços que não estão habilitados , como serviços executados em vários clusters (em particular, o marcapasso nem vê como um problema / falha e não reage a ele - trata-o como uma ação administrativa planejada).

Há também systemctl snapshot , mas é ainda mais complicado e, portanto, menos à prova de erros.

O que você pode fazer nos seus serviços (para se tornar mais à prova de erros)? Observe como outros programadores lidaram com isso. Eles evitam dependências e preferem colocar vários processos em um único serviço de guarda-chuva. Na instalação padrão do RHEL7, não há dependências de serviço. Por exemplo, postfix:

$ systemctl status postfix
[...] Tasks: 3
   CGroup: /system.slice/postfix.service
           ├─1288 /usr/libexec/postfix/master -w
           ├─1290 qmgr -l -t unix -u
           └─7340 pickup -l -t unix -u

$ cat /usr/lib/systemd/system/postfix.service
[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service

[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop

[Install]
WantedBy=multi-user.target
    
por 29.05.2018 / 11:31

Tags