GNU/Linux >> Tutoriels Linux >  >> Linux

Commencez à utiliser systemd comme outil de dépannage

Personne ne considérerait vraiment systemd comme un outil de dépannage, mais lorsque j'ai rencontré un problème sur mon serveur Web, ma connaissance croissante de systemd et de certaines de ses fonctionnalités m'a aidé à localiser et à contourner le problème.

Le problème était que mon serveur, yorktown, qui fournit des services de noms, DHCP, NTP, HTTPD et SendMail pour le réseau de mon bureau à domicile, n'a pas réussi à démarrer le démon Apache HTTPD lors du démarrage normal. J'ai dû le démarrer manuellement après avoir réalisé qu'il ne fonctionnait pas. Le problème durait depuis un certain temps et j'ai récemment essayé de le résoudre.

Certains d'entre vous diront que systemd lui-même est la cause de ce problème et, d'après ce que je sais maintenant, je suis d'accord avec vous. Cependant, j'ai eu des types de problèmes similaires avec SystemV. (Dans le premier article de cette série, j'ai examiné la controverse autour de systemd en remplacement de l'ancien programme d'initialisation SystemV et des scripts de démarrage. Si vous souhaitez en savoir plus sur systemd, lisez également les deuxième et troisième articles.) Aucun logiciel n'est parfait, et ni systemd ni SystemV ne font exception, mais systemd fournit bien plus d'informations pour la résolution de problèmes que SystemV n'en a jamais offert.

Déterminer le problème

La première étape pour trouver la source de ce problème consiste à déterminer l'état du service httpd :

[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 ~]#

Cette information d'état est l'une des fonctionnalités de systemd que je trouve beaucoup plus utile que tout ce que propose SystemV. La quantité d'informations utiles ici me conduit facilement à une conclusion logique qui me mène dans la bonne direction. Tout ce que j'ai obtenu de l'ancien chkconfig La commande indique si le service est en cours d'exécution ou non et l'ID de processus (PID) si c'est le cas. Ce n'est pas très utile.

L'entrée de clé dans ce rapport d'état indique que HTTPD ne peut pas se lier à l'adresse IP, ce qui signifie qu'il ne peut pas accepter les demandes entrantes. Cela indique que le réseau ne démarre pas assez rapidement pour être prêt pour que le service HTTPD se lie à l'adresse IP car l'adresse IP n'a pas encore été définie. Cela n'est pas censé se produire, j'ai donc exploré les fichiers de configuration de démarrage de systemd de mon service réseau; tout semblait correct avec les bonnes déclarations "après" et "nécessite". Voici le /lib/systemd/system/httpd.service fichier de mon serveur :

# 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

Le httpd.service le fichier d'unité spécifie explicitement qu'il doit être chargé après le network.target et le httpd-init.service (entre autres). J'ai essayé de trouver tous ces services en utilisant les systemctl list-units commande et les rechercher dans le flux de données résultant. Tous étaient présents et auraient dû s'assurer que le service httpd ne se chargeait pas avant que l'adresse IP du réseau ne soit définie.

Première solution

En savoir plus sur les administrateurs système

  • Activer le blog Sysadmin
  • L'entreprise automatisée :un guide pour gérer l'informatique avec l'automatisation
  • Livre électronique :Automatisation Ansible pour les administrateurs système
  • Témoignages du terrain :guide de l'administrateur système sur l'automatisation informatique
  • eBook :Un guide de Kubernetes pour les SRE et les administrateurs système
  • Derniers articles sur l'administrateur système

Une petite recherche sur Internet a confirmé que d'autres avaient rencontré des problèmes similaires avec httpd et d'autres services. Cela semble se produire parce que l'un des services requis indique à systemd qu'il a terminé son démarrage, mais il lance en fait un processus enfant qui n'est pas terminé. Après un peu plus de recherche, j'ai trouvé un contournement.

Je n'arrivais pas à comprendre pourquoi l'adresse IP prenait autant de temps à être attribuée à la carte d'interface réseau. Donc, j'ai pensé que si je pouvais retarder le démarrage du service HTTPD d'un délai raisonnable, l'adresse IP serait attribuée à ce moment-là.

Heureusement, le /lib/systemd/system/httpd.service fichier ci-dessus fournit une certaine direction. Bien qu'il indique de ne pas le modifier, il indique comment procéder :utilisez la commande systemctl edit httpd , qui crée automatiquement un nouveau fichier (/etc/systemd/system/httpd.service.d/override.conf ) et ouvre l'éditeur GNU Nano. (Si vous n'êtes pas familier avec Nano, assurez-vous de regarder les conseils au bas de l'interface Nano.)

Ajoutez le texte suivant au nouveau fichier et enregistrez-le :

[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

Le [Service] La section de ce fichier de remplacement contient une seule ligne qui retarde le démarrage du service HTTPD de 30 secondes. La commande d'état suivante affiche l'état du service pendant le temps d'attente :

[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 ~]#

Et cette commande affiche l'état du service HTTPD après l'expiration du délai de 30 secondes. Le service fonctionne correctement :

[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.

J'aurais pu expérimenter pour voir si un délai plus court fonctionnerait aussi, mais mon système n'est pas si critique, alors j'ai décidé de ne pas le faire. Il fonctionne de manière fiable tel quel, donc je suis content.

Parce que j'ai rassemblé toutes ces informations, je les ai signalées à Red Hat Bugzilla en tant que bogue 1825554. Je pense qu'il est beaucoup plus productif de signaler des bogues que de s'en plaindre.

La meilleure solution

Quelques jours après avoir signalé cela comme un bogue, j'ai reçu une réponse indiquant que systemd n'est que le gestionnaire, et si httpd doit être commandé après que certaines exigences soient remplies, il doit être exprimé dans le fichier d'unité. La réponse m'a dirigé vers le httpd.service page de manuel. J'aurais aimé trouver cela plus tôt car c'est une meilleure solution que celle que j'ai trouvée. Cette solution est explicitement ciblée sur l'unité cible prérequise plutôt qu'un délai quelque peu aléatoire.

À partir du httpd.service page de manuel :

Démarrer le service au démarrage

Les unités httpd.service et httpd.socket sont désactivées par défaut. Pour démarrer le service httpd au démarrage, exécutez :systemctl enable httpd.service . Dans la configuration par défaut, le démon httpd acceptera les connexions sur le port 80 (et, si mod_ssl est installé, les connexions TLS sur le port 443) pour toute adresse IPv4 ou IPv6 configurée.

Si httpd est configuré pour dépendre d'une adresse IP spécifique (par exemple, avec une directive "Listen") qui peut n'être disponible qu'au démarrage, ou si httpd dépend d'autres services (comme un démon de base de données), le service doit être configuré pour garantir une commande de démarrage correcte.

Par exemple, pour vous assurer que httpd ne s'exécute qu'après la configuration de toutes les interfaces réseau configurées, créez un fichier d'insertion (comme décrit ci-dessus) avec la section suivante :

[Unité]

Après=network-online.target

Veut=network-online.target

Je pense toujours qu'il s'agit d'un bogue car il est assez courant, du moins d'après mon expérience, d'utiliser un écoute directive dans httpd.conf fichier de configuration. J'ai toujours utilisé Écouter directives, même sur les hôtes avec une seule adresse IP, et il est clairement nécessaire sur les hôtes avec plusieurs cartes d'interface réseau (NIC) et adresses de protocole Internet (IP). Ajout des lignes ci-dessus à /usr/lib/systemd/system/httpd.service le fichier par défaut ne causerait pas de problèmes pour les configurations qui n'utilisent pas un écoute directive et éviterait ce problème pour ceux qui le font.

En attendant, je vais utiliser la solution suggérée.

Étapes suivantes

Cet article décrit un problème que j'ai rencontré lors du démarrage du service Apache HTTPD sur mon serveur. Il vous guide à travers les étapes de détermination du problème que j'ai prises et montre comment j'ai utilisé systemd pour vous aider. J'ai également couvert le contournement que j'ai implémenté à l'aide de systemd et la meilleure solution qui découlait de mon rapport de bogue.

Comme je l'ai mentionné au début, il est très probable que cela soit le résultat d'un problème avec systemd, en particulier la configuration pour le démarrage de httpd. Néanmoins, systemd m'a fourni les outils pour localiser la source probable du problème et pour formuler et mettre en œuvre un contournement. Aucune des deux solutions ne résout vraiment le problème à ma satisfaction. Pour l'instant, la cause première du problème existe toujours et doit être corrigée. S'il s'agit simplement d'ajouter les lignes recommandées au /usr/lib/systemd/system/httpd.service fichier, cela fonctionnerait pour moi.

L'une des choses que j'ai découvertes au cours de ce processus est que j'ai besoin d'en savoir plus sur la définition des séquences dans lesquelles les choses commencent. J'explorerai cela dans mon prochain article, le cinquième de cette série.

Ressources

De nombreuses informations sur systemd sont disponibles sur Internet, mais la plupart sont concises, obtuses ou même trompeuses. En plus des ressources mentionnées dans cet article, les pages Web suivantes offrent des informations plus détaillées et fiables sur le démarrage de systemd.

  • Le projet Fedora propose un bon guide pratique de systemd. Il contient à peu près tout ce que vous devez savoir pour configurer, gérer et entretenir un ordinateur Fedora à l'aide de systemd.
  • Le projet Fedora a également une bonne feuille de triche qui renvoie les anciennes commandes SystemV à des commandes systemd comparables.
  • Pour des informations techniques détaillées sur systemd et les raisons de sa création, consultez la description de systemd par Freedesktop.org.
  • Linux.com's "More systemd fun" propose des informations et des conseils plus avancés sur systemd.

Il existe également une série d'articles profondément techniques pour les administrateurs système Linux par Lennart Poettering, le concepteur et développeur principal de systemd. Ces articles ont été écrits entre avril 2010 et septembre 2011, mais ils sont tout aussi pertinents aujourd'hui qu'ils l'étaient alors. Une grande partie de tout ce qui a été écrit sur systemd et son écosystème est basé sur ces articles.

  • Repenser le PID 1
  • systemd pour les administrateurs, partie I
  • systemd pour les administrateurs, partie II
  • systemd pour les administrateurs, partie III
  • systemd pour les administrateurs, partie IV
  • systemd pour les administrateurs, partie V
  • systemd pour les administrateurs, partie VI
  • systemd pour les administrateurs, partie VII
  • systemd pour les administrateurs, partie VIII
  • systemd pour les administrateurs, partie IX
  • systemd pour les administrateurs, partie X
  • systemd pour les administrateurs, partie XI

Linux
  1. Utilisation des journaux systemd pour résoudre les problèmes transitoires

  2. Gérer le démarrage à l'aide de systemd

  3. Utiliser l'outil de capture d'écran GNOME sous Linux comme un pro

  4. Utilisation de l'outil SS pour le dépannage du réseau

  5. Le service Systemd ne démarre pas Nodejs ?

Explorez les fichiers binaires à l'aide de cet outil Linux complet

Comment démarrer le service httpd dans RHEL Linux

Afficher l'utilisation de la bande passante réseau à l'aide de l'outil Bandwhich

Afficher les informations réseau sous Linux à l'aide de What IP Tool

Utiliser les fonctionnalités de systemd pour sécuriser les services

Utilisation du transfert de port SSH comme outil de sécurité sous Linux