Can systemd manage a pipeline?

Can systemd manage a pipeline similar to how the daemontools family does it? And if so, what's the best way to achieve this?

I want to run the equivalent of service1 | service2 where both service1 and service2 are (separate or not) services managed by systemd.

I would like to be able to restart the service2 process without interrupting service1. In other words, the file descriptor to which service1 is writing must not be closed when service2 exits. When a new instance of service2 starts, it should inherit the existing file descriptor so that stdout from service1 will flow into the new service2. (Much like daemontools maintains a pipe between run and log/run, though the pipeline need not be a service and a logger.)

Perhaps something with a systemd-managed FIFO in between?

1
задан 1 September 2016 в 06:53
2 ответа

Наконец-то у меня появилась возможность и необходимость пройти через это самостоятельно. Мое решение требует поддержки опции fd к StandardOutput=, которая доступна в (как минимум) systemd версии 232, но не в версии 215.

Есть три сервиса и два FIFO. Вместе они создают поток -вход | -фильтр | -выход , и любая часть потока может быть перезапущена по отдельности без потери данных.

-вход -вход записывает в FIFO, из которого считывается -фильтр , который, в свою очередь, записывает в FIFO, из которого считывается -выход .

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
4
ответ дан 3 December 2019 в 17:04

Попросите службу записать в стандартный вывод и настройте StandardOutput в файле модуля systemd, чтобы служба записывала в журнал:

http://0pointer.de/public/systemd-man /systemd.exec.html

Это делает журналы доступными для службы journald, которая предлагает другие варианты использования журналов.

http://0pointer.de/public/systemd-man/journald.conf.html

Пользовательский «регистратор» может быть клиентом journald и может напрямую извлекать из журнала, а если недоступно, из восходящего потока сервис конечно не влияет.Регистратор также может быть настроен с его собственным файлом модуля, поэтому им управляет systemd.

1
ответ дан 3 December 2019 в 17:04

Теги

Похожие вопросы