ubuntuusers.de

Du betrachtest eine alte Revision dieser Wikiseite.

Service Units

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist mit keiner aktuell unterstützten Ubuntu-Version getestet! Bitte teste diesen Artikel für eine Ubuntu-Version, welche aktuell unterstützt wird. Dazu sind die Hinweise zum Testen von Artikeln zu beachten.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

In systemd ist eine Organisationseinheit eine "Unit" (auf Deutsch: Einheit). Units werden z.B. für Dienste, Timer, Einhängepunkte, Sockets, Swap-Speicher und Geräte (devices) erstellt. Während die letzteren in der Regel automatisch vom System erstellt werden und kein Eingriff durch den Nutzer nötig ist, können Units für Services und Timer auch vom Nutzer erstellt werden.

Service Units dienen dazu, Dienste zu starten und entsprechen damit den Init-Skripten von SysVinit bzw. Upstart.

Installation

Da systemd ab Ubuntu 15.04 integraler Bestandteil des Systems ist (und dieses ohne systemd nicht lauffähig ist), sind alle benötigten Komponenten bereits installiert.

Benutzung

Dateien für Service Units sind unter Ubuntu an zwei Stellen im Dateisystem abgelegt:

  • /lib/systemd/system: Hier liegen alle .service Dateien (sowie Dateien anderer Units), welche durch Dienste systemweit vorinstalliert worden sind. Diese Dateien sollten nie editiert werden.

  • /etc/systemd/system: hier liegen alle .service Dateien (sowie Dateien anderer Units), welche durch den Nutzer angelegt oder editiert werden. Dazu sind Root-Rechte[1] erforderlich.

Eigene Service Units anlegen

Units bestehen normalerweise aus einer einzelnen Datei. Diese hat eine Syntax und einen Aufbau ähnlich wie INI-Dateien. Das heißt, dass eckige Klammer Abschnitte ("sections") innerhalb der Datei markieren und innerhalb dieser Schlüssel-Werte-Paare angegeben werden.

Eine minimale allgemeine Service-Datei sieht wie folgt aus:

[Unit]
Description=Meine Service Unit

[Service]
Type=simple
ExecStart=/PFAD/ZUM/BEFEHL/befehl

[Install]
WantedBy=multi-user.target

Es gibt also drei Sektionen:

  • "[Unit]": Der Schlüssel Description enthält den Namen der Unit. Diese kann frei gewählt werden und sollte aussagekräftig sein, da dieser Service später über diesen Namen referenziert werden kann. Weiterhin können auch Angaben gemacht werden, ob die Unit von anderen Service Units abhängt und z.B. erst gestartet werden soll, wenn der andere Service bereits läuft.

  • "[Service]": Der Schlüssel ExecStart enthält den Befehl zum Starten des Dienstes. Wichtig ist, dass immer der volle Pfad zum Befehl angegeben wird. In diesem Abschnitt kann z.B. auch eingetragen werden, welche Befehle vor oder nach dem Start des eigentlichen Services ausgeführt werden sollen, unter welchem Benutzer und welcher Gruppe der Dienst läuft (Standard: root). Außerdem wird hier festgelegt, welchen Typ der Service haben soll. Das Type=simple im obigen Beispiel müsste nicht explizit angegeben werden, da dies der Vorgabewert ist.

  • "[Install]": Der Schlüssel WantedBy legt fest, wann der Service gestartet wird, was den früheren "run levels" entspricht. Der Wert multi-user.target ist dabei der Standard für ein Mehrbenutzersystem (auch ohne grafische Oberfläche, wie z.B. Server).

Gerade beim Anlegen eigener Units ist zu beachten, dass die Schlüssel immer mit Großbuchstaben beginnen und in CamelCase-Schreibweise geschrieben werden: ExecStart=...

Service Typen

Wie oben erwähnt gibt es verschiedene Typen für einen Service. simple ist der Standardwert und die richtige Wahl für Dienste, welche permanent laufen, aber nicht "forken".

"Forkt" ein Service, d.h. erzeugt ein Dienst weiter Prozesse (wie es z.B. einige Webserver tun), dann muss der Service-Typ auf forking gesetzt werden.

Soll ein Service nur einmal laufen (z.B. ein "Aufräumskript", welche eine bestimmte Aufgabe erfüllt und dann beendet ist), dann wählt man als Service-Typ oneshot.

Eine vollständige Übersicht auch weiterer Typen inklusive Erklärungen ist in der systemd Dokumentation 🇬🇧 zu finden.

Optionen für die [Unit]-Sektion

In der Sektion "[Unit]" können unter anderem folgende Schlüssel eingefügt werden:

Schlüssel Erklärung
Description Ein aussagekräftiger Name für die Unit. Dieser Schlüssel ist Pflicht.
Requires Hier kann hinterlegt werden, welche andere Unit auf jeden Fall gestartet sein muss, damit die eigene Service Unit gestartet wird. Wird Requires nicht erfüllt, startet die eigene Unit nicht. Wird die in Requires hinterlegte Unit gestoppt, stoppt auch die eigene Unit.
Wants Dies ist die "schwache" Variante von Requires. Es wird zuerst geprüft, ob die bei Wants eingetragene Unit läuft oder gestartet werden kann, dann wird die eigene Unit gestartet. Schlägt der Start der andere Unit fehlt (oder wird diese gestoppt), läuft die eigene Unit aber trotzdem (weiter).
Before Legt fest, dass die eigene Unit vor den in Before eingetragenen Units gestartet werden soll.
After Legt fest, dass die eigene Unit nach den in After eingetragenen Units gestartet werden soll.

