Systemd Units verstehen: Ein tiefer Einblick in die Service-Konfiguration

Tauchen Sie tief in systemd-Unit-Dateien ein, das Konfigurationsfundament für Linux-Dienste. Lernen Sie, `.service`-Dateien zu lesen, zu ändern und zu erstellen und verstehen Sie Abschnitte wie `[Unit]`, `[Service]` und `[Install]`. Diese Anleitung behandelt praktische Beispiele für die Verwaltung benutzerdefinierter Dienste mit `systemctl` und die Anzeige von Protokollen mit `journalctl` und bietet wesentliches Wissen für Systemadministratoren und Entwickler.

45 Aufrufe

Systemd Units verstehen: Ein tiefer Einblick in die Service-Konfiguration

Systemd ist zum De-facto-Standard für die Initialisierung und Verwaltung von Diensten auf modernen Linux-Distributionen geworden. Im Kern stützt sich systemd auf Unit-Dateien, um verschiedene Systemressourcen zu definieren und zu steuern, darunter Dienste, Geräte, Mount-Punkte und mehr. Das Verständnis der Struktur und Syntax dieser Unit-Dateien ist für Systemadministratoren und Entwickler gleichermaßen entscheidend, da es ihnen ermöglicht, bestehende Dienste effektiv zu verwalten und benutzerdefinierte Dienste zu erstellen, die auf ihre spezifischen Bedürfnisse zugeschnitten sind.

Dieser Artikel bietet einen umfassenden Einblick in systemd Unit-Dateien, wobei der Schwerpunkt hauptsächlich auf Service Units (.service-Dateien) liegt. Wir werden ihre grundlegende Struktur, gängige Direktiven und praktische Beispiele für das Lesen, Ändern und Erstellen untersuchen. Am Ende dieser Anleitung werden Sie eine solide Grundlage haben, um die Leistungsfähigkeit von systemd zur Verwaltung Ihrer Systemdienste mit Zuversicht zu nutzen.

Was sind Systemd Unit-Dateien?

Systemd Unit-Dateien sind einfache Textdateien, die Konfigurationsdirektiven für eine bestimmte Unit enthalten. Eine Unit repräsentiert eine von systemd verwaltete Ressource. Der häufigste Typ ist die Service Unit, die definiert, wie ein Hintergrundprozess oder eine Anwendung gestartet, gestoppt, neu gestartet und verwaltet wird.

Unit-Dateien sind in Abschnitte unterteilt, die jeweils durch eckige Klammern ([]) gekennzeichnet sind. Die wichtigsten Abschnitte für Service Units sind:

  • [Unit]: Enthält Metadaten über die Unit, Abhängigkeiten und die Reihenfolge.
  • [Service]: Definiert das Verhalten des Dienstes selbst, einschließlich der Ausführungsmethode.
  • [Install]: Gibt an, wie die Unit aktiviert oder deaktiviert werden soll, typischerweise durch Verknüpfung mit Ziel-Units.

Systemd sucht nach Unit-Dateien in mehreren Standardverzeichnissen, wobei die gebräuchlichsten sind:

  • /etc/systemd/system/: Für lokal konfigurierte Units, die Standard-Units überschreiben.
  • /usr/lib/systemd/system/: Für von Paketen installierte Units.

Aufbau einer .service Unit-Datei

Lassen Sie uns eine typische .service Unit-Datei aufschlüsseln, um ihre Komponenten zu verstehen.

Der [Unit] Abschnitt

Dieser Abschnitt liefert beschreibende Informationen und definiert die Beziehungen zwischen Units.

  • Description=: Eine für Menschen lesbare Beschreibung des Dienstes.
  • Documentation=: URLs oder Pfade zur Dokumentation des Dienstes.
  • After=: Gibt an, dass diese Unit nachdem die aufgeführten Units gestartet wurden, gestartet werden soll.
  • Requires=: Ähnlich wie After=, macht aber die aufgeführten Units auch zwingend erforderlich. Wenn eine erforderliche Unit nicht gestartet werden kann, schlägt auch diese Unit fehl.
  • Wants=: Eine schwächere Form der Abhängigkeit. Diese Unit versucht, ihre gewünschten Units zu starten, aber ihr Scheitern verhindert nicht den Start dieser Unit.
  • Conflicts=: Gibt Units an, die nicht gleichzeitig mit dieser Unit ausgeführt werden können.

Beispiel [Unit] Abschnitt:

