Pode o systemd gerenciar um pipeline?

1

O systemd pode gerenciar um pipeline semelhante a como a família daemontools faz isso? E se sim, qual é a melhor maneira de conseguir isso?

Eu quero executar o equivalente a service1 | service2 em que ambos os serviços service1 e service2 são (separados ou não) gerenciados pelo systemd.

Gostaria de poder reiniciar o processo service2 sem interromper service1 . Em outras palavras, o descritor de arquivo para o qual service1 está escrevendo não deve ser fechado quando service2 sair. Quando uma nova instância de service2 for iniciada, ela deverá herdar o descritor de arquivo existente para que o stdout de service1 flua para o novo service2 . (Assim como o daemontools mantém um pipe entre run e log/run , embora o pipeline não precise ser um serviço e um registrador.)

Talvez algo com um FIFO gerenciado pelo systemd entre eles?

    
por Patrick 22.07.2016 / 13:40

2 respostas

4

Finalmente tive a oportunidade e a necessidade de trabalhar com isso sozinho. Minha solução requer suporte para a opção fd para StandardOutput= , que está disponível no (pelo menos) systemd versão 232 mas não na versão 215.

Existem três serviços e dois FIFOs. Juntos, eles criam o pipeline input | filter | output e qualquer parte do pipeline pode ser reiniciada individualmente sem perda de dados.

O processo input grava em um FIFO do qual filter lê, que por sua vez grava em um FIFO que output lê.

input.service

[Unit]
Description=The input process
Requires=filter.socket
After=filter.socket

Wants=filter.service output.service

[Service]
TimeoutStartSec=infinity

Sockets=filter.socket

StandardInput=null
StandardOutput=fd:filter.socket
StandardError=journal
ExecStart=/path/to/input

Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target

filter.service

[Unit]
Description=The filter process
Requires=filter.socket output.socket
After=filter.socket output.socket

[Service]
TimeoutStartSec=infinity

Sockets=filter.socket
Sockets=output.socket

StandardInput=fd:filter.socket
StandardOutput=fd:output.socket
StandardError=journal
ExecStart=/path/to/filter

Restart=always
RestartSec=5s

filter.socket

[Unit]
Description=Filter process reads from this

[Socket]
ListenFIFO=/run/filter
SocketMode=0600
RemoveOnStop=false

output.service

[Unit]
Description=The output process
Requires=output.socket
After=output.socket

[Service]
TimeoutStartSec=infinity

Sockets=output.socket

StandardInput=fd:output.socket
StandardOutput=journal
StandardError=journal
ExecStart=output

Restart=always
RestartSec=5s

output.socket

[Unit]
Description=Output process reads from this

[Socket]
ListenFIFO=/run/output
SocketMode=0600
RemoveOnStop=false
    
por 03.01.2017 / 23:36
1

Faça o serviço gravar no stdout e configure o StandardOutput no arquivo de unidade do systemd para que o serviço grave no diário:

link

Isso torna os logs disponíveis para o serviço journald, que oferece outras opções para o consumo de log.

link

Um "logger" personalizado pode ser um cliente de journald e pode extrair diretamente do diário e, se não estiver disponível, o serviço de upstream obviamente não será afetado. O registrador também pode ser configurado com seu próprio arquivo de unidade, portanto, ele é gerenciado pelo systemd.

    
por 27.08.2016 / 13:58