Bei Requires, Wants etc. können auch mehrere Werte zu dem Schlüssel hinterlegt werden. Die Werte müssen dann durch ein Leerzeichen getrennt sein, also z.B. Requires=mysql.service apache2.service.

Eine vollständige Übersicht über alle möglichen Schlüssel mit ausführlicher Erklärung ist in der Dokumentation 🇬🇧 von systemd zu finden.

Optionen für die [Service]-Sektion

In der Sektion "[Service]" können unter anderem folgende Schlüssel eingefügt werden:

Schlüssel Erklärung
ExecStart der Befehl, der beim Start der Unit ausgeführt wird
ExecStartPre der Befehl, der vor dem Start der Unit (also vor der Ausführung von ExecStart) ausgeführt werden soll
ExecStartPost der Befehl, der nach dem Start der Unit (also nach der Ausführung von ExecStart) ausgeführt werden soll
WorkingDirectory legt das Arbeitsverzeichnis fest, in dem die Prozesse ausgeführt werden. Das Verzeichnis muss als absoluter Pfad angegeben werden oder als ~. Bei letzterem wird das Homeverzeichnis des im Schlüssel User angegebenen Nutzers gewählt.
User legt fest, unter welchem Benutzer der Service laufen soll (Standard: root)
Group legt fest, unter welcher Gruppe der Service laufen soll

Die Schlüssel ExecStarPre und ExecStartPost dürfen auch mehrmals mit verschiedenen Befehlen vorkommen. Wichtig ist, dass bei den Werten für die Exec* Schlüssel immer der vollständige Pfad zum Programm/Skript mit angegeben wird, also z.B. ExecStart=/user/local/bin/mein_programm

systemd kennt noch eine Vielzahl weiterer Schlüssel für diesen Abschnitt. Eine ausführliche Auflistung und Erklärung ist in der Dokumentation für Service 🇬🇧 als auch in der Dokumentation systemd.exec 🇬🇧 zu finden.

[Install]: WantedBy-Arten

Im Abschnitt "[Install]" wird mit dem Schlüssel WantedBy angegeben, wann der Service gestartet wird. Es sind verschiedene Werte möglich:

Target Beschreibung
multi-user.target für Mehrbenutzersystem, mit oder ohne grafische Anmeldung (entspricht Runlevel 3)
graphical.target für Mehrbenutzersystem, die aber eine grafische Anmelde-Oberfläche haben müssen (entspricht Runlevel 3 plus grafischer Anmeldung)
rescue.target Einzelnutzer-Modus, wird in der Regel nur zur Systemrettung benötigt (entspricht Runlevel 1)
reboot.target Service wird nur bei einem Neustart des Systems ausgeführt
poweroff.target Service wird nur beim Herunterfahren des Systems ausgeführt

Eine vollständige Übersicht über alle Targets inklusive Erklärung ist in der Dokumentation 🇬🇧 von systemd zu finden.

Selbst angelegte Service Units aktivieren

Hat man eine eigene Service Unit angelegt, muss man diese noch aktivieren. Diese geschieht über den Befehl systemctl mit Root-Rechten[1][2]:

sudo systemctl enable NAME_DER_UNIT_DATEI 

Zum Deaktivieren dient der Befehl:

sudo systemctl disable NAME_DER_UNIT_DATEI 

Um zu prüfen, ob eine Service Unit aktiv ist, führt man folgenden Befehl aus:

sudo systemctl is-enabled NAME_DER_UNIT_DATEI 

Bestehende Service Untis editieren

Möchte man eine bestehende Service Unit editieren, gibt es dafür zwei Möglichkeiten. Welche die "bessere", ist hängt davon ab, wie viele und welche Änderungen man machen möchte.

Teile der bestehende Service Unit überschreiben

Mit dem Befehl

sudo systemctl edit SERVICEUNIT 

wird eine Datei /etc/systemd/system/SERVICEUNIT.service.d/override.conf angelegt und es öffnet sich automatisch der Standardeditor für die Konsole[3]. Hier können dann Einträge in die Datei override.conf gemacht werden. Eingetragen werden können alle Abschnitte ("sections") und alle Schlüssel, welche auch in den regulären Unit-Service-Dateien erlaubt sind. Nach dem Speichern und Schließen des Editors wird die Service Unit neu geladen.

Bei Schlüsseln, die sowohl in der original .service-Datei als auch der override.conf vorkommen, wird der Schlüssel aus der override.conf dem Original vorgezogen.

Natürlich können so nicht nur bestehende Schlüssel überschrieben werden, sondern auch neue Schlüssel hinzugefügt werden.

Hinweis:

Wichtig ist, dass die Sektion(en) in der override.conf auch angegeben werden! So hätte ein alleiniger Eintrag von ExecStart=foobar keine Auswirkung. Es muss vorher die Sektion angegeben werden, also

[Service]
ExecStart=foobar 

Komplette Service Unit editieren

Mit dem Befehl

sudo systemctl edit --full SERVICEUNIT 

wird eine Kopie der .service Datei für die UNIT SERVICEUNIT aus /lib/systemd/system im Verzeichnis /etc/systemd/systemd angelegt, und der Standardeditor des Systems öffnet diese Datei zum Editieren. Nach dem Speichern und Schließen des Editors wird die Service Unit automatisch neu geladen.

Liegen unter /etc/systemd/systemd .service-Dateien mit dem gleichen Namen wie unter /lib/systemd/system, so wird denen aus /etc/systemd/systemd der Vorzug gegeben, d.h. diese werden vom System geladen.

intern

extern

Diese Revision wurde am 20. Juli 2017 15:50 von Heinrich_Schwietering erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: systemd, System, Dienste