Systemd
Systemd ist das Init-System und der Dienst-Manager unter Linux. Es startet beim Booten alle Prozesse, verwaltet Dienste, mountet Dateisysteme und protokolliert Ereignisse. Alles dreht sich um sogenannte Units – kleine Konfigurationsdateien die beschreiben was gestartet, gemountet oder überwacht werden soll.
Units
- Eine Unit ist eine Konfigurationsdatei mit der Endung die ihren Typ beschreibt
| Unit-Typ |
Endung |
Beschreibung
|
| Service |
.service |
Startet und überwacht einen Prozess
|
| Timer |
.timer |
Führt eine Unit zeitgesteuert aus
|
| Mount |
.mount |
Hängt ein Dateisystem ein
|
| Target |
.target |
Gruppiert Units – vergleichbar mit Runleveln
|
| Socket |
.socket |
Startet einen Dienst bei eingehender Verbindung
|
Wo liegen Units?
| Pfad |
Beschreibung
|
| /lib/systemd/system/ |
Vom System mitgelieferte Units – nicht anfassen
|
| /etc/systemd/system/ |
Eigene Units und Overrides – hier arbeiten wir
|
systemctl
- Der zentrale Befehl zur Steuerung von Diensten und Units
| Befehl |
Beschreibung
|
| systemctl start <unit> |
Unit starten
|
| systemctl stop <unit> |
Unit stoppen
|
| systemctl restart <unit> |
Unit neu starten
|
| systemctl reload <unit> |
Konfiguration neu laden ohne Neustart
|
| systemctl enable <unit> |
Unit beim Boot aktivieren
|
| systemctl disable <unit> |
Unit beim Boot deaktivieren
|
| systemctl enable --now <unit> |
Aktivieren und sofort starten
|
| systemctl is-enabled <unit> |
Ist der Dienst enabled?
|
| systemctl status <unit> |
Status und letzte Logzeilen anzeigen
|
| systemctl is-active <unit> |
Nur prüfen ob aktiv – gut für Skripte
|
| systemctl list-units |
Alle aktiven Units anzeigen
|
| systemctl list-unit-files |
Alle bekannten Units anzeigen
|
| systemctl daemon-reload |
Neue oder geänderte Units einlesen
|
Service Unit
- Als Beispiel bauen wir einen einfachen HTTP-Server mit Python – der Webserver lauscht auf Port 8080 und liefert den Inhalt des aktuellen Verzeichnisses aus.
Unit-Datei erstellen
- vi /etc/systemd/system/webshare.service
[Unit]
Description=Python HTTP Server auf Port 8080
After=network.target
[Service]
Type=simple
User=nobody
WorkingDirectory=/var/www/html
ExecStart=/usr/bin/python3 -m http.server 8080
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Verzeichnis vorbereiten
- mkdir -p /var/www/html
- echo "Hallo vom Python HTTP Server" > /var/www/html/index.html
Dienst starten
- Nach jeder Änderung an einer Unit-Datei muss systemd neu eingelesen werden
- systemctl daemon-reload
- systemctl enable --now webshare.service
Test
[Unit]
- Description
- Freitext-Beschreibung des Dienstes, erscheint u. a. bei
systemctl status
- After=network.target
- Startreihenfolge: Der Dienst wird erst gestartet, nachdem das Netzwerk-Target erreicht ist
- Keine harte Abhängigkeit (kein
Requires=) – der Dienst startet auch, falls network.target fehlschlägt
[Service]
- Type=simple
- Standard-Diensttyp: systemd betrachtet den Prozess als gestartet, sobald
ExecStart ausgeführt wurde
- Der Hauptprozess läuft im Vordergrund und wird von systemd direkt überwacht
- User=nobody
- Dienst läuft nicht als root, sondern unter dem unprivilegierten Benutzer
nobody
- Sicherheitsmaßnahme nach dem Prinzip der geringsten Rechte (principle of least privilege)
- WorkingDirectory=/var/www/html
- Arbeitsverzeichnis des Prozesses
python3 -m http.server stellt den Inhalt dieses Verzeichnisses bereit
- ExecStart=/usr/bin/python3 -m http.server 8080
- Der eigentliche Startbefehl
- Absoluter Pfad zum Interpreter ist Pflicht (kein
$PATH-Lookup durch systemd)
- Restart=on-failure
- Der Dienst wird automatisch neu gestartet, falls er mit einem Fehlercode beendet wird
- Bei sauberem Beenden (Exit-Code 0) erfolgt kein Neustart
- RestartSec=5
- Wartezeit von 5 Sekunden zwischen Absturz und Neustartversuch
- Verhindert ein zu schnelles Neustart-Loop (restart flapping)
[Install]
- WantedBy=multi-user.target
- Legt fest, in welchem Target der Dienst beim Systemstart mit aktiviert wird
multi-user.target entspricht dem klassischen Runlevel 3 (Mehrbenutzerbetrieb ohne grafische Oberfläche)
- Wird nur wirksam, wenn der Dienst zuvor mit
systemctl enable aktiviert wurde
Hinweis
- Port < 1024
- Für Ports unterhalb von 1024 wäre
User=nobody problematisch, da diese root-Rechte (bzw. CAP_NET_BIND_SERVICE) erfordern
- Port 8080 ist unproblematisch, da er oberhalb der privilegierten Portgrenze liegt.
Targets
- Targets gruppieren Units und definieren den Systemzustand – vergleichbar mit Runleveln unter SysV
| Target |
Entspricht |
Beschreibung
|
| poweroff.target |
Runlevel 0 |
System ausschalten
|
| rescue.target |
Runlevel 1 |
Einzelbenutzermodus
|
| multi-user.target |
Runlevel 3 |
Mehrbenutzermodus ohne GUI
|
| graphical.target |
Runlevel 5 |
Mehrbenutzermodus mit GUI
|
| reboot.target |
Runlevel 6 |
Neustart
|
- Aktuelles Target anzeigen
- Standard-Target setzen – Boot ohne GUI
- systemctl set-default multi-user.target
- Standard-Target setzen – Boot mit GNOME
- systemctl set-default graphical.target
- In ein Target wechseln ohne Neustart
- systemctl isolate multi-user.target
journalctl
- journalctl ist das Werkzeug zum Lesen des systemd-Journals – alle Logs aller Dienste an einem Ort.
Grundlegende Befehle
| Befehl |
Beschreibung
|
| journalctl |
Gesamtes Journal anzeigen
|
| journalctl -f |
Live mitverfolgen (wie tail -f)
|
| journalctl -b |
Nur aktueller Boot
|
| journalctl -b -1 |
Letzter Boot
|
| journalctl -u ssh (Debian) |
Nur Logs von sshd
|
| journalctl -fu ssh (Debian) |
sshd live verfolgen
|
| journalctl -u sshd (Rocky) |
Nur Logs von sshd
|
| journalctl -fu sshd (Rocky) |
sshd live verfolgen
|
| journalctl -u named -g 88.10 |
Logs von named, davon nur Anzeigen vom Suchmuster
|
| journalctl -k |
Kernelmeldungen
|
| journalctl -n 50 |
Letzte 50 Zeilen
|
| journalctl -p err |
Nur Fehler anzeigen
|
| journalctl --since "1 hour ago" |
Letzte Stunde
|
| journalctl --since "2025-06-01" --until "2025-06-02" |
Zeitraum
|
Prioritäten
| Kürzel |
Priorität |
Beschreibung
|
| 0 |
emerg |
System nicht mehr nutzbar
|
| 1 |
alert |
Sofortiger Handlungsbedarf
|
| 2 |
crit |
Kritischer Fehler
|
| 3 |
err |
Fehler
|
| 4 |
warning |
Warnung
|
| 5 |
notice |
Normaler aber wichtiger Hinweis
|
| 6 |
info |
Informationen
|
| 7 |
debug |
Debug-Ausgaben
|
Persistentes Journal
- Standardmäßig wird das Journal nach einem Reboot gelöscht – mit dieser Einstellung bleibt es erhalten
- mkdir -p /var/log/journal
- vi /etc/systemd/journald.conf
[Journal]
Storage=persistent
SystemMaxUse=500M
- systemctl restart systemd-journald
Praktische Beispiele
- Fehler seit dem letzten Boot
- firewalld live beobachten
- named Logs der letzten Stunde
- journalctl -u named --since "1 hour ago"
- Alle Logs eines bestimmten Dienstes mit Kontext
- journalctl -u sshd -n 100 --no-pager