0Pricing
DevOps Bootcamp · Lektion

systemd-Dienste steuern und Unit-Dateien schreiben

Steuern Sie Dienste mit systemctl und erstellen Sie eigene Unit- und Timer-Dateien für daemonisierte Skripte.

systemd-Dienste steuern und Unit-Dateien schreiben ist eine kostenlose DevOps Bootcamp-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des DevOps Bootcamp-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.

Einführung in systemd und systemctl

systemd ist das von den meisten modernen Linux-Distributionen verwendete Init-System und der Dienstemanager. Es ist für das Starten, Stoppen und Verwalten von Systemdiensten sowie für Bootsequenzen und den Systemzustand zuständig.

Das wichtigste Werkzeug für die Interaktion mit systemd ist systemctl. Damit können Sie:

  • Dienste starten und stoppen
  • Dienste beim Systemstart aktivieren oder deaktivieren
  • Dienststatus und Protokolle prüfen
  • Die Konfiguration ohne Neustart neu laden

Alle von systemd verwalteten Dienste werden durch Unit-Dateien definiert. Dabei handelt es sich um deklarative Konfigurationsdateien, die unter /etc/systemd/system/ (systemweit) oder ~/.config/systemd/user/ (pro Benutzer) gespeichert sind.

Wichtige systemctl-Befehle

Dies sind die am häufigsten verwendeten systemctl-Befehle für die tägliche Dienstverwaltung. Jeder Befehl arbeitet mit einem Unit-Namen wie nginx.service oder einfach nginx.

  • systemctl start <unit> — einen Dienst sofort starten
  • systemctl stop <unit> — einen laufenden Dienst anhalten
  • systemctl restart <unit> — anhalten und anschließend starten (vollständiger Neustart)
  • systemctl reload <unit> — SIGHUP senden, um die Konfiguration neu zu laden, ohne den Dienst anzuhalten
  • systemctl enable <unit> — symbolische Links erstellen, damit die Unit beim Systemstart gestartet wird
  • systemctl disable <unit> — diese symbolischen Links entfernen
  • systemctl status <unit> — Status, PID und die neuesten Protokollzeilen anzeigen
#!/usr/bin/env bash
# Quick reference: inspect and control an nginx service
# (Requires nginx to be installed; run as root or with sudo)

systemctl status nginx
systemctl start nginx
systemctl enable nginx
systemctl reload nginx
systemctl restart nginx
systemctl stop nginx
systemctl disable nginx

Dienststatus im Detail prüfen

systemctl status liefert eine umfassende Momentaufnahme einer Unit. Das Verständnis der Ausgabe ist entscheidend, um Probleme schnell zu diagnostizieren.

  • Loaded: Pfad zur Unit-Datei und Angabe, ob sie beim Systemstart aktiviert ist
  • Active: aktueller Status — active (running), inactive (dead), failed
  • Main PID: die Prozess-ID des Hauptprozesses des Dienstes
  • CGroup: alle dem Dienst zugehörigen untergeordneten Prozesse
  • Log lines: die neuesten Journal-Einträge für diese Unit

Sie können den aktiven Status auch mit systemctl is-active und den Aktivierungsstatus mit systemctl is-enabled separat abfragen. Diese Befehle eignen sich ideal für die Verwendung in Skripten.

#!/usr/bin/env bash
# Script-friendly service health check
SERVICE="sshd"

if systemctl is-active --quiet "$SERVICE"; then
    echo "$SERVICE is running."
else
    echo "$SERVICE is NOT running. Attempting restart..."
    systemctl restart "$SERVICE"
fi

if systemctl is-enabled --quiet "$SERVICE"; then
    echo "$SERVICE is enabled at boot."
else
    echo "WARNING: $SERVICE is not enabled at boot."
fi

Units auflisten und filtern

Bei der Verwaltung vieler Dienste benötigen Sie effiziente Möglichkeiten, Units aufzulisten und zu filtern. systemctl list-units zeigt alle derzeit geladenen Units an, während list-unit-files alle installierten Unit-Dateien und deren Aktivierungsstatus auflistet.

Nützliche Filteroptionen:

  • --type=service — nur Service-Units anzeigen
  • --state=failed — nur fehlgeschlagene Units anzeigen
  • --state=active — nur aktive Units anzeigen
  • --all — inaktive Units in die Auflistung aufnehmen

