IT-Admin.tech

systemd-Service-Abhängigkeiten debuggen: journalctl, systemctl und coredump-Analyse

Technisches Unit-Abhängigkeitsdiagramm für systemd mit Logauszügen und Terminalansicht
Unit-Graph, gezielte Log-Auszüge und ein Terminal im Hintergrund illustrieren die strukturierte Analyse von systemd-Abhängigkeiten mit systemctl, journalctl und coredumpctl.

Wer im Betrieb systemd-Service-Abhängigkeiten debuggen muss, braucht eine strukturierte Prüfreihenfolge statt hektischem Neustarten. Dieses Runbook richtet sich an Administratoren, System Engineers und Operatoren: Es verbindet systemctl (Status und Dependency-Graph), journalctl (kontextreiche Logs) und coredumpctl (Crash-Analyse) zu einer praktikablen Troubleshooting-Sequenz mit Ursachenbildern, Risiken, Prüfschritten und klaren Rückfallstrategien.

Warum Abhängigkeiten häufig die eigentliche Ursache sind

In systemd ist jede Unit (z. B. .service, .socket, .mount, .target) ein gewünschter Zustand. Abhängigkeiten legen fest, welche Units gestartet werden oder in welcher Reihenfolge. Entscheidend ist die Unterscheidung zwischen Reihenfolge (After=/Before=) und Bindung (Wants=/Requires=): Reihenfolge sagt nur, wer nach wem startet; Bindung legt fest, ob eine Unit den Start einer anderen erzwingt oder bei deren Fehlschlag mitgestoppt wird. Fehlerhaft modellierte Dependencies führen zu Boot-Delays, Race Conditions, Restart-Loops oder zu Diensten, die „active“ sind, aber keine Funktion liefern.

Ersteinschätzung: Symptomklasse bestimmen

Zu Beginn klären Sie: Startet die Unit nicht, hängt sie im Aktivierungszustand, läuft sie ohne Funktion oder crasht sie? Diese Einordnung bestimmt, ob Sie vorrangig Abhängigkeiten, Ressourcen (Mounts, Ports) oder Prozessfehler untersuchen.

Dienst startet nicht oder bleibt „activating“

Hauptursachen: blockierende ExecStartPre-Schritte, fehlende Mounts, Timeouts oder Jobs, die auf andere Units warten. Finden Sie zuerst heraus, ob systemd auf eine Voraussetzung wartet oder ob ein Startbefehl fehlschlägt.

Dienst läuft, Funktion fehlt

Oft ist nur die Reihenfolge definiert (After=), aber nicht die Startgarantie (Wants=/Requires=), oder der Dienst hat vor einem Mount geschrieben. Prüfen Sie, ob die nötigen Ressourcen tatsächlich vorhanden und erreichbar sind.

Dienst crasht oder startet endlos neu

Logs und Core Dumps sind hier zentral. Abhängigkeiten können dennoch beteiligt sein, wenn der Prozess bei fehlender Ressource (z. B. Datenbank) abstürzt. Unterscheiden Sie zwischen Crash durch Signal (z. B. SIGSEGV) und einem OOM-Kill des Kernels.

Schritt 1: systemctl status — schnell, aber gezielt

systemctl status liefert Exit-Codes, Restart-Zähler, Trigger-Informationen und letzte Logzeilen. Das ist der erste Blick, ersetzt aber nicht die weitere Kette.

Shell
systemctl status --no-pager --full meinservice.service

Achten Sie auf:

  • Active: Bei erwarteten Daemons ist active (running) richtig; active (exited) ist bei Type=oneshot korrekt, bei Daemons aber verdächtig.
  • ExecStart / ExecStartPre: Exit-Status ungleich 0 weist auf Konfigurations- oder Ressourcenfehler hin.
  • TriggeredBy: Hinweise auf Socket- oder Path-Activation.
  • StartLimit: Rate-Limits verhindern endlose Neustarts.

Schritt 2: Abhängigkeiten sichtbar machen

Unterscheiden Sie, welche Units gestartet werden sollen (Wants/Requires) und welche nur in Reihenfolge stehen (After/Before). Das zeigt, ob systemd für eine Voraussetzung sorgt oder nur wartet.

Shell
systemctl list-dependencies --all meinservice.service
systemctl list-dependencies --all --reverse meinservice.service
systemctl show meinservice.service -p Wants -p Requires -p After -p Before -p ExecStart -p Type -p Restart

Interpretation: Wenn in After= etwas steht, aber nicht in Wants/Requires=, existiert nur eine Reihenfolge, keine Startgarantie. Wenn Requires= gesetzt ist, schlägt der Start bei einem Fehler der Abhängigkeit fehl — bewusst einsetzen, wenn ohne Voraussetzung Datenverlust droht.

