Fehlerbehebung bei Linux-Diensten mit systemctl und journalctl

Ein praktischer Workflow zur Fehlerbehebung bei fehlgeschlagenen oder fehlerhaften Linux-Diensten mit systemctl und journalctl.

Fehlerbehebung bei Linux-Diensten mit systemctl und journalctl

Wenn ein Linux-Dienst ausfällt, ist der schnellste Weg normalerweise keine Websuche. Es sind drei lokale Überprüfungen: was systemd denkt, was passiert ist, was der Dienst protokolliert hat und was sich vor dem Fehler geändert hat. systemctl und journalctl geben Ihnen diese Antworten, ohne zu raten.

Diese Anleitung verwendet häufige Dienstfehler als Beispiele: einen Dienst, der nicht startet, einen Prozess, der läuft, aber keine nützliche Arbeit verrichtet, und einen Dienst, der beendet wird, nachdem er gesund aussah. Die Befehle gelten für die meisten systemd-verwalteten Dienste, aber die genauen Einheitennamen und Protokollspeicherorte variieren je nach Distribution und Paket.

Grundlegendes zu systemctl und journalctl

Bevor Sie mit der Fehlerbehebung beginnen, ist es wichtig, die Rollen dieser beiden primären Werkzeuge zu verstehen:

  • systemctl: Dieser Befehl ist das zentrale Dienstprogramm zum Steuern und Abfragen des systemd-System- und Dienstmanagers. Damit können Sie Dienste starten, stoppen, neu starten, ihren Status überprüfen und aktivieren/deaktivieren.
  • journalctl: Dieser Befehl wird verwendet, um das systemd-Journal abzufragen, ein zentralisiertes Protokollierungssystem. Es sammelt Protokolle vom Kernel, Systemdiensten und Anwendungen und bietet eine einheitliche Ansicht von Systemereignissen. journalctl ist unverzichtbar, um zu verstehen, warum ein Dienst fehlgeschlagen ist oder sich unerwartet verhalten hat.

Häufige Szenarien zur Fehlerbehebung und Lösungen

Lassen Sie uns typische Probleme untersuchen und wie man sie angeht:

1. Dienst konnte nicht gestartet werden

Dies ist vielleicht das häufigste Problem. Sie versuchen, einen Dienst zu starten, und er schlägt sofort fehl.

Schritt 1: Überprüfen Sie den Dienststatus

Verwenden Sie systemctl status, um einen sofortigen Überblick über den Zustand des Dienstes und die letzten Protokolleinträge zu erhalten.

sudo systemctl status apache2.service

Erwartete Ausgabe (illustrativ – Ihre kann abweichen):

● apache2.service - The Apache HTTP Server
     Geladen: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Aktiv: **failed** (result: exit-code) seit Di 2023-10-27 10:00:00 UTC; vor 1 Min.
       Docs: https://httpd.apache.org/docs/2.4/
    Prozess: 12345 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)
   Haupt-PID: 12345 (code=exited, status=1/FAILURE)

Okt 27 10:00:00 your-server systemd[1]: Starte The Apache HTTP Server...
Okt 27 10:00:00 your-server apachectl[12345]: AH00526: Syntaxfehler in Zeile 123 von /etc/apache2/apache2.conf:
Okt 27 10:00:00 your-server apachectl[12345]: Ungültiges Mutex-Verzeichnis im Argument file: '/var/run/apache2/'
Okt 27 10:00:00 your-server systemd[1]: apache2.service: Hauptprozess beendet, code=exited, status=1/FAILURE
Okt 27 10:00:00 your-server systemd[1]: **Fehler** beim Starten von The Apache HTTP Server.
Okt 27 10:00:00 your-server systemd[1]: apache2.service: Einheit ist in den Fehlerzustand eingetreten.

Analyse: Die Ausgabe von systemctl status zeigt deutlich Aktiv: failed und einen Ausschnitt der Fehlermeldung: Ungültiges Mutex-Verzeichnis im Argument file: '/var/run/apache2/'. Dies deutet auf ein Konfigurationsproblem hin.

Schritt 2: Untersuchen Sie Protokolle mit journalctl

Verwenden Sie für detailliertere Informationen journalctl, um speziell für den fehlgeschlagenen Dienst Protokolle anzuzeigen. Das Flag -u gibt die Einheit (den Dienst) an.

sudo journalctl -u apache2.service -xe
  • -u apache2.service: Filtert Protokolle für die Einheit apache2.service.
  • -x: Fügt Erklärungen für einige Protokollmeldungen hinzu.
  • -e: Springt zum Ende des Journals und zeigt die neuesten Einträge an.

Mögliche Erkenntnisse: Die journalctl-Ausgabe könnte mehr Kontext zu Konfigurationsfehlern, Berechtigungsproblemen oder Abhängigkeitsproblemen offenbaren.

