Frage Starten Sie N Prozesse mit einer Systemd Service Datei


Ich fand diese Systemd-Dienstdatei, um autosh zu starten, um einen SSH-Tunnel aufrechtzuerhalten: https://gist.github.com/thomasfr/9707568

[Unit]
Description=Keeps a tunnel to 'remote.example.com' open
After=network.target

[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa

[Install]
WantedBy=multi-user.target

Gibt es eine Möglichkeit, systemd so zu konfigurieren, dass mehrere Tunnel gestartet werden? ein Bedienung.

Ich möchte keine N System Service Dateien erstellen, da ich Copy + Paste vermeiden möchte.

Alle Servicedateien wären identisch, außer dass "remote.example.com" durch andere Hostnamen ersetzt würde.

1,5 Jahre später ...

Ich habe diese Frage vor etwa 1,5 Jahren gestellt.

Mein Verstand hat sich ein bisschen verändert. Ja, es ist schön, dass Sie das mit Systemd machen können (ich benutze es immer noch), aber ich werde in Zukunft das Konfigurations-Management verwenden.

Warum sollte systemd eine Template-Sprache implementieren und% h ersetzen?

Einige Monate später sollte diese Schleife und das Templating mit einem Tool gelöst werden, das die Konfiguration automatisiert. Ich benutze ein Werkzeug davon Liste bei Wikipedia jetzt.


26
2017-10-20 14:13


Ursprung


Mit anderen Worten, Sie sagen, verwenden Sie ein Konfigurations-Management-System, um mehrere fast identische Service-Dateien zu generieren, um diese Aufgabe zu erfüllen? Hmmm vielleicht. Wie bei den meisten derartigen Themen gibt es keine klare Trennlinie zwischen diesen. - pgoetz
@pgoetz config management ist noch neu für mich, aber es hat einen Vorteil, wenn Sie sich das Thema dieser Frage ansehen: Wenn Sie sich das Ergebnis der Konfigurationsverwaltung anschauen, wird jeder, der Systemd-Service-Dateien kennt, es verstehen: einfache und einfache Service-Dateien . Ich denke, es ist sinnvoller, ein Konfigurationsverwaltungssystem zu erlernen und zu verwenden, da das Wissen für alle Konfigurationen in / etc verwendet werden kann, nicht nur für systemd. - guettli


Antworten:


Nun, vorausgesetzt, dass die nur Sache, die pro Einheitsdatei ändert, ist die remote.example.com Teil können Sie einen verwenden Instanziiert  Bedienung.

Von dem systemd.unit man seite:

Optional können Einheiten zur Laufzeit aus einer Vorlagendatei instanziiert werden.   Dies ermöglicht die Erstellung mehrerer Einheiten aus einer einzigen Konfiguration   Datei. Wenn Systemd nach einer Gerätekonfigurationsdatei sucht, wird es zuerst angezeigt   Suchen Sie nach dem Namen der Literaleinheit im Dateisystem. Wenn das keine ergibt   Erfolg und der Name der Einheit enthält ein "@" Zeichen, Systemd wird aussehen   für eine Unit-Vorlage, die denselben Namen wie die Instanz hat   Zeichenfolge (d. h. der Teil zwischen dem Zeichen "@" und dem Suffix)   entfernt. Beispiel: Wenn ein Service getty@tty3.service angefordert wird und keine   Datei mit diesem Namen gefunden wird, sucht systemd nach getty @ .service und   instanziieren Sie einen Dienst von dieser Konfigurationsdatei, wenn sie gefunden wird.

Grundsätzlich erstellen Sie eine einzelne Unit-Datei, die eine Variable enthält (normalerweise %i) wo die Unterschiede auftreten und dann werden sie verknüpft, wenn Sie diesen Dienst "aktivieren".

Zum Beispiel habe ich eine Unit-Datei namens /etc/systemd/system/autossh@.service Das sieht so aus:

[Unit]
Description=AutoSSH service for ServiceABC on %i
After=network.target

[Service]
Environment=AUTOSSH_GATETIME=30 AUTOSSH_LOGFILE=/var/log/autossh/%i.log AUTOSSH_PIDFILE=/var/run/autossh.%i.pid
PIDFile=/var/run/autossh.%i.pid
#Type=forking
ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i

[Install]
WantedBy=multi-user.target

Was ich dann aktiviert habe

[user@anotherhost ~]$ sudo systemctl enable autossh@somehost.example.com
ln -s '/etc/systemd/system/autossh@.service' '/etc/systemd/system/multi-user.target.wants/autossh@somehost.example.com.service'

Und kann mit interagieren

[user@anotherhost ~]$ sudo systemctl start autossh@somehost.example.com
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
autossh@somehost.example.service - AutoSSH service for ServiceABC on somehost.example
   Loaded: loaded (/etc/systemd/system/autossh@.service; enabled)
   Active: active (running) since Tue 2015-10-20 13:19:01 EDT; 17s ago
 Main PID: 32524 (autossh)
   CGroup: /system.slice/system-autossh.slice/autossh@somehost.example.com.service
           ├─32524 /usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com
           └─32525 /usr/bin/ssh -L 40000:127.0.0.1:40000 -R 40000:127.0.0.1:40001 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com

Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
autossh@somehost.example.com.service - AutoSSH service for ServiceABC on somehost.example.com
   Loaded: loaded (/etc/systemd/system/autossh@.service; enabled)
   Active: inactive (dead) since Tue 2015-10-20 13:24:10 EDT; 2s ago
  Process: 32524 ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i (code=exited, status=0/SUCCESS)
 Main PID: 32524 (code=exited, status=0/SUCCESS)

Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopping AutoSSH service for ServiceABC on somehost.example.com...
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopped AutoSSH service for ServiceABC on somehost.example.com.

Wie Sie sehen können, alle Instanzen von %i in der Unit-Datei mit ersetzt werden somehost.example.com.

Da ist noch ein Haufen mehr Spezifikatoren das kann man zwar in einer unit-Datei verwenden, finde ich aber %i am besten in solchen Fällen zu arbeiten.


37
2017-10-20 17:36



Wow, Systemd ist großartig. - guettli
Sie zeigen nicht, wie man beim Booten automatisch startet, einschließlich welcher zu starten. - Craig Hicks
Mit Systemd, dem enable Aktion ist, was eine Einheit / einen Dienst beim Booten startet. - GregL
Kann ich die Instanzen unabhängig voneinander aktivieren / deaktivieren? - Soumya Kanti
Ja, das machst du, wenn du sie aktivierst / deaktivierst. - GregL


Hier ist ein Python-Beispiel, nach dem ich gesucht habe:

$ cat /etc/systemd/system/my-worker@.service

[Unit]
Description=manages my worker service, instance %i
After=multi-user.target

[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
Restart=always
TimeoutStartSec=10
RestartSec=10

Verschiedene Methoden, um es aufzurufen

Aktivieren verschiedener Zählungen zum Beispiel:

  • 30 Arbeiter aktivieren:

    sudo systemctl enable my-worker\@{1..30}.service
    
  • Aktiviere 2 Arbeiter:

    sudo systemctl enable my-worker\@{1..2}.service
    

Dann stellen Sie sicher, dass Sie neu laden:

sudo systemctl daemon-reload

Jetzt kannst du auf verschiedene Arten starten / stoppen:

  • Start 1:

    sudo systemctl start my-worker@2.service
    
  • Start mehrere:

    sudo systemctl start my-worker@{1..2}
    
  • Stopp mehrere:

    sudo systemctl stop my-worker@{1..2}
    
  • Status überprüfen:

    sudo systemctl status my-worker@1
    

AKTUALISIEREN: Um Instanzen als einen Service zu verwalten, können Sie Folgendes tun:

/etc/systemd/system/some-worker@.service:

[Unit]
Description=manage worker instances as a service, instance %i
Requires=some-worker.service
Before=some-worker.service
BindsTo=some-worker.service

[Service]
PermissionsStartOnly=true
Type=idle
User=root
#EnvironmentFile=/etc/profile.d/optional_envvars.sh
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
TimeoutStartSec=10
RestartSec=10

[Install]
WantedBy=some-worker.service

/usr/bin/some-worker-start.sh:

#!/bin/bash
systemctl start some-worker@{1..10}

/etc/systemd/system/some-worker.service:

[Unit]
Description=manages some worker instances as a service, instance

[Service]
Type=oneshot
ExecStart=/usr/bin/sh /usr/bin/some-worker-start.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Und jetzt können Sie alle Instanzen mit verwalten sudo systemctl some-worker (start|restart|stop)


9
2017-10-13 19:46





GregLs Antwort hat mir sehr geholfen. Hier ist ein Beispiel für eine Unit-Vorlage, die ich in meinem Code mit dem obigen Beispiel für einen Gearman-Job-Server verwendet habe. Ich habe ein Shell-Skript erstellt, mit dem ich eine Menge "Worker" mit dieser Vorlage erstellen kann.

[Unit]
Description=az gearman worker
After=gearman-job-server.service

[Service]
PIDFile=/var/run/gearman_worker_az%i.pid
Type=simple
User=www-data
WorkingDirectory=/var/www/mysite.com/jobs/
ExecStart=/usr/bin/php -f gearman_worker_az.php > /dev/null 2>&1
Restart=on-success
KillMode=process

[Install]
WantedBy=multi-user.target

1
2018-03-23 05:21