Schritt 3: Jobs, Blockaden und kritische Kette

Jobs sind geplante Aktionen; hängende Jobs blockieren Ketten. Nutzen Sie list-jobs und systemd-analyze, um Engpässe zu finden.

Shell
systemctl list-jobs
systemd-analyze critical-chain
systemd-analyze blame

systemd-analyze critical-chain zeigt, welche Units den Bootpfad verzögern — nützlich bei Boot-Blockaden durch Wait-Online-Services oder Mounts.

Schritt 4: journalctl gezielt einsetzen

Das Journal kombiniert Zeitstempel, PID und Unit-Kontext. Filtern Sie bewusst, sonst verlieren Sie sich in Daten. Arbeiten Sie entlang der Kette: Logs des betroffenen Dienstes, dann der blockierenden Units.

Shell
journalctl -u meinservice.service -b --no-pager -n 200
journalctl -u meinservice.service --since "30 min ago" --no-pager
journalctl -u abhaengige-unit.service -b --no-pager -n 200

Nutzen Sie Prioritätsfilter gezielt, aber prüfen Sie auch info-Meldungen, da viele Services Fehler nur informativ protokollieren.

Journal-Konfiguration, Limits und typische Stolperfallen

journald hat Konfigurationsgrenzen: begrenzter Speicher, Ratelimiting und optionales Forwarding an Syslog oder externen Log-Server. Wenn Logs fehlen, prüfen Sie die Speicherung und Ratelimit-Ereignisse.

Shell
# Prüfen, ob persistentes Journal aktiv ist
ls -ld /var/log/journal || echo "kein persistent journal"
# Zeige journald-Konfiguration
cat /etc/systemd/journald.conf
# Journald-Usage ansehen
journalctl --disk-usage
# Alte Logs platzsparend entfernen
journalctl --vacuum-size=500M
journalctl --vacuum-time=7d

Hinweis: Ratelimiting kann viele wiederkehrende Fehlermeldungen unterdrücken. In einem Incident schalten Sie das nicht grundsätzlich aus; identifizieren Sie zuerst die Ursache und heben nur testweise Ratelimits an.

Typische Fallen und schnelle Prüfungen

network.target vs. network-online.target

network.target signalisiert nur, dass der Netzwerkstack initialisiert ist, nicht unbedingt, dass Routing oder DNS funktionieren. network-online.target verlangt einen Wait-Online-Dienst; wenn dieser falsch konfiguriert ist, blockiert er Startketten.

Shell
systemctl status --no-pager NetworkManager-wait-online.service
systemctl status --no-pager systemd-networkd-wait-online.service

Mounts: Pfad existiert, Storage fehlt

Dienste schreiben manchmal in lokale Verzeichnisse, wenn ein NAS/Block-Device fehlt — später verschwindet der „Datenbestand“, wenn der Mount nachträglich kommt. Verwenden Sie RequiresMountsFor=, um Mounts sicherzustellen.

Shell
findmnt -T /var/lib/meinservice
systemctl status --no-pager var-lib-meinservice.mount

Zyklische Abhängigkeiten

Dependency-Cycles entstehen, wenn A von B und B indirekt von A abhängt. systemd meldet solche Zyklen; lösen Sie sie durch Entkopplung (Wants statt Requires) oder ein eigenes Target als Koordinator.

Socket-Activation

Bei .socket-Units startet der Dienst erst bei Verbindung. Das ist effizient, kann aber Monitoring verwirren: Der Dienst kann inactive sein, obwohl alles korrekt ist.

Shell
systemctl status --no-pager meinservice.socket
systemctl status --no-pager meinservice.service
ss -lntp

Wenn ein Dienst abstürzt: coredumpctl sicher nutzen

Core Dumps liefern detaillierte Absturzinformationen, können aber sensible Daten enthalten. Prüfen Sie Aufbewahrungsrichtlinien und Berechtigungen, bevor Sie Dumps erzeugen oder verteilen. Systemd verwaltet Dumps über systemd-coredump; die Konfiguration steht in /etc/systemd/coredump.conf.

Shell
# Prüfe coredump-Konfiguration
cat /etc/systemd/coredump.conf 2>/dev/null || true
# Liste verfügbare Dumps für eine Unit
coredumpctl --no-pager list meinservice.service
# Detailansicht eines bestimmten Dumps
coredumpctl info PID

Für die eigentliche Analyse können Sie den Core extrahieren oder direkt mit gdb öffnen. Auf Produktionssystemen fehlen häufig Debug-Symbole; ohne Symbole sind Stacktraces eingeschränkt, aber oft noch hilfreich.

Shell
# Direkt mit gdb starten (nur in gesicherter Umgebung)
coredumpctl debug PID
# Alternativ: Core und Executable exportieren
coredumpctl dump PID --output=core.pid
file /usr/bin/meinservice
gdb /usr/bin/meinservice core.pid

