¿Cómo crear un servicio virtual systemd para detener/iniciar varias instancias juntas?

¿Cómo crear un servicio virtual systemd para detener/iniciar varias instancias juntas?

Planeo alojar varias instancias de la misma aplicación web para clientes que usan systemd. Me gustaría poder stoputilizar startcada instancia de cliente systemd, así como tratar toda la colección de instancias de cliente como un único servicio que se puede detener e iniciar juntos.

systemdParece proporcionar los componentes básicos que necesito para usar PartOfy los archivos unitarios de plantilla, pero detuve el servicio principal, el servicio al cliente secundario no se detiene. ¿Cómo puedo hacer que esto funcione con systemd? Esto es lo que tengo hasta ahora.

El archivo de la unidad de padres 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

Un archivo de plantilla de unidad denominado [email protected], que se utiliza para crear instancias de clientes:

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

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

Mi app-poc.shscript (prueba de concepto que simplemente se imprime en el archivo de registro en un bucle):

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

Para la prueba de concepto, tengo los archivos de la unidad systemd en formato ~/.config/systemd/user.

Luego inicio el padre y una instancia basada en la plantilla (después systemctl --user daemon-reload):

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

Desde el uso journalctl -fpuedo ver que ambos comenzaron y que la instancia del cliente continúa ejecutándose. Ahora espero que apagar al padre detenga al niño (porque uséPartOf), pero no es así. Además, iniciar al padre tampoco inicia al hijo como se esperaba.

systemctl --user stop app

¡Gracias!

(Estoy usando Ubuntu 16.04 con systemd 229).

Respuesta1

Aprendí que para eso sirven las "Unidades de destino" de systemd. Al utilizar una Unidad objetivo, obtengo los beneficios que deseo sin necesidad de crear la [Service]sección falsa que tenía arriba. Un archivo de ejemplo funcional de "Unidad de destino" se ve así:

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

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

Luego, cada instancia de cliente debe incluirse PartOfen la [Unit]sección (como lo señala @meuh), y también debe tener una [Install]sección para que enablefuncione disableen el servicio específico:

# 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

Para abrir la instancia del cliente y hacer que se inicie cuando se inicia el destino, se utiliza este comando de habilitación único:

 systemctl enable app

Ahora, en este punto, puedo usar stopy startpara app@customeruna instancia específica, o puedo usar start appy stop apppara detener todas las aplicaciones juntas.

Respuesta2

Necesitas mover la línea

PartOf=app.service

fuera [Service]y dentro de la [Unit]sección, y agregue a la [Unit]lista app.servicede clientes para comenzar, por ejemplo

[email protected] [email protected]

o como dijo sourcejedi en los comentarios, Requires=lo mismo. Puedes conservar los PartOfservicios que inicias manualmente y que no están en la lista anterior, como .systemctl --user start [email protected]

información relacionada