Schritt 3: Überprüfen Sie die Konfigurationsdateien

Basierend auf der Fehlermeldung untersuchen Sie die relevanten Konfigurationsdateien. Im obigen Beispiel verweist es auf /etc/apache2/apache2.conf und das Verzeichnis /var/run/apache2/.

sudo nano /etc/apache2/apache2.conf

Lösung: Probleme wie dieses entstehen oft durch ein fehlendes Laufzeitverzeichnis, eine Paketänderung oder eine Konfigurationsdatei, die auf einen Pfad verweist, der nicht mehr existiert. Erstellen Sie nicht blind Verzeichnisse aus einem Beispiel aus dem Internet. Bestätigen Sie zuerst, was die Anwendung auf Ihrer Distribution erwartet, und beheben Sie dann den fehlenden Pfad oder die Konfiguration. Eine mögliche Reparatur könnte so aussehen:

sudo mkdir -p /var/run/apache2/
sudo chown www-data:www-data /var/run/apache2/
sudo systemctl start apache2.service

Wenn der Fehler ein Syntaxproblem erwähnt, führen Sie den eigenen Konfigurationstest der Anwendung aus, bevor Sie erneut starten:

sudo apachectl configtest
sudo nginx -t
sudo sshd -t

Anwendungsspezifische Validatoren erkennen Fehler, die systemd nicht verstehen kann. Systemd weiß, ob der Prozess beendet wurde. Es weiß nicht, ob Ihr Nginx-server-Block auf die falsche Zertifikatsdatei verweist oder ob eine Apache-Direktive in einen anderen Kontext gehört.

2. Dienst läuft, antwortet aber nicht

Manchmal zeigt systemctl status einen Dienst als active (running) an, aber er erfüllt nicht seine beabsichtigte Funktion (z. B. ein Webserver, der keine Seiten ausliefert).

Schritt 1: Überprüfen Sie den Dienststatus und die PID

Bestätigen Sie, dass er tatsächlich läuft und eine Prozess-ID (PID) hat.

sudo systemctl status nginx.service

Wenn es active (running) anzeigt, notieren Sie die PID.

Schritt 2: Untersuchen Sie die Dienstprotokolle auf Fehler

Selbst wenn er läuft, kann der Dienst interne Fehler aufweisen, die ihn daran hindern, ordnungsgemäß zu funktionieren.

sudo journalctl -u nginx.service -f
  • -f: Folgt der Protokollausgabe in Echtzeit. Dies ist nützlich, wenn Sie das Problem auslösen können (z. B. versuchen, auf die Webseite zuzugreifen), während journalctl läuft.

Schritt 3: Überprüfen Sie anwendungsspezifische Protokolle

Viele Dienste schreiben zusätzlich zum systemd-Journal eigene Protokolle. Überprüfen Sie für Webserver wie Nginx oder Apache die typischen Protokollspeicherorte (z. B. /var/log/nginx/error.log, /var/log/apache2/error.log).

sudo tail -n 50 /var/log/nginx/error.log

Schritt 4: Überprüfen Sie die Ressourcennutzung

Ein überlastetes System kann dazu führen, dass Dienste nicht mehr reagieren.

top
htop
free -h

Achten Sie auf hohe CPU-, Speicher- oder Festplatten-E/A durch die Prozesse des Dienstes.

Überprüfen Sie auch, ob der Dienst dort lauscht, wo Sie es erwarten:

sudo ss -ltnp
sudo ss -lunp

Bei einem Webdienst ist es nur die halbe Geschichte, nginx in systemctl aktiv zu sehen. Sie müssen immer noch wissen, ob es an 0.0.0.0:80, 127.0.0.1:8080, einem IPv6-Socket oder gar keinem Socket gebunden ist. Eine Firewall-Regel, ein Reverse-Proxy-Konflikt oder eine falsche Bind-Adresse können einen gesunden Prozess von außen kaputt aussehen lassen.

Lösung: Wenn Protokolle auf Probleme hinweisen oder Ressourcen knapp sind, müssen Sie möglicherweise:

  • Konfigurationen optimieren.
  • Den Dienst neu starten (sudo systemctl restart <dienstname>.service).
  • Zugrunde liegende Systemressourcenprobleme untersuchen.
  • Systemressourcen bei Bedarf erhöhen.

3. Dienst stoppt unerwartet

Wenn ein Dienst, der zuvor lief, plötzlich stoppt, liegt dies oft an einer nicht behandelten Ausnahme oder einem Watchdog-Timeout.

Schritt 1: Überprüfen Sie die letzten Ereignisse mit journalctl

Verwenden Sie journalctl, um zu sehen, was kurz vor dem Stoppen des Dienstes passiert ist. Die Flags --since und --until können hilfreich sein, wenn Sie die ungefähre Zeit kennen.