Debug-Symbole: Installieren Sie paket-spezifische -dbg/-debuginfo-Pakete auf einer „Analyse-VM“ oder nutzen Sie ein Symbol-Server. Vermeiden Sie breite Debug-Installationen auf Produktionsknoten aus Speicher- und Sicherheitsgründen.

Sicherheits-Einschränkungen und Namespace-Effekte

Unit-Einstellungen wie ProtectSystem=, PrivateTmp=, NoNewPrivileges= oder Capability-Revoke können Services den Zugriff verwehren, obwohl Dependencies erfüllt sind. Solche Härtungsoptionen sind wichtig für Sicherheit, können aber unerwartete Fehlfunktionen verursachen.

Shell
# Prüfen, ob Härtung gesetzt ist
systemctl show meinservice.service -p ProtectSystem -p PrivateTmp -p NoNewPrivileges -p CapabilityBoundingSet
# SELinux-Denies prüfen (falls aktiv)
ausearch -m AVC -ts recent || true
# AppArmor-Denies prüfen
dmesg | grep apparmor || true

Wenn ein Audit-Daemon Zugriffsprobleme meldet, lesen Sie die Audit-Logs, bevor Sie Härtungsoptionen lockern.

Wants, Requires, BindsTo: Regeln für sinnvolle Modelle

Wann welches Verhalten wählen? Kurz gefasst:

  • Wants=: weiche Bindung, versucht zu starten, toleriert Fehler der Abhängigkeit.
  • Requires=: harte Bindung, scheitert oder stoppt bei Fehlern der Abhängigkeit.
  • BindsTo=: wie Requires, aber zusätzlich wird die Unit gestoppt, wenn die Abhängigkeit verschwindet (z. B. Gerät entfernt).

Beispiel: Wenn Ihr Dienst auf eine Datenbank angewiesen ist, wählen Sie Wants=database.service + After=database.service für weiches Verhalten mit kontrollierten Timeouts; wählen Sie Requires=, wenn Start ohne DB kritische Fehler verursacht.

Ini
# Drop-in: /etc/systemd/system/meinservice.service.d/override.conf
[Unit]
Wants=postgresql.service
After=postgresql.service
# Alternativ für harte Abhängigkeit
# Requires=postgresql.service
# After=postgresql.service

Canary-Deployment und Rollback-Strategie für Unit-Änderungen

Systemd-Overrides sind mächtig; behandeln Sie sie wie Code:

  1. Versionieren Sie Drop-ins in Git und dokumentieren Sie die Änderung.
  2. Führen Sie Änderungen zuerst auf einer Einzelinstanz (Canary) durch.
  3. Automatisierter Test: Start-Check, Health-Check (Port, Endpoint), Smoke-Tests.
  4. Rollout stufenweise und mit Monitoring, Rollback durch Entfernen des Drop-ins und daemon-reload.
Shell
# Canary: Änderung anwenden und prüfen
systemctl edit meinservice.service   # erstellt Drop-in
systemctl daemon-reload
systemctl restart meinservice.service
# Smoke-Test
ss -lnt | grep 12345
curl -f http://127.0.0.1:12345/health || echo "Healthcheck failed"
# Rollback
rm /etc/systemd/system/meinservice.service.d/override.conf
systemctl daemon-reload
systemctl restart meinservice.service

Praxis-Checkliste für Hosting-Operatoren

  • Sammeln Sie initial Status, list-jobs, dependency-Graph und relevante Journal-Auszüge.
  • Prüfen Sie Mounts, DNS/Backend-Erreichbarkeit und Ports, bevor Sie Unit-Änderungen machen.
  • Beschränken Sie Debug-Installationen auf Analyse-Boxen, nicht produktiv.
  • Versionieren Sie Drop-ins und testen Sie Rollbacks regelmäßig in Staging.
  • Richten Sie zentrales Log-Forwarding ein, damit Boot- und Kernel-Logs nicht verlorengehen.

Runbook: Schrittfolge für ein Incident

  1. Zustand sichern: Status, Jobs, Logs sammeln.
  2. Fehlerklasse bestimmen: hängt, läuft ohne Funktion, crasht.
  3. Abhängigkeit identifizieren: list-dependencies + critical-chain.
  4. Blocker prüfen: Journal der blockierenden Unit, Mount/Netz/Socket-Status.
  5. Crashpfad prüfen: coredumpctl info, Kernel-Logs auf OOM.
  6. Konfiguration prüfen: systemctl cat, Drop-ins verifizieren.
  7. Kontrollierter Neustart zur Hypothesentestung; danach Logs sichern.