[Unit]
Description=Mein benutzerdefinierter Webserver
Documentation=https://example.com/docs/my-web-server
After=network.target

Dies zeigt an, dass unser benutzerdefinierter Webserver gestartet werden soll, nachdem das Netzwerk verfügbar ist.

Der [Service] Abschnitt

Hier befindet sich die Kernlogik für die Ausführung des Dienstes.

  • Type=: Definiert den Starttyp des Prozesses. Gängige Typen sind:
    • simple (Standard): Der Hauptprozess ist derjenige, der von ExecStart= gestartet wird. Systemd betrachtet den Dienst als sofort gestartet, nachdem der von ExecStart= gestartete Prozess geforkt wurde.
    • forking: Wird für traditionelle Dämonen verwendet, die einen Kindprozess abspalten und sich beenden. Systemd wartet, bis der Elternprozess beendet ist.
    • oneshot: Für Aufgaben, die einen einzelnen Befehl ausführen und sich dann beenden.
    • notify: Der Dienst sendet eine Benachrichtigung an systemd, wenn er mit dem Starten fertig ist.
    • dbus: Für Dienste, die einen D-Bus-Namen erwerben.
  • ExecStart=: Der auszuführende Befehl zum Starten des Dienstes.
  • ExecStop=: Der auszuführende Befehl zum Stoppen des Dienstes.
  • ExecReload=: Der auszuführende Befehl zum Neuladen der Konfiguration des Dienstes, ohne ihn neu zu starten.
  • Restart=: Definiert, wann der Dienst neu gestartet werden soll. Optionen sind no (Standard), on-success, on-failure, on-abnormal, on-watchdog, on-abort und always.
  • RestartSec=: Die Wartezeit vor dem Neustart des Dienstes.
  • User= / Group=: Der Benutzer und die Gruppe, unter denen der Dienst ausgeführt werden soll.
  • WorkingDirectory=: Das Arbeitsverzeichnis für die ausgeführten Prozesse.
  • Environment= / EnvironmentFile=: Legt Umgebungsvariablen für den Dienst fest.

Beispiel [Service] Abschnitt:

[Service]
Type=simple
ExecStart=/usr/local/bin/my-web-server --config /etc/my-web-server.conf
User=www-data
Group=www-data
Restart=on-failure
RestartSec=5

Diese Konfiguration startet unseren Webserver, führt ihn als Benutzer und Gruppe www-data aus und startet ihn automatisch neu, wenn er fehlschlägt, mit einer Verzögerung von 5 Sekunden.

Der [Install] Abschnitt

Dieser Abschnitt wird beim Aktivieren oder Deaktivieren einer Unit verwendet. Er definiert, wie die Unit in die Ziel-Units von systemd integriert wird.

  • WantedBy=: Gibt das/die Ziel(e) an, die diese Unit "wünschen" sollen, wenn sie aktiviert ist. Für Dienste, die beim Booten gestartet werden sollen, wird häufig multi-user.target verwendet.

Beispiel [Install] Abschnitt:

[Install]
WantedBy=multi-user.target

Wenn Sie systemctl enable my-custom-service.service ausführen, erstellt systemd einen symbolischen Link von /etc/systemd/system/multi-user.target.wants/ zu Ihrer Service-Datei, um sicherzustellen, dass sie gestartet wird, wenn das System den Multi-User-Runlevel erreicht.

Erstellen und Verwalten benutzerdefinierter Service Units

Lassen Sie uns den Prozess des Erstellens einer benutzerdefinierten Service Unit durchlaufen.

Schritt 1: Erstellen Sie die Unit-Datei

Erstellen Sie eine neue Datei in /etc/systemd/system/ mit der Erweiterung .service. Für unser Beispiel erstellen wir /etc/systemd/system/my-app.service.

[Unit]
Description=Mein benutzerdefinierter Anwendungsdienst
After=network.target

[Service]
Type=simple
ExecStart=/opt/my-app/bin/run-app --port 8080
User=appuser
Group=appgroup
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Wichtige Überlegungen:

  • Stellen Sie sicher, dass der Befehl ExecStart auf ein ausführbares Skript oder Binärprogramm verweist, das zugänglich ist und über Ausführungsberechtigungen verfügt.
  • Erstellen Sie den angegebenen User und Group, falls sie nicht existieren (sudo useradd -r -s /bin/false appuser, sudo groupadd appgroup, sudo usermod -a -G appgroup appuser).
  • Stellen Sie sicher, dass die Anwendung mit den angegebenen Befehlen korrekt gestartet und gestoppt werden kann.

