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.
systemctl status --no-pager --full meinservice.serviceAchten 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.
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 RestartInterpretation: 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.
systemctl list-jobs
systemd-analyze critical-chain
systemd-analyze blamesystemd-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.
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 200Nutzen 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.
# 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=7dHinweis: 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.
systemctl status --no-pager NetworkManager-wait-online.service
systemctl status --no-pager systemd-networkd-wait-online.serviceMounts: 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.
findmnt -T /var/lib/meinservice
systemctl status --no-pager var-lib-meinservice.mountZyklische 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.
systemctl status --no-pager meinservice.socket
systemctl status --no-pager meinservice.service
ss -lntpWenn 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.
# 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 PIDFü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.
# 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.pidDebug-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.
# 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 || trueWenn 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.
# 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.serviceCanary-Deployment und Rollback-Strategie für Unit-Änderungen
Systemd-Overrides sind mächtig; behandeln Sie sie wie Code:
- Versionieren Sie Drop-ins in Git und dokumentieren Sie die Änderung.
- Führen Sie Änderungen zuerst auf einer Einzelinstanz (Canary) durch.
- Automatisierter Test: Start-Check, Health-Check (Port, Endpoint), Smoke-Tests.
- Rollout stufenweise und mit Monitoring, Rollback durch Entfernen des Drop-ins und daemon-reload.
# 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.servicePraxis-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
- Zustand sichern: Status, Jobs, Logs sammeln.
- Fehlerklasse bestimmen: hängt, läuft ohne Funktion, crasht.
- Abhängigkeit identifizieren: list-dependencies + critical-chain.
- Blocker prüfen: Journal der blockierenden Unit, Mount/Netz/Socket-Status.
- Crashpfad prüfen: coredumpctl info, Kernel-Logs auf OOM.
- Konfiguration prüfen: systemctl cat, Drop-ins verifizieren.
- Kontrollierter Neustart zur Hypothesentestung; danach Logs sichern.
# 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.
# 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-runoder 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.