Shell
# Schnell-Check-Skript (kompakt)
systemctl status --no-pager --full meinservice.service
systemctl list-dependencies --all meinservice.service
systemd-analyze critical-chain
journalctl -u meinservice.service -b --no-pager -n 200
coredumpctl --no-pager list meinservice.service || true
systemctl cat meinservice.service

Rollback, Rescue und Worst-Case-Szenarien

Wenn ein Override die Situation verschlechtert, entfernen Sie das Drop-in und laden systemd neu. Testen Sie Rollback-Schritte regelmäßig. Im Worst Case booten Sie in den Rescue-Mode, mounten die Systempartition und entfernen störende Drop-ins manuell.

Shell
# Drop-in entfernen und Rollback
rm -f /etc/systemd/system/meinservice.service.d/override.conf
systemctl daemon-reload
systemctl restart meinservice.service
systemctl status --no-pager --full meinservice.service

Fazit

systemd-Service-Abhängigkeiten debuggen heißt, Ketten zu lesen statt nur Services neu zu starten. Mit einer festen Prüfreihenfolge — Status prüfen, Dependency-Graph analysieren, Jobs/Blocker identifizieren, Logs und Core Dumps auswerten — finden Sie die Root Cause schneller und führen Änderungen sicher und rückrollbar aus. Für Hosting-Umgebungen reduziert diese Arbeitsweise Incident-Zeiten und minimiert Seiteneffekte wie Datenverlust durch falsche Mounts oder Boot-Blockaden. Pflegen Sie Versionierung für Drop-ins, dokumentierte Rollbacks und eine strukturierte Canary-Strategie, damit Änderungen kontrolliert und sicher ausgerollt werden können.

systemd-Service-Abhängigkeiten debuggen: Betriebsarchitektur, Fleet- und Integrationsaspekte

Neben dem Einzelknoten-Debugging gibt es eine Reihe architektur- und betriebsseitiger Aspekte, die Incidents verhindern oder bei Änderungen zu unerwarteten Abhängigkeiten führen können. Entscheider und IT-Leitung sollten diese Punkte in Deployment- und Observability-Pfaden verankern, damit Debugging auf der Infrastruktur- statt auf der Symptombehandlungsebene stattfindet.

Wichtige Aspekte:

  • Unit-Quelle und Paketverwaltung: Systemd lädt Unit-Dateien aus /lib/systemd/system (Vendor) und /etc/systemd/system (Admin). Verwenden Sie systemd-delta, um überschriebene Einträge zu erkennen und Überraschungen nach Paket-Updates zu vermeiden.
  • Enable/Mask-Strategie: Setzen Sie nicht-produktive Units gezielt auf masked, um automatische Starts zu verhindern. Prüfen Sie in CI, ob Deployments Units enabled/disabled hinterlassen.
  • Transient Units und Simulationen: Für Testläufe nutzen Sie systemd-run oder transient units in einer isolierten Testumgebung, bevor Sie Änderungen in der gesamten Flotte ausrollen.
  • Konfigurationsdrift und Automatisierung: Versionieren Sie Unit-Änderungen im Konfig-Repo und validieren Sie Unit-Syntax automatisiert (systemd-analyze verify) als Teil des Release-Pipelines. So vermeiden Sie unterschiedliche Dependency-Modelle zwischen Staging und Produktion.
  • Observability und Alerting: Modellieren Sie Health-Checks, die nicht nur Prozess-Liveness, sondern Anwendungs-Health (z. B. DB-Verbindung) prüfen. Erstellen Sie Alerts für StartLimitHit, wiederholte Restart-Loops und erhöhte journald-Disk-Usage, damit Probleme frühzeitig erkennbar sind.
  • Datenschutz und Coredumps: Core Dumps können vertrauliche Daten enthalten. Definieren Sie Policies, wo Dumps gespeichert und wer Zugriff hat; nutzen Sie eine Analyse-VM mit Symbolserver statt breitflächiger Debug-Installationen auf Produktivsystemen.

Risiken bei Änderungen: package-Updates können Units überschreiben, Masking/unabsichtliche Enables führen zu Startzyklen, und inkonsistente network-online-Implementierungen erzeugen intermittierende Boot-Blockaden. Betreiben Sie daher Unit-Checks als Teil des Release-Prozesses und führen Sie Canary-Rollouts mit gezielten Inventar-Tags durch. So verbinden Sie systemd-Fehlerdiagnose mit nachhaltiger Betriebssteuerung und vermeiden wiederkehrende Abhängigkeitsvorfälle in Ihrer Hosting-Umgebung.

Für dieses Thema sind auch Systemd Abhängigkeiten wichtig. Der Beitrag ordnet diese Aspekte verständlich ein und zeigt, worauf es im Alltag ankommt.

Weiterfuehrend

Passende weitere Inhalte