Durch die Kombination dieser Filter mit grep können Sie leistungsfähige Prüf-Pipelines in Wartungsskripten erstellen.

#!/usr/bin/env bash
# List all failed services and report them
echo "=== Failed Services ==="
systemctl list-units --type=service --state=failed --no-legend

echo ""
echo "=== Services Enabled at Boot ==="
systemctl list-unit-files --type=service --state=enabled --no-legend | awk '{print $1}'

Aufbau einer systemd-Service-Unit-Datei

Eine Service-Unit-Datei ist eine einfache Textdatei im INI-Stil, die aus Abschnitten besteht. Jeder Abschnitt steuert einen anderen Aspekt des Lebenszyklus der Unit.

  • [Unit] — Metadaten: Beschreibung und Abhängigkeiten für die Reihenfolge (After=, Requires=, Wants=)
  • [Service] — Angaben zum Starten und Beenden des Prozesses: ExecStart, ExecStop, Restart, User, WorkingDirectory
  • [Install] — Angabe, wann diese Unit aktiviert werden soll: WantedBy=multi-user.target bedeutet, dass sie während eines normalen Multi-User-Systemstarts aktiviert wird

Nachdem Sie eine Unit-Datei unter /etc/systemd/system/ abgelegt oder bearbeitet haben, müssen Sie systemctl daemon-reload ausführen, damit systemd die Änderungen übernimmt.

Ihre erste Service-Unit-Datei schreiben

Erstellen wir eine einfache Service-Unit-Datei für ein benutzerdefiniertes Python-HTTP-Server-Skript. Die Unit-Datei teilt systemd genau mit, wie dieser Prozess verwaltet werden soll, als wäre er ein gewöhnlicher Systemdienst.

Wichtige hier verwendete Direktiven in [Service]:

  • Type=simple — systemd behandelt den mit ExecStart gestarteten Prozess als Hauptprozess
  • User=www-data — den Prozess aus Sicherheitsgründen unter einem Konto ohne Root-Rechte ausführen
  • WorkingDirectory — das Arbeitsverzeichnis des Prozesses festlegen
  • Restart=on-failure — den Prozess automatisch neu starten, wenn er mit einem von null verschiedenen Code beendet wird
  • RestartSec=5 — zwischen Neustartversuchen 5 Sekunden warten
#!/usr/bin/env bash
# Create a custom service unit file for a simple HTTP server
# Run as root

cat > /etc/systemd/system/mywebserver.service << 'EOF'
[Unit]
Description=My Custom Python Web Server
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/mysite
ExecStart=/usr/bin/python3 -m http.server 8080
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now mywebserver.service
systemctl status mywebserver.service

Diensttypen und Prozesslebenszyklus

Die Direktive Type= in [Service] teilt systemd mit, woran erkannt werden soll, dass ein Dienst vollständig gestartet ist. Die Wahl des falschen Typs ist eine häufige Ursache für Fehler bei der Startreihenfolge.

  • Type=simple — Standardwert; systemd betrachtet den Dienst als gestartet, sobald ExecStart ausgeführt wird. Es ist kein Bereitschaftssignal erforderlich.
  • Type=forking — der mit ExecStart gestartete Prozess erzeugt einen Kindprozess und wird beendet; der eigentliche Daemon läuft als Kindprozess weiter. Verwenden Sie PIDFile=, damit systemd ihn verfolgen kann.
  • Type=notify — der Prozess sendet sd_notify(READY=1), sobald er tatsächlich bereit ist. Dies ist für komplexe Daemons am zuverlässigsten.
  • Type=oneshot — wird einmal ausgeführt und beendet sich anschließend; nachfolgende Units warten auf den Abschluss. Ideal für Einrichtungsskripte.
  • Type=idle — wie simple, aber die Ausführung wird verzögert, bis alle aktiven Aufträge abgeschlossen sind.
#!/usr/bin/env bash
# Example: oneshot service for a database migration script
# /etc/systemd/system/db-migrate.service

cat > /etc/systemd/system/db-migrate.service << 'EOF'
[Unit]
Description=Run Database Migrations
After=postgresql.service
Requires=postgresql.service

[Service]
Type=oneshot
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/scripts/migrate.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start db-migrate.service

Umgebungsvariablen und Sicherheits-Härtung

Service-Unit-Dateien unterstützen mehrere Direktiven zum Übergeben von Umgebungsvariablen und zum Anwenden von Sicherheitseinschränkungen — beides ist in Produktionssystemen wichtig.