Schritt 2: Laden Sie die Systemd-Konfiguration neu

Nachdem Sie eine Unit-Datei erstellt oder geändert haben, müssen Sie systemd anweisen, seine Konfiguration neu zu laden.

sudo systemctl daemon-reload

Dieser Befehl scannt nach neuen oder geänderten Unit-Dateien und aktualisiert den internen Zustand von systemd.

Schritt 3: Aktivieren und starten Sie den Dienst

Um den Dienst sofort zu starten und ihn für den automatischen Start beim Booten zu konfigurieren:

sudo systemctl enable my-app.service  # Erstellt Symlinks für den Bootstart
sudo systemctl start my-app.service   # Startet den Dienst jetzt

Schritt 4: Verwalten Sie den Dienst

Verwenden Sie systemctl-Befehle, um Ihren Dienst zu verwalten:

  • Status prüfen:
    bash sudo systemctl status my-app.service
    Dies zeigt an, ob der Dienst aktiv ist, seine Prozess-ID, aktuelle Protokolleinträge und mehr.

  • Dienst stoppen:
    bash sudo systemctl stop my-app.service

  • Dienst neu starten:
    bash sudo systemctl restart my-app.service

  • Dienst neu laden (wenn ExecReload= definiert ist):
    bash sudo systemctl reload my-app.service

  • Dienst deaktivieren (verhindern, dass er beim Booten startet):
    bash sudo systemctl disable my-app.service

Schritt 5: Protokolle mit journalctl anzeigen

Systemd ist eng mit journald für die Protokollierung integriert. Sie können die Protokolle für Ihren Dienst mit journalctl anzeigen:

  • Protokolle für einen bestimmten Dienst anzeigen:
    bash sudo journalctl -u my-app.service

  • Protokolle in Echtzeit verfolgen:
    bash sudo journalctl -f -u my-app.service

  • Protokolle seit dem letzten Bootvorgang anzeigen:
    bash sudo journalctl -b -u my-app.service

Best Practices und Tipps

  • Verwenden Sie Type=notify für moderne Anwendungen: Wenn Ihre Anwendung dies unterstützt, bietet Type=notify eine bessere Integration mit systemd und ermöglicht es ihm, die Bereitschaft des Dienstes genau zu verfolgen.
  • Dienste als Nicht-Root-Benutzer ausführen: Geben Sie immer User= und Group= im Abschnitt [Service] an, um Sicherheitsrisiken zu minimieren.
  • Abhängigkeiten sorgfältig definieren: Verwenden Sie After=, Requires= und Wants=, um sicherzustellen, dass Dienste in der richtigen Reihenfolge gestartet werden und kritische Abhängigkeiten erfüllt sind.
  • Nutzen Sie Restart=: Konfigurieren Sie geeignete Neustartrichtlinien, um die Verfügbarkeit des Dienstes zu gewährleisten.
  • Unit-Dateien einfach halten: Für komplexe Startsequenzen sollten Sie Wrapper-Skripte verwenden, die von ExecStart= aufgerufen werden, anstatt komplexe Befehle direkt in der Unit-Datei einzugeben.
  • Verwenden Sie systemctl cat <unit>: Um den vollständigen Inhalt einer Unit-Datei anzuzeigen, wie systemd ihn sieht, einschließlich aller Überschreibungen.
  • Verwenden Sie systemctl edit <unit>: Dieser Befehl öffnet einen Editor, um eine Überschreibungsdatei für eine vorhandene Unit zu erstellen. Dies ist eine sauberere Methode, Standard-Unit-Dateien zu ändern, als sie direkt zu bearbeiten.

Fazit

Systemd Unit-Dateien, insbesondere .service-Dateien, sind das Rückgrat der Dienstverwaltung auf modernen Linux-Systemen. Durch das Verständnis ihrer Struktur – die Abschnitte [Unit], [Service] und [Install] – und die Beherrschung der systemctl- und journalctl-Befehle erhalten Sie eine leistungsstarke Kontrolle über die Prozesse Ihres Systems. Ob Sie bestehende Dienstkonfigurationen anpassen oder benutzerdefinierte Dämonen erstellen, ein solides Verständnis von Unit-Dateien ermöglicht es Ihnen, Ihr System effizienter, zuverlässiger und sicherer zu verwalten.