
Ich plane, mehrere Instanzen derselben Web-App für Kunden zu hosten, die verwenden systemd
. Ich möchte in der Lage sein stop
, start
jede Kundeninstanz mithilfe von zu verwalten systemd
und die gesamte Sammlung von Kundeninstanzen als einen einzigen Dienst zu behandeln, der gemeinsam gestoppt und gestartet werden kann.
systemd
scheint die Bausteine bereitzustellen PartOf
, die ich mithilfe von und Vorlagen-Unit-Dateien brauche, aber wenn ich den übergeordneten Dienst stoppe, wird der untergeordnete Kundendienst nicht gestoppt. Wie kann ich das mit systemd zum Laufen bringen? Hier ist, was ich bisher habe.
Die übergeordnete Unit-Datei 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
Eine Unit-Vorlagendatei mit dem Namen [email protected]
, die zum Erstellen von Kundeninstanzen verwendet wird:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
Mein app-poc.sh
Skript (Proof of Concept, der einfach in einer Schleife in eine Protokolldatei druckt):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
Für den Proof of Concept habe ich die Systemd-Unit-Dateien in ~/.config/systemd/user
.
Ich starte dann das übergeordnete Element und eine auf der Vorlage basierende Instanz (nachher systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start [email protected]
Durch die Verwendung journalctl -f
kann ich sehen, dass beide gestartet wurden und dass die Kundeninstanz weiterhin ausgeführt wird. Jetzt gehe ich davon aus, dass das Herunterfahren des übergeordneten Elements das untergeordnete Element stoppt (weil ich verwendet habePartOf
), aber das ist nicht der Fall. Außerdem wird beim Starten des übergeordneten Elements das untergeordnete Element nicht wie erwartet gestartet.
systemctl --user stop app
Danke!
(Ich verwende Ubuntu 16.04 mit systemd 229).
Antwort1
Ich habe gelernt, dass dies der Zweck der systemd-Zieleinheiten ist. Durch die Verwendung einer Zieleinheit erhalte ich die gewünschten Vorteile, ohne den [Service]
oben beschriebenen Fake-Abschnitt erstellen zu müssen. Eine funktionierende Beispieldatei einer Zieleinheit sieht folgendermaßen aus:
# named like app.target
[Unit]
Description=App Web Service
# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target
Dann sollte jede Kundeninstanz PartOf
den [Unit]
Abschnitt enthalten (wie von @meuh angemerkt) und sollte auch einen [Install]
Abschnitt haben, damit an dem spezifischen Dienst gearbeitet werden kann 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
Um die Kundeninstanz aufzurufen und sie beim Start des Ziels starten zu lassen, wird dieser einmalige Aktivierungsbefehl verwendet:
systemctl enable app
Jetzt kann ich an dieser Stelle stop
und start
zum Stoppen app@customer
einer bestimmten Instanz verwenden oder und , start app
um stop app
alle Apps gleichzeitig zu stoppen.
Antwort2
Sie müssen die Linie verschieben
PartOf=app.service
aus [Service]
und in den [Unit]
Abschnitt, und fügen Sie die [Unit]
der app.service
Liste der Kunden zu starten, zB
[email protected] [email protected]
oder wie sourcejedi in den Kommentaren sagte, Requires=
dasselbe. Sie können die behalten, PartOf
um Dienste zu stoppen, die Sie manuell starten und die nicht in der obigen Liste enthalten sind, wie .systemctl --user start [email protected]