Как создать виртуальную службу systemd для одновременной остановки/запуска нескольких экземпляров?

Как создать виртуальную службу systemd для одновременной остановки/запуска нескольких экземпляров?

Я планирую разместить несколько экземпляров одного и того же веб-приложения для клиентов, использующих systemd. Я хотел бы иметь возможность stopи startкаждый экземпляр клиента, использующий systemd, а также обрабатывать всю коллекцию экземпляров клиентов как единую службу, которую можно останавливать и запускать вместе.

systemdкажется, предоставляет необходимые мне строительные блоки с использованием PartOf, и файлов шаблонов единиц, но пошел я останавливаю родительскую службу, дочерняя служба клиентов не останавливается. Как мне заставить это работать с systemd? Вот что у меня есть на данный момент.

Файл родительского блока app.service:

[Unit]
Description=App Web Service

[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal

Файл шаблона блока с именем [email protected], используемый для создания экземпляров клиентов:

[Unit]
Description=%I Instance of App Web Service

[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal

Мой app-poc.shскрипт (доказательство концепции, который просто печатает в файл журнала в цикле):

#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
  echo "The App PoC loop for $@"
  sleep 2;
done

Для подтверждения концепции у меня есть файлы модулей systemd в формате ~/.config/systemd/user.

Затем я запускаю родительский объект и экземпляр на основе шаблона (после systemctl --user daemon-reload):

systemctl --user start app
systemctl --user start [email protected]

Из использования journalctl -fя вижу, что оба запущены и что экземпляр клиента продолжает работать. Теперь я ожидаю, что выключение родителя остановит потомка (потому что я использовалPartOf), но этого не происходит. Кроме того, запуск родителя также не запускает потомка, как ожидается.

systemctl --user stop app

Спасибо!

(Я использую Ubuntu 16.04 с systemd 229).

решение1

Я узнал, что для этого нужны systemd "Target Units". Используя Target Unit, я получаю желаемые преимущества без необходимости создания поддельного [Service]раздела, который я привел выше. Рабочий пример файла "Target Unit" выглядит так:

# named like app.target
[Unit]
Description=App Web Service

# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target

Затем каждый экземпляр клиента должен включать PartOfв себя [Unit]раздел (как указал @meuh), а также должен иметь [Install]раздел, который enableбудет disableработать с определенной службой:

# In a file name like [email protected]
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target

[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal

# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp

# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target

Чтобы вызвать экземпляр клиента и запустить его при запуске цели, используется эта одноразовая команда включения:

 systemctl enable app

Теперь на этом этапе я могу использовать и stopдля конкретного экземпляра или могу использовать и для остановки всех приложений одновременно.startapp@customerstart appstop app

решение2

Вам нужно переместить линию.

PartOf=app.service

из раздела [Service]и в [Unit]раздел, и добавьте в [Unit]список app.serviceклиентов, чтобы начать, например

[email protected] [email protected]

или как сказал sourcejedi в комментариях, Requires=то же самое. Вы можете сохранить, PartOfчтобы остановить службы, которые вы запускаете вручную, которые не указаны в списке выше, например .systemctl --user start [email protected]

Связанный контент