sudo journalctl -u <dienstname>.service --since "vor 1 Stunde"

Oder, um alle Protokolle zum Dienst seit dem letzten Start anzuzeigen:

sudo journalctl -u <dienstname>.service -b

Schritt 2: Suchen Sie nach Core Dumps oder Absturzberichten

Wenn der Dienst abgestürzt ist, hat das System möglicherweise einen Core Dump oder einen Absturzbericht erstellt.

ls -l /var/crash/

Schritt 3: Überprüfen Sie die systemd-Dienst-Unit-Datei

Untersuchen Sie die Unit-Datei des Dienstes (normalerweise in /etc/systemd/system/ oder /lib/systemd/system/) auf Restart=-Direktiven und WatchdogSec=-Einstellungen. Eine falsche Restart=-Konfiguration oder ein zu kurzes WatchdogSec= kann unerwartete Neustarts oder Fehler verursachen.

systemctl cat <dienstname>.service

Lösung: Beheben Sie die in den Protokollen identifizierte Ursache. Dies kann das Beheben von Codefehlern, das Anpassen von systemd-Unit-Datei-Parametern oder das Erhöhen von Ressourcengrenzen umfassen.

Wenn Sie wiederholte Neustarts sehen, überprüfen Sie, ob systemd die Einheit ratenbegrenzt hat:

systemctl status <dienstname>.service
journalctl -u <dienstname>.service --since "vor 30 Minuten"

Meldungen über Start request repeated too quickly bedeuten normalerweise, dass der Dienst mehrmals in einem kurzen Zeitfenster abgestürzt ist. Nachdem Sie das zugrunde liegende Problem behoben haben, setzen Sie den Fehlerzustand zurück:

sudo systemctl reset-failed <dienstname>.service
sudo systemctl start <dienstname>.service

4. Probleme mit systemctl enable oder systemctl disable

Obwohl es sich nicht um einen Laufzeitfehler handelt, können Probleme beim Aktivieren oder Deaktivieren von Diensten auftreten.

Problem: Ein Dienst ist aktiviert, startet aber nicht beim Booten, oder umgekehrt.

Status überprüfen:

sudo systemctl is-enabled <dienstname>.service

Dieser Befehl gibt enabled oder disabled aus.

Fehlerbehebung:

  • Stellen Sie sicher, dass die Dienst-Unit-Datei selbst gültig und korrekt platziert ist (z. B. /etc/systemd/system/).
  • Führen Sie nach Änderungen an einer Unit-Datei immer sudo systemctl daemon-reload aus.
  • Überprüfen Sie die Protokolle des Dienstes (journalctl -u <dienstname>.service) auf Startfehler, die verhindern könnten, dass er aktiv wird, selbst wenn er aktiviert ist.

Tipps für eine effektive Fehlerbehebung

  • Beginnen Sie mit systemctl status: Beginnen Sie immer hier. Es bietet eine schnelle Momentaufnahme und weist Ihnen oft den richtigen Weg.
  • Verwenden Sie journalctl -u <dienst>: Dies ist Ihr primäres Werkzeug, um zu verstehen, warum etwas passiert.
  • -f-Flag mit journalctl: Äußerst nützlich für die Echtzeitüberwachung, wenn Sie versuchen, ein Problem zu reproduzieren.
  • systemctl restart <dienst>: Führen Sie nach Konfigurationsänderungen immer einen Neustart des Dienstes durch, um sie anzuwenden.
  • systemctl daemon-reload: Entscheidend nach der Änderung von .service-Unit-Dateien.
  • Abhängigkeiten prüfen: Manchmal schlägt ein Dienst fehl, weil ein Dienst, von dem er abhängt, nicht gestartet ist oder selbst fehlschlägt. systemctl status zeigt dies oft an.
  • Berechtigungen: Viele Dienstfehler sind auf falsche Datei- oder Verzeichnisberechtigungen zurückzuführen. Stellen Sie sicher, dass der Benutzer, unter dem der Dienst läuft, den erforderlichen Zugriff hat.
  • Netzwerkprobleme: Wenn der Dienst auf das Netzwerk angewiesen ist, überprüfen Sie die Netzwerkkonnektivität, Firewall-Regeln und die Portverfügbarkeit.

Eine Fehlerbehebungsreihenfolge, die Bestand hat

Wenn der Druck groß ist, verwenden Sie jedes Mal die gleiche Reihenfolge:

systemctl status <dienst>.service
journalctl -u <dienst>.service -b --no-pager
systemctl cat <dienst>.service
systemctl list-dependencies <dienst>.service