Direktiven für die Umgebung:

  • Environment="KEY=value" — eine einzelne Variable direkt setzen
  • EnvironmentFile=/etc/myapp/env — Variablen aus einer Datei laden (eine KEY=value-Angabe pro Zeile)

Gängige Direktiven zur Sicherheits-Härtung:

  • NoNewPrivileges=true — verhindern, dass der Prozess über setuid zusätzliche Berechtigungen erlangt
  • ProtectSystem=strict — /usr, /boot und /etc schreibgeschützt einhängen
  • PrivateTmp=true — dem Dienst ein eigenes isoliertes /tmp bereitstellen
  • CapabilityBoundingSet= — alle Linux-Capabilities entfernen
#!/usr/bin/env bash
# Hardened service unit with environment file

cat > /etc/systemd/system/secureapp.service << 'EOF'
[Unit]
Description=Secure Application Daemon
After=network.target

[Service]
Type=simple
User=secureapp
Group=secureapp
WorkingDirectory=/opt/secureapp
EnvironmentFile=/etc/secureapp/env
ExecStart=/opt/secureapp/bin/server
Restart=on-failure
RestartSec=10

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
CapabilityBoundingSet=
ReadWritePaths=/var/lib/secureapp /var/log/secureapp

[Install]
WantedBy=multi-user.target
EOF

# Create the environment file separately so secrets stay out of the unit file
install -m 600 -o secureapp /dev/null /etc/secureapp/env
echo 'APP_PORT=9000' >> /etc/secureapp/env
echo 'DB_URL=postgresql://localhost/mydb' >> /etc/secureapp/env

systemctl daemon-reload

Einführung in systemd-Timer-Units

Ein systemd-Timer ist eine Unit, die eine andere Unit (in der Regel eine .service) nach einem Zeitplan aktiviert. Er ersetzt herkömmliche cron-Jobs durch einen stärker integrierten, protokollierbaren und besser steuerbaren Mechanismus.

Jede Timer-Unit (foo.timer) ist mit einer Service-Unit desselben Basisnamens (foo.service) verknüpft, die die eigentliche Arbeit ausführt. Sie aktivieren und starten den Timer, nicht den Dienst direkt.

Timer-Typen:

  • Echtzeit- (Kalender-)Timer — werden zu Uhrzeiten ausgelöst, die mit OnCalendar=-Ausdrücken wie daily, weekly oder Mon *-*-* 02:00:00 festgelegt werden
  • Monotone Timer — werden relativ zu einem Systemereignis mit OnBootSec=, OnActiveSec= oder OnUnitActiveSec= ausgelöst

Eine Timer-Unit-Datei schreiben

Erstellen wir ein vollständiges Timer-Service-Paar, das täglich um 02:00 Uhr ein Backup-Skript ausführt. Beachten Sie, dass der Abschnitt [Timer] in einer eigenen .timer-Datei steht, während die auszuführende Arbeit in der zugehörigen .service-Datei definiert ist.

Wichtige Direktiven in [Timer]:

  • OnCalendar= — Kalendere Ausdruck für den Zeitplan
  • Persistent=true — wenn das System zum geplanten Auslösezeitpunkt ausgeschaltet war, die Ausführung beim nächsten Systemstart sofort nachholen
  • RandomizedDelaySec= — eine zufällige Verzögerung von bis zu N Sekunden hinzufügen, um den Ansturm vieler Hosts zum selben Zeitpunkt zu vermeiden
  • Unit= — explizite Ziel-Unit (optional, wenn die Namen übereinstimmen)
#!/usr/bin/env bash
# Create a daily backup timer pair
# Run as root

# 1. The service that does the work
cat > /etc/systemd/system/daily-backup.service << 'EOF'
[Unit]
Description=Daily Database Backup
After=network.target postgresql.service

