Und dann kamen SystemD Services...

systemd ist die Zukunft. Alle neuen Linux Dienste nutzen diesen Standard um sich im System zu registrieren.

Auch falsch! (Langsam zeichnet sich ein Muster ab.)

Mir bleibt wirklich gar nichts erspart, und somit kommen jetzt (beruflich wie privat) auch noch .service Dateien in meine Welt.


Eigentlich ist systemd der ausgereifteste Ansatz, wie man Dienste verwalten kann. Denn hier werden nicht lose Scripts irgendwie ausgeführt, sondern ein verwalteter und definierter Hauptdienst startet und verwaltet alles Andere.

Init-Scripts sind quasi selbstverantwortlich, wie sie ihre zugehörigen Prozesse starten. Ob hier 1x oder 2x gefork()t wird, ob man den Account wechselt, das ist alles ein Script-Geheimnis.

systemd versucht uns alle Optionen als Konfiguration zur Verfügung zu stellen, so dass wir einfach nur noch Variablen (bzw. Einstellungen) setzen und kein selbstgeschriebener Code mehr notwendig ist.

Man legt quasi eine INI-Datei, als “Service-Unit” im Verzeichnis /etc/systemd/system/ an, deren Inhalt beschreibt, wie der Daemon gestartet werden soll.
Beispiel: /etc/systemd/system/myserviced.service

[Unit]
Description=MyService Daemon
Requires=other_daemon1,other_daemon2

[Service]
Type=exec
ExecStart=/usr/bin/myserviced

[Install]
WantedBy=multi-user.target

Der exec Typ

Es gibt mehrere “Typen” von Diensten, und exec ist (neben dem ähnlich Typ simple) der einfachste, weil sich hier systemd um die gesamte Laufzeit kümmert.
Es startet den Prozess im Hintergrund und überwacht ihn. Wird von außen die Beendigung eingefordert, schickt systemd die notwendigen Standard-Signale an den Prozess.

Der oneshot Typ

Manchmal bedeutet “Dienst” auch nur “eine-Aktion-und-fertig”. Genau dafür ist der oneshot-Typ erschaffen worden. Das ausgeführte Programm darf sich nämlich nach seiner “Aktion” beenden, aber systemd behandelt den Dienst weiter als “laufend”, obwohl gar kein Prozess mehr am Arbeiten ist.

Das hilft einem vor allem bei Abhängigkeiten, wenn ein Dienst einen anderen braucht. Wird nämlich ein Dienst beendet, beendet systemd auch alle von ihm abhängigen Dienste.
Mit oneshot lässt sich so eine Kette von Aufgaben bilden, die hintereinander ausgeführt werden, die sich aber nach ihrem Ende nicht gegenseitig abbrechen.

Der forking Typ

Viele alte Init-Script Daemons haben sich selbst verwaltet, also sich selbst gefork()t, und für solche Fälle ist dieser Typ gut geeignet. Hier kann man dann eine PID-Datei und eine Beendigungsroutine konfigurieren, um geforkte Dienste zu beenden:

[Unit]
Description=MyService Daemon
Requires=other_daemon1,other_daemon2

[Service]
Type=forking
ExecStart=/usr/bin/myserviced --start-me
ExecStop=/usr/bin/myserviced --kill-me
PIDFile=/var/run/myserviced.pid

[Install]
WantedBy=multi-user.target

Und vieles mehr

Dann gibt es da noch diverse andere Typen, die über dbus mit ihrem Prozess kommunizieren, aber die sind für meine Zwecke zu komplex.

Außerdem lassen sich in systemd Service Dateien jede Menge Sonderfälle spezifizieren wie:

  • Wiederhole den Start X mal, wenn sich der Prozess beendet/aufhängt.
  • Interpretiere/Ignoriere den Exit-Code eines Prozesses anders.
  • Führe ein anderes Programm/Script vor oder nach dem Daemon-Prozess aus.
  • Definiere Timeouts, wie lange Einzelschritte dauern dürfen.
  • Festlegung, ob oder welche Kindprozesse mitüberwacht und mitverwaltet werden sollen.
  • Wechsele den Account, das Verzeichnis oder das Environment
  • Definition von Abhängigkeiten, was vor oder nach wem gestartet wird, und was automatisch wieder beendet werden soll, wenn der eigene Dienst terminiert.
  • usw., siehe: systemd.service

Nutzung von systemctl

Das Zentrale Tool zur Verwaltung ist systemctl.
Ist eine .service Datei angelegt, werden mit systemctl daemon-reload alle Service-Dateien eingelesen und integriert.

systemctl enable myserviced.service aktiviert das Service für den automatischen Start.

Mit systemctl start|stop|status myserviced lässt sich wie mit klassischen Init-Scripts ein Daemon starten, stoppen oder dessen aktueller Status ausgeben.

Fazit

Tja, wie schon mal gesagt:

systemd ist super, aber…

Ich werde also künftig .service Dateien mit Typ forking anlegen, die aber auf meine alten Init-Scripts verweisen.

Der Grund dafür: Docker
Leider ist systemd nicht ohen Workarounds in Docker-Containern nutzbar, Init-Scripts funktionieren dort aber wie gehabt.

Es macht für mich also Sinn, das “neue” System mit meiner “alten” Technik zu verbinden.

Aber gäbe es die Container-Einschränkung nicht, wäre systemd vermutlich genau das, was ich in Linux immer vermisst habe und was in Windows seit NT 4 Standard ist:
Nämlich eine ordentliche Instanz zur zentralen und einheitlichen Verwaltung von System-Diensten.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!