GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Beginnen Sie mit der Verwendung von systemd als Tool zur Fehlerbehebung

Niemand würde systemd wirklich als Tool zur Fehlerbehebung betrachten, aber als ich auf meinem Webserver auf ein Problem stieß, half mir mein wachsendes Wissen über systemd und einige seiner Funktionen, das Problem zu lokalisieren und zu umgehen.

Das Problem bestand darin, dass mein Server, Yorktown, der Namensdienste, DHCP-, NTP-, HTTPD- und SendMail-E-Mail-Dienste für mein Heimnetzwerk bereitstellt, den Apache HTTPD-Daemon während des normalen Starts nicht starten konnte. Ich musste es manuell starten, nachdem ich bemerkte, dass es nicht lief. Das Problem besteht seit einiger Zeit, und ich habe kürzlich versucht, es zu beheben.

Einige von Ihnen werden sagen, dass systemd selbst die Ursache dieses Problems ist, und basierend auf dem, was ich jetzt weiß, stimme ich Ihnen zu. Ich hatte jedoch ähnliche Probleme mit SystemV. (Im ersten Artikel dieser Reihe habe ich die Kontroverse um systemd als Ersatz für das alte SystemV-Init-Programm und die Startskripte betrachtet. Wenn Sie mehr über systemd erfahren möchten, lesen Sie auch den zweiten und dritten Artikel.) Keine Software ist perfekt, und weder systemd noch SystemV bilden eine Ausnahme, aber systemd bietet weitaus mehr Informationen zur Problemlösung als SystemV jemals angeboten hat.

Bestimmung des Problems

Der erste Schritt, um die Ursache dieses Problems zu finden, besteht darin, den Status des httpd-Dienstes zu ermitteln:

[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Thu 2020-04-16 11:54:37 EDT; 15min ago
     Docs: man:httpd.service(8)
  Process: 1101 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 1101 (code=exited, status=1/FAILURE)
   Status: "Reading configuration..."
      CPU: 60ms

Apr 16 11:54:35 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 11:54:37 yorktown.both.org httpd[1101]: (99)Cannot assign requested address: AH00072: make_sock: could not bind to address 192.168.0.52:80
Apr 16 11:54:37 yorktown.both.org httpd[1101]: no listening sockets available, shutting down
Apr 16 11:54:37 yorktown.both.org httpd[1101]: AH00015: Unable to open logs
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Failed with result 'exit-code'.
Apr 16 11:54:37 yorktown.both.org systemd[1]: Failed to start The Apache HTTP Server.
[root@yorktown ~]#

Diese Statusinformationen sind eine der systemd-Funktionen, die ich viel nützlicher finde als alles, was SystemV bietet. Die Menge an hilfreichen Informationen hier führt mich leicht zu einer logischen Schlussfolgerung, die mich in die richtige Richtung führt. Alles, was ich jemals von der alten chkconfig bekommen habe Befehl ist, ob der Dienst ausgeführt wird oder nicht, und die Prozess-ID (PID), falls dies der Fall ist. Das ist nicht sehr hilfreich.

Der Schlüsseleintrag in diesem Statusbericht zeigt, dass HTTPD sich nicht an die IP-Adresse binden kann, was bedeutet, dass es keine eingehenden Anfragen annehmen kann. Dies weist darauf hin, dass das Netzwerk nicht schnell genug startet, um für den HTTPD-Dienst bereit zu sein, sich an die IP-Adresse zu binden, da die IP-Adresse noch nicht festgelegt wurde. Das sollte eigentlich nicht passieren, also habe ich die Systemd-Startkonfigurationsdateien meines Netzwerkdienstes untersucht; alles schien korrekt zu sein mit den richtigen „nach“- und „erfordert“-Aussagen. Hier ist der /lib/systemd/system/httpd.service Datei von meinem Server:

# Modifying this file in-place is not recommended, because changes                                                                                    
# will be overwritten during package upgrades.  To customize the                                                                                      
# behaviour, run "systemctl edit httpd" to create an override unit.                                                                                  
                                                                                                                                                     
# For example, to pass additional options (such as -D definitions) to                                                                                
# the httpd binary at startup, create an override unit (as is done by                                                                                
# systemctl edit) and enter the following:                                                                                                            
                                                                                                                                                     
#       [Service]                                                                                                                                    
#       Environment=OPTIONS=-DMY_DEFINE                                                                                                              
                                                                                                                                                     
[Unit]                                                                                                                                                
Description=The Apache HTTP Server                                                                                                                    
Wants=httpd-init.service                                                                                                                              
After=network.target remote-fs.target nss-lookup.target httpd-init.service                                                                            
Documentation=man:httpd.service(8)                                                                                                                    
                                                                                                                                                     
[Service]                                                                                                                                            
Type=notify                                                                                                                                          
Environment=LANG=C                                                                                                                                    
                                                                                                                                                     
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND                                                                                                      
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful                                                                                                      
# Send SIGWINCH for graceful stop                                                                                                                    
KillSignal=SIGWINCH                                                                                                                                  
KillMode=mixed                                                                                                                                        
PrivateTmp=true                                                                                                                                      
                                                                                                                                                     
[Install]                                                                                                                                            
WantedBy=multi-user.target

Der httpd.service Unit-Datei gibt explizit an, dass sie nach network.target geladen werden soll und der httpd-init.service (unter anderen). Ich habe versucht, alle diese Dienste mithilfe der systemctl list-units zu finden Befehl und sucht sie im resultierenden Datenstrom. Alle waren anwesend und hätten sicherstellen sollen, dass der httpd-Dienst nicht geladen wurde, bevor die Netzwerk-IP-Adresse festgelegt wurde.

Erste Lösung

Mehr über Systemadministratoren

  • Sysadmin-Blog aktivieren
  • Das automatisierte Unternehmen:ein Leitfaden zur IT-Verwaltung mit Automatisierung
  • eBook:Ansible-Automatisierung für SysAdmins
  • Geschichten aus der Praxis:Ein Leitfaden für Systemadministratoren zur IT-Automatisierung
  • eBook:Ein Leitfaden zu Kubernetes für SREs und Systemadministratoren
  • Neueste Sysadmin-Artikel

Ein wenig Suche im Internet bestätigte, dass andere auf ähnliche Probleme mit httpd und anderen Diensten gestoßen waren. Dies scheint zu passieren, weil einer der erforderlichen Dienste systemd anzeigt, dass er seinen Startvorgang abgeschlossen hat – aber tatsächlich einen untergeordneten Prozess ausgliedert, der noch nicht abgeschlossen ist. Nach etwas mehr Suche bin ich auf eine Umgehung gestoßen.

Ich konnte nicht herausfinden, warum es so lange dauerte, bis die IP-Adresse der Netzwerkschnittstellenkarte zugewiesen wurde. Also dachte ich, wenn ich den Start des HTTPD-Dienstes um eine angemessene Zeit verzögern könnte, würde die IP-Adresse bis zu diesem Zeitpunkt zugewiesen werden.

Glücklicherweise ist der /lib/systemd/system/httpd.service Die obige Datei gibt eine Richtung vor. Obwohl es heißt, es nicht zu ändern, zeigt es an, wie vorzugehen ist:Verwenden Sie den Befehl systemctl edit httpd , wodurch automatisch eine neue Datei erstellt wird (/etc/systemd/system/httpd.service.d/override.conf ) und öffnet den GNU Nano Editor. (Wenn Sie mit Nano nicht vertraut sind, lesen Sie unbedingt die Hinweise am unteren Rand der Nano-Benutzeroberfläche.)

Fügen Sie der neuen Datei den folgenden Text hinzu und speichern Sie sie:

[root@yorktown ~]# cd /etc/systemd/system/httpd.service.d/
[root@yorktown httpd.service.d]# ll
total 4
-rw-r--r-- 1 root root 243 Apr 16 11:43 override.conf
[root@yorktown httpd.service.d]# cat override.conf
# Trying to delay the startup of httpd so that the network is
# fully up and running so that httpd can bind to the correct
# IP address
#
# By David Both, 2020-04-16

[Service]
ExecStartPre=/bin/sleep 30

Der [Dienst] Abschnitt dieser Überschreibungsdatei enthält eine einzelne Zeile, die den Start des HTTPD-Dienstes um 30 Sekunden verzögert. Der folgende Statusbefehl zeigt den Dienststatus während der Wartezeit an:

[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf
           /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: activating (start-pre) since Thu 2020-04-16 12:14:29 EDT; 28s ago
     Docs: man:httpd.service(8)
Cntrl PID: 1102 (sleep)
    Tasks: 1 (limit: 38363)
   Memory: 260.0K
      CPU: 2ms
   CGroup: /system.slice/httpd.service
           └─1102 /bin/sleep 30

Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.
[root@yorktown ~]#

Und dieser Befehl zeigt den Status des HTTPD-Dienstes nach Ablauf der 30-Sekunden-Verzögerung an. Der Dienst ist eingerichtet und wird korrekt ausgeführt:

[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf
           /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: active (running) since Thu 2020-04-16 12:15:01 EDT; 1min 18s ago
     Docs: man:httpd.service(8)
  Process: 1102 ExecStartPre=/bin/sleep 30 (code=exited, status=0/SUCCESS)
 Main PID: 1567 (httpd)
   Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec:   0 B/sec"
    Tasks: 213 (limit: 38363)
   Memory: 21.8M
      CPU: 82ms
   CGroup: /system.slice/httpd.service
           ├─1567 /usr/sbin/httpd -DFOREGROUND
           ├─1569 /usr/sbin/httpd -DFOREGROUND
           ├─1570 /usr/sbin/httpd -DFOREGROUND
           ├─1571 /usr/sbin/httpd -DFOREGROUND
           └─1572 /usr/sbin/httpd -DFOREGROUND

Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.

Ich hätte experimentieren können, um zu sehen, ob eine kürzere Verzögerung auch funktionieren würde, aber mein System ist nicht so kritisch, also habe ich mich dagegen entschieden. Es funktioniert so wie es ist zuverlässig, also bin ich zufrieden.

Da ich all diese Informationen gesammelt habe, habe ich sie Red Hat Bugzilla als Fehler 1825554 gemeldet. Ich glaube, dass es viel produktiver ist, Fehler zu melden, als sich über sie zu beschweren.

Die bessere Lösung

Ein paar Tage, nachdem ich dies als Fehler gemeldet hatte, erhielt ich eine Antwort, die darauf hinwies, dass systemd nur der Manager ist, und wenn httpd bestellt werden muss, nachdem einige Anforderungen erfüllt sind, muss dies in der Unit-Datei ausgedrückt werden. Die Antwort verwies mich auf den httpd.service Manpage. Ich wünschte, ich hätte das früher gefunden, weil es eine bessere Lösung ist als die, die ich mir ausgedacht habe. Diese Lösung zielt explizit auf die vorausgesetzte Zieleinheit ab und nicht auf eine etwas zufällige Verzögerung.

Vom httpd.service Manpage:

Starten des Dienstes beim Booten

Die Einheiten httpd.service und httpd.socket sind deaktiviert standardmäßig. Um den httpd-Dienst beim Booten zu starten, führen Sie Folgendes aus:systemctl enable httpd.service . In der Standardkonfiguration akzeptiert der httpd-Daemon Verbindungen auf Port 80 (und, wenn mod_ssl installiert ist, TLS-Verbindungen auf Port 443) für jede konfigurierte IPv4- oder IPv6-Adresse.

Wenn httpd so konfiguriert ist, dass es von einer bestimmten IP-Adresse abhängt (z. B. mit einer „Listen“-Direktive), die möglicherweise nur während des Starts verfügbar wird, oder wenn httpd von anderen Diensten (z. B. einem Datenbank-Daemon) abhängt, wird der Dienst muss konfiguriert werden, um eine korrekte Startreihenfolge zu gewährleisten.

Um beispielsweise sicherzustellen, dass httpd erst ausgeführt wird, nachdem alle konfigurierten Netzwerkschnittstellen konfiguriert sind, erstellen Sie eine Drop-in-Datei (wie oben beschrieben) mit dem folgenden Abschnitt:

[Einheit]

After=network-online.target

Wants=network-online.target

Ich denke immer noch, dass dies ein Fehler ist, weil es ziemlich üblich ist – zumindest meiner Erfahrung nach – ein Listen zu verwenden Direktive in der httpd.conf Konfigurationsdatei. Ich habe immer Listen verwendet Direktiven, selbst auf Hosts mit nur einer einzigen IP-Adresse, und es ist eindeutig notwendig auf Hosts mit mehreren Netzwerkschnittstellenkarten (NICs) und Internet Protocol (IP)-Adressen. Fügen Sie die obigen Zeilen zu /usr/lib/systemd/system/httpd.service hinzu default-Datei würde keine Probleme für Konfigurationen verursachen, die kein Listen verwenden Richtlinie und würde dieses Problem für diejenigen verhindern, die dies tun.

In der Zwischenzeit werde ich die vorgeschlagene Lösung verwenden.

Nächste Schritte

Dieser Artikel beschreibt ein Problem, das ich beim Starten des Apache HTTPD-Dienstes auf meinem Server hatte. Es führt Sie durch die Schritte zur Problembestimmung, die ich unternommen habe, und zeigt, wie ich systemd zur Unterstützung verwendet habe. Ich habe auch die Umgehung behandelt, die ich mit systemd implementiert habe, und die bessere Lösung, die sich aus meinem Fehlerbericht ergibt.

Wie ich eingangs erwähnt habe, ist es sehr wahrscheinlich, dass dies auf ein Problem mit systemd zurückzuführen ist, insbesondere auf die Konfiguration für den httpd-Start. Trotzdem hat mir systemd die Werkzeuge an die Hand gegeben, um die wahrscheinliche Ursache des Problems zu lokalisieren und eine Umgehung zu formulieren und umzusetzen. Keine Lösung löst das Problem wirklich zu meiner Zufriedenheit. Im Moment besteht die Ursache des Problems noch und muss behoben werden. Wenn das einfach das Hinzufügen der empfohlenen Zeilen zu /usr/lib/systemd/system/httpd.service ist Datei, das würde für mich funktionieren.

Eines der Dinge, die ich während dieses Prozesses entdeckt habe, ist, dass ich mehr darüber lernen muss, wie man die Sequenzen definiert, in denen die Dinge beginnen. Ich werde das in meinem nächsten Artikel untersuchen, dem fünften in dieser Serie.

Ressourcen

Es gibt eine Menge Informationen über systemd im Internet, aber vieles ist knapp, stumpf oder sogar irreführend. Zusätzlich zu den in diesem Artikel erwähnten Ressourcen bieten die folgenden Webseiten detailliertere und zuverlässigere Informationen zum Systemstart.

  • Das Fedora-Projekt hat eine gute, praktische Anleitung zu systemd. Es enthält so ziemlich alles, was Sie wissen müssen, um einen Fedora-Computer mit systemd zu konfigurieren, zu verwalten und zu warten.
  • Das Fedora-Projekt hat auch einen guten Spickzettel, der die alten SystemV-Befehle mit vergleichbaren Systemd-Befehlen vergleicht.
  • Detaillierte technische Informationen über systemd und die Gründe für seine Erstellung finden Sie in der Beschreibung von systemd auf Freedesktop.org.
  • Linux.com's "More systemd fun" bietet weiterführende Informationen und Tipps zu systemd.

Es gibt auch eine Reihe von sehr technischen Artikeln für Linux-Systemadministratoren von Lennart Poettering, dem Designer und Hauptentwickler von systemd. Diese Artikel wurden zwischen April 2010 und September 2011 geschrieben, sind aber heute genauso aktuell wie damals. Vieles von allem anderen Guten, das über systemd und sein Ökosystem geschrieben wurde, basiert auf diesen Papieren.

  • Überdenken von PID 1
  • systemd für Administratoren, Teil I
  • systemd für Administratoren, Teil II
  • systemd für Administratoren, Teil III
  • systemd für Administratoren, Teil IV
  • systemd für Administratoren, Teil V
  • systemd für Administratoren, Teil VI
  • systemd für Administratoren, Teil VII
  • systemd für Administratoren, Teil VIII
  • systemd für Administratoren, Teil IX
  • systemd für Administratoren, Teil X
  • systemd für Administratoren, Teil XI

Linux
  1. Verwalten Sie den Start mit systemd

  2. Verwenden des GNOME-Screenshot-Tools unter Linux wie ein Profi

  3. 5 Linux-Befehle, die ich verwenden werde

  4. Verwenden des SS-Tools für die Netzwerkfehlerbehebung

  5. Systemd-Dienst startet Nodejs nicht?

Erkunden Sie Binärdateien mit diesem voll funktionsfähigen Linux-Tool

So starten Sie den httpd-Dienst in RHEL Linux

Anzeige der Netzwerkbandbreitennutzung mit dem Bandwhich-Tool

Zeigen Sie Netzwerkinformationen in Linux mit What IP Tool an

Verwenden von systemd-Funktionen zum Sichern von Diensten

Verwenden der SSH-Portweiterleitung als Sicherheitstool unter Linux