[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/backup-db.sh
StandardOutput=journal
StandardError=journal
EOF

# 2. The timer that schedules it
cat > /etc/systemd/system/daily-backup.timer << 'EOF'
[Unit]
Description=Run Daily Database Backup at 02:00

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target
EOF

systemctl daemon-reload
systemctl enable --now daily-backup.timer

# Verify
systemctl list-timers daily-backup.timer

Protokolle prüfen und Units Fehler suchen

systemd leitet die gesamte Dienstausgabe an das Journal weiter, das Sie mit journalctl abfragen. Dadurch werden die Protokolle aller Units in einem durchsuchbaren Speicher zentralisiert.

Wichtige journalctl-Optionen zur Fehleranalyse von Diensten:

  • -u <unit> — nach Unit-Namen filtern
  • -f — das Protokoll in Echtzeit verfolgen (wie tail -f)
  • -n 50 — nur die letzten 50 Zeilen anzeigen
  • --since "1 hour ago" — den Zeitraum begrenzen
  • -p err — nur Fehler und Meldungen mit höherer Priorität anzeigen
  • -b — nur Protokolle des aktuellen Systemstarts anzeigen

Wenn eine Unit nicht gestartet werden kann, führen Sie zuerst journalctl -u <unit> -n 30 --no-pager und anschließend systemctl status <unit> aus, um den aktuellen Fehlerkontext zu erfassen.

#!/usr/bin/env bash
# Troubleshooting helper: dump unit status and recent logs
# Usage: ./service-debug.sh <unit-name>

UNIT="${1:-nginx.service}"

echo "=============================="
echo "STATUS: $UNIT"
echo "=============================="
systemctl status "$UNIT" --no-pager -l

echo ""
echo "=============================="
echo "RECENT LOGS (last 50 lines): $UNIT"
echo "=============================="
journalctl -u "$UNIT" -n 50 --no-pager

echo ""
echo "=============================="
echo "ERRORS ONLY (current boot)"
echo "=============================="
journalctl -u "$UNIT" -b -p err --no-pager

Wissensüberprüfung: systemd-Unit-Dateien

Testen Sie Ihr Verständnis der Konfiguration von systemd-Service- und Timer-Units.

Lektionsrückblick: systemd-Dienste steuern und Unit-Dateien schreiben

In dieser Lektion haben Sie die grundlegenden Konzepte der systemd-Dienstverwaltung und das professionelle Erstellen von Unit-Dateien kennengelernt. Hier ist eine Zusammenfassung der behandelten Themen:

  • systemctl-Grundlagen — start, stop, restart, reload, enable, disable, status, is-active und is-enabled für skriptfreundliche Prüfungen
  • Auflisten und Filtern — list-units und list-unit-files mit den Optionen --type und --state, um fehlgeschlagene oder aktivierte Dienste herauszufiltern
  • Aufbau von Unit-Dateien — die drei Abschnitte [Unit], [Service] und [Install] sowie ihre wichtigsten Direktiven
  • Diensttypen — simple, forking, notify, oneshot und der jeweilige geeignete Einsatz
  • Umgebung und Sicherheit — EnvironmentFile, NoNewPrivileges, ProtectSystem und PrivateTmp für gehärtete Daemons
  • Timer-Units — Verknüpfung von .timer- und .service-Dateien, OnCalendar-Ausdrücke und das Nachholen verpasster Ausführungen mit Persistent
  • Journalctl — Filtern nach Unit, Zeit, Systemstart und Priorität, um Fehler effizient zu diagnostizieren

Mit diesen Kenntnissen können Sie jeden Systemdienst verwalten, wiederkehrende Aufgaben zuverlässig planen und produktionsreife Unit-Dateien für Ihre eigenen Daemons erstellen.

Häufig gestellte Fragen

Ist die Lektion „systemd-Dienste steuern und Unit-Dateien schreiben“ kostenlos?

Ja — der vollständige Text von „systemd-Dienste steuern und Unit-Dateien schreiben“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des DevOps Bootcamp-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „systemd-Dienste steuern und Unit-Dateien schreiben“?

Steuern Sie Dienste mit systemctl und erstellen Sie eigene Unit- und Timer-Dateien für daemonisierte Skripte. Du übst DevOps Bootcamp mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um DevOps Bootcamp zu starten?

Keine Vorkenntnisse erforderlich. DevOps Bootcamp auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „systemd-Dienste steuern und Unit-Dateien schreiben“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser DevOps Bootcamp-Lektion Code schreiben und ausführen?

Ja. Jede DevOps Bootcamp-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Bereitstellung von Benutzern und Gruppen automatisieren
  2. systemd-Dienste steuern und Unit-Dateien schreiben
  3. Datenträger-, Dateisystem- und Mount-Automatisierung
  4. Skripte für Systemprüfungen und Warnmeldungen erstellen
← Zurück zu DevOps Bootcamp