Beginnen Sie mit dem aktuellen Zustand, lesen Sie dann die Protokolle des aktuellen Starts, inspizieren Sie dann die Einheit genau so, wie systemd sie sieht, und überprüfen Sie dann die Abhängigkeiten. Wenn der Dienst netzwerkorientiert ist, fügen Sie ss -ltnp und einen lokalen curl- oder Client-Test hinzu. Wenn er eine Konfigurationsdatei liest, führen Sie den eigenen Konfigurationsvalidator des Dienstes aus.

Der Punkt ist, zufällige Neustarts zu vermeiden. Ein Neustart kann nach einer Konfigurationsänderung oder einem feststeckenden Prozess eine gültige Lösung sein, aber er vernichtet auch Beweise. Lesen Sie genug vom Journal, bevor Sie wissen, was Sie ändern und warum.

Journal-Ausgabe lesen, ohne sich zu verlieren

journalctl kann laut sein, besonders auf vielbeschäftigten Servern. Beginnen Sie eng und erweitern Sie nur, wenn Sie müssen.

Für einen Dienst im aktuellen Start:

journalctl -u <dienst>.service -b --no-pager

Für die letzten Minuten:

journalctl -u <dienst>.service --since "vor 15 Minuten" --no-pager

Für den vorherigen Start:

journalctl -u <dienst>.service -b -1 --no-pager

Diese Ansicht des vorherigen Starts ist nützlich, wenn ein Dienst während des Startvorgangs fehlgeschlagen und dann wiederhergestellt wurde oder wenn die gesamte Maschine neu gestartet wurde, bevor Sie sie inspizieren konnten. Sie können Starts auflisten mit:

journalctl --list-boots

Wenn der Dienst strukturierte Felder oder lange Zeilen protokolliert, verwenden Sie kurze ISO-Zeitstempel:

journalctl -u <dienst>.service -o short-iso --no-pager

Wenn Sie Protokolle teilen müssen, entfernen Sie Geheimnisse, Token, interne Hostnamen und Kundendaten. Dienstprotokolle enthalten oft umgebungsabgeleitete Einstellungen, URLs, Header oder Verbindungszeichenfolgen. Eine saubere Fehlerbehebungsgewohnheit beinhaltet die Schwärzung, bevor Sie eine Ausgabe irgendwo einfügen.

Wenn systemctl "Aktiv" sagt, Benutzer aber immer noch einen Fehler sehen

Ein active (running)-Zustand bedeutet nur, dass systemd einen Prozess hat, der den Erwartungen der Einheit entspricht. Es beweist nicht, dass die Anwendung gesund ist. Eine Webanwendung kann laufen, während sie HTTP 500 zurückgibt. Ein Worker kann aktiv sein, während er an einer fehlerhaften Warteschlangennachricht hängt. Ein Datenbank-Proxy kann laufen, während alle Backend-Verbindungen fehlschlagen.

Testen Sie für Netzwerkdienste von denselben Ebenen aus, auf die Ihre Benutzer angewiesen sind:

curl -v http://127.0.0.1:8080/health
curl -v http://localhost/health
curl -v https://service.example.com/health

Diese drei Überprüfungen beantworten unterschiedliche Fragen. Die erste überprüft den lokalen App-Port. Die zweite kann einen lokalen Reverse-Proxy enthalten. Die dritte überprüft DNS, TLS, Routing, Firewall-Regeln und den öffentlich zugänglichen Pfad.

Überprüfen Sie für Worker-Dienste die Sache, die sie verbrauchen oder produzieren. Ein Warteschlangen-Worker benötigt möglicherweise eine Überprüfung der Warteschlangentiefe. Ein Backup-Dienst benötigt möglicherweise eine aktuelle Ausgabedatei. Ein Metriksammler benötigt möglicherweise eine Abfrage gegen das Metrik-Backend. systemctl sagt Ihnen, ob die Überwachung funktioniert; Anwendungsprüfungen sagen Ihnen, ob der Dienst nützlich ist.

Beheben Sie jeweils eine Variable

Wenn eine Einheit nach einer Bereitstellung ausfällt, ist es verlockend, mehrere Dinge zu ändern und neu zu starten. Das kann die eigentliche Ursache verschleiern. Bevorzugen Sie jeweils eine Änderung:

systemctl cat my-app.service
journalctl -u my-app.service --since "vor 30 Minuten" --no-pager
sudo systemctl edit my-app.service
sudo systemctl daemon-reload
sudo systemctl restart my-app.service

Überprüfen Sie dann das Ergebnis, bevor Sie die nächste Sache ändern. Wenn der Fehler eine fehlende Datei ist, korrigieren Sie den Dateipfad. Wenn es ein Berechtigungsfehler ist, korrigieren Sie den Besitzer oder Modus. Wenn es eine Abhängigkeit ist, korrigieren Sie die Einheitenbeziehung oder das Wiederholungsverhalten der Anwendung. Langsame, langweilige Fehlerbehebung ist oft schneller als eine Neustartschleife mit fünf unverfolgten Bearbeitungen.