Dépannage des services Linux avec systemctl et journalctl
Un workflow pratique pour déboguer les services Linux défaillants ou malsains avec systemctl et journalctl.
Dépannage des services Linux avec systemctl et journalctl
Lorsqu'un service Linux échoue, le chemin le plus rapide n'est généralement pas une recherche sur le web. Il s'agit de trois vérifications locales : ce que systemd pense qu'il s'est passé, ce que le service a enregistré, et ce qui a changé avant la panne. systemctl et journalctl vous donnent ces réponses sans avoir à deviner.
Ce guide utilise des pannes de service courantes comme exemples : un service qui ne démarre pas, un processus qui tourne mais n'effectue pas de travail utile, et un service qui se termine après avoir semblé sain. Les commandes s'appliquent à la plupart des services gérés par systemd, mais les noms d'unités exacts et les emplacements des journaux varient selon la distribution et le paquet.
Comprendre systemctl et journalctl
Avant de plonger dans le dépannage, il est crucial de comprendre les rôles de ces deux outils principaux :
systemctl: Cette commande est l'utilitaire central pour contrôler et interroger le gestionnaire de système et de servicessystemd. Elle permet de démarrer, arrêter, redémarrer, vérifier l'état et activer/désactiver les services.journalctl: Cette commande est utilisée pour interroger le journal systemd, qui est un système de journalisation centralisé. Il collecte les journaux du noyau, des services système et des applications, fournissant une vue unifiée des événements système.journalctlest inestimable pour comprendre pourquoi un service a échoué ou s'est comporté de manière inattendue.
Scénarios de dépannage courants et solutions
Explorons les problèmes typiques et comment les résoudre :
1. Le service n'a pas réussi à démarrer
C'est peut-être le problème le plus courant. Vous essayez de démarrer un service, et il échoue immédiatement.
Étape 1 : Vérifier l'état du service
Utilisez systemctl status pour obtenir un aperçu immédiat de l'état du service et des entrées de journal récentes.
sudo systemctl status apache2.service
Sortie attendue (illustrative - la vôtre peut varier) :
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: **failed** (result: exit-code) since Tue 2023-10-27 10:00:00 UTC; 1min ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 12345 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)
Main PID: 12345 (code=exited, status=1/FAILURE)
Oct 27 10:00:00 your-server systemd[1]: Starting The Apache HTTP Server...
Oct 27 10:00:00 your-server apachectl[12345]: AH00526: Syntax error on line 123 of /etc/apache2/apache2.conf:
Oct 27 10:00:00 your-server apachectl[12345]: Invalid Mutex directory in argument file: '/var/run/apache2/'
Oct 27 10:00:00 your-server systemd[1]: apache2.service: Main process exited, code=exited, status=1/FAILURE
Oct 27 10:00:00 your-server systemd[1]: **Failed** to start The Apache HTTP Server.
Oct 27 10:00:00 your-server systemd[1]: apache2.service: Unit entered failed state.
Analyse : La sortie de systemctl status montre clairement Active: failed et fournit un extrait du message d'erreur : Invalid Mutex directory in argument file: '/var/run/apache2/'. Cela suggère un problème de configuration.
Étape 2 : Enquêter sur les journaux avec journalctl
Pour des informations plus détaillées, utilisez journalctl pour afficher les journaux spécifiques au service défaillant. Le drapeau -u spécifie l'unité (service).
sudo journalctl -u apache2.service -xe
-u apache2.service: Filtre les journaux pour l'unitéapache2.service.-x: Ajoute des explications pour certains messages de journal.-e: Saute à la fin du journal, montrant les entrées les plus récentes.
Résultats potentiels : La sortie de journalctl pourrait révéler plus de contexte sur l'erreur de configuration, les problèmes de permissions ou les problèmes de dépendances.
Étape 3 : Vérifier les fichiers de configuration
Sur la base du message d'erreur, examinez les fichiers de configuration pertinents. Dans l'exemple ci-dessus, il pointe vers /etc/apache2/apache2.conf et le répertoire /var/run/apache2/.
sudo nano /etc/apache2/apache2.conf
Solution : Les problèmes comme celui-ci proviennent souvent d'un répertoire d'exécution manquant, d'un changement de paquetage ou d'un fichier de configuration qui fait référence à un chemin qui n'existe plus. Ne créez pas aveuglément des répertoires à partir d'un exemple sur Internet. Confirmez d'abord ce que l'application attend sur votre distribution, puis corrigez le chemin manquant ou la configuration. Une réparation possible pourrait ressembler à ceci :
sudo mkdir -p /var/run/apache2/
sudo chown www-data:www-data /var/run/apache2/
sudo systemctl start apache2.service
Si l'erreur mentionne un problème de syntaxe, exécutez le propre test de configuration de l'application avant de redémarrer à nouveau :
sudo apachectl configtest
sudo nginx -t
sudo sshd -t
Les validateurs spécifiques à l'application détectent les erreurs que systemd ne peut pas comprendre. Systemd sait si le processus s'est terminé. Il ne sait pas si votre bloc server Nginx pointe vers le mauvais fichier de certificat ou si une directive Apache appartient à un contexte différent.
2. Le service est en cours d'exécution mais ne répond pas
Parfois, systemctl status montre un service comme active (running), mais il ne remplit pas sa fonction prévue (par exemple, un serveur web ne sert pas de pages).
Étape 1 : Vérifier l'état du service et le PID
Confirmez qu'il est réellement en cours d'exécution et qu'il a un ID de processus (PID).
sudo systemctl status nginx.service
S'il affiche active (running), notez le PID.
Étape 2 : Examiner les journaux de service pour les erreurs
Même en cours d'exécution, le service peut rencontrer des erreurs internes qui l'empêchent de fonctionner correctement.
sudo journalctl -u nginx.service -f
-f: Suit la sortie du journal en temps réel. Ceci est utile si vous pouvez déclencher le problème (par exemple, essayez d'accéder à la page web) pendant quejournalctlest en cours d'exécution.
Étape 3 : Vérifier les journaux spécifiques à l'application
De nombreux services écrivent leurs propres journaux en plus du journal de systemd. Pour les serveurs web comme Nginx ou Apache, vérifiez leurs emplacements de journaux typiques (par exemple, /var/log/nginx/error.log, /var/log/apache2/error.log).
sudo tail -n 50 /var/log/nginx/error.log
Étape 4 : Vérifier l'utilisation des ressources
Un système surchargé peut rendre les services non réactifs.
top
htop
free -h
Recherchez une utilisation élevée du CPU, de la mémoire ou des E/S disque par les processus du service.
Vérifiez également si le service écoute là où vous vous y attendez :
sudo ss -ltnp
sudo ss -lunp
Pour un service web, voir nginx actif dans systemctl n'est que la moitié de l'histoire. Vous devez encore savoir s'il est lié à 0.0.0.0:80, 127.0.0.1:8080, un socket IPv6, ou aucun socket du tout. Une règle de pare-feu, une inadéquation de proxy inverse ou une mauvaise adresse de liaison peuvent rendre un processus sain cassé de l'extérieur.
Solution : Si les journaux indiquent des problèmes ou si les ressources sont tendues, vous pourriez avoir besoin de :
- Optimiser les configurations.
- Redémarrer le service (
sudo systemctl restart <nom_du_service>.service). - Enquêter sur les problèmes de ressources système sous-jacents.
- Augmenter les ressources système si nécessaire.
3. Le service s'arrête de manière inattendue
Si un service qui fonctionnait auparavant s'arrête soudainement, c'est souvent dû à une exception non gérée ou à un délai d'attente de watchdog.
Étape 1 : Vérifier l'historique récent avec journalctl
Utilisez journalctl pour voir ce qui s'est passé juste avant l'arrêt du service. Les drapeaux --since et --until peuvent être utiles si vous connaissez l'heure approximative.
sudo journalctl -u <nom_du_service>.service --since "1 hour ago"
Ou, pour voir tous les journaux liés au service depuis le dernier démarrage :
sudo journalctl -u <nom_du_service>.service -b
Étape 2 : Rechercher les vidages mémoire ou les rapports de crash
Si le service a planté, le système peut avoir généré un vidage mémoire ou un rapport de crash.
ls -l /var/crash/
Étape 3 : Examiner le fichier d'unité de service systemd
Examinez le fichier d'unité du service (généralement dans /etc/systemd/system/ ou /lib/systemd/system/) pour les directives Restart= et les paramètres WatchdogSec=. Une configuration Restart= incorrecte ou un WatchdogSec= trop court pourrait provoquer des redémarrages ou des échecs inattendus.
systemctl cat <nom_du_service>.service
Solution : Traitez la cause racine identifiée dans les journaux. Cela peut impliquer la correction de bogues de code, l'ajustement des paramètres du fichier d'unité systemd ou l'augmentation des limites de ressources.
Si vous voyez des redémarrages répétés, vérifiez si systemd a limité le débit de l'unité :
systemctl status <nom_du_service>.service
journalctl -u <nom_du_service>.service --since "30 minutes ago"
Les messages concernant Start request repeated too quickly signifient généralement que le service a planté plusieurs fois dans une courte fenêtre. Après avoir corrigé le problème sous-jacent, effacez l'état d'échec :
sudo systemctl reset-failed <nom_du_service>.service
sudo systemctl start <nom_du_service>.service
4. Problèmes avec systemctl enable ou systemctl disable
Bien qu'il ne s'agisse pas d'une panne au moment de l'exécution, des problèmes d'activation ou de désactivation des services peuvent survenir.
Problème : Un service est activé mais ne démarre pas au démarrage, ou vice versa.
Vérifier l'état :
sudo systemctl is-enabled <nom_du_service>.service
Cette commande affichera enabled ou disabled.
Dépannage :
- Assurez-vous que le fichier d'unité de service lui-même est valide et placé correctement (par exemple,
/etc/systemd/system/). - Après avoir apporté des modifications à un fichier d'unité, exécutez toujours
sudo systemctl daemon-reload. - Vérifiez les journaux du service (
journalctl -u <nom_du_service>.service) pour toute erreur de démarrage qui pourrait l'empêcher de devenir actif même s'il est activé.
Conseils pour un dépannage efficace
- Commencez par
systemctl status: Commencez toujours ici. Il fournit un aperçu rapide et vous oriente souvent dans la bonne direction. - Utilisez
journalctl -u <service>: C'est votre outil principal pour comprendre pourquoi quelque chose se produit. - Drapeau
-favecjournalctl: Extrêmement utile pour la surveillance en temps réel lorsque vous essayez de reproduire un problème. systemctl restart <service>: Après avoir apporté des modifications de configuration, redémarrez toujours le service pour les appliquer.systemctl daemon-reload: Crucial après avoir modifié des fichiers d'unité.service.- Vérifier les dépendances : Parfois, un service échoue parce qu'un service dont il dépend n'a pas démarré ou est lui-même défaillant.
systemctl statusle montrera souvent. - Permissions : De nombreuses pannes de service sont dues à des permissions incorrectes sur les fichiers ou répertoires. Assurez-vous que l'utilisateur sous lequel le service s'exécute dispose de l'accès nécessaire.
- Problèmes réseau : Si le service dépend du réseau, vérifiez la connectivité réseau, les règles de pare-feu et la disponibilité des ports.
Un ordre de dépannage qui tient la route
Quand la pression est là, utilisez le même ordre à chaque fois :
systemctl status <service>.service
journalctl -u <service>.service -b --no-pager
systemctl cat <service>.service
systemctl list-dependencies <service>.service
Commencez par l'état actuel, puis lisez les journaux du démarrage en cours, puis inspectez l'unité exactement comme systemd la voit, puis vérifiez les dépendances. Si le service est orienté réseau, ajoutez ss -ltnp et un test curl ou client local. S'il lit un fichier de configuration, exécutez le validateur de configuration du service lui-même.
Le but est d'éviter les redémarrages aléatoires. Le redémarrage peut être une correction valide après un changement de configuration ou un processus bloqué, mais il détruit également les preuves. Lisez suffisamment le journal d'abord pour savoir ce que vous modifiez et pourquoi.
Lire la sortie du journal sans se perdre
journalctl peut être bruyant, en particulier sur les serveurs occupés. Commencez par une recherche étroite, puis élargissez uniquement lorsque vous en avez besoin.
Pour un service dans le démarrage en cours :
journalctl -u <service>.service -b --no-pager
Pour les dernières minutes :
journalctl -u <service>.service --since "15 minutes ago" --no-pager
Pour le démarrage précédent :
journalctl -u <service>.service -b -1 --no-pager
Cette vue du démarrage précédent est utile lorsqu'un service a échoué pendant le démarrage puis a récupéré, ou lorsque la machine entière a redémarré avant que vous puissiez l'inspecter. Vous pouvez lister les démarrages avec :
journalctl --list-boots
Si le service enregistre des champs structurés ou de longues lignes, utilisez des horodatages ISO courts :
journalctl -u <service>.service -o short-iso --no-pager
Lorsque vous devez partager des journaux, supprimez les secrets, les jetons, les noms d'hôte internes et les données client. Les journaux de service incluent souvent des paramètres dérivés de l'environnement, des URL, des en-têtes ou des chaînes de connexion. Une habitude de dépannage propre inclut la rédaction avant de coller la sortie n'importe où.
Quand systemctl dit "Active" mais que les utilisateurs voient toujours un échec
Un état active (running) signifie seulement que systemd a un processus qui correspond aux attentes de l'unité. Cela ne prouve pas que l'application est saine. Une application web peut être en cours d'exécution tout en renvoyant une erreur HTTP 500. Un worker peut être actif tout en étant bloqué sur un mauvais message de file d'attente. Un proxy de base de données peut être en cours d'exécution alors que toutes les connexions backend échouent.
Pour les services réseau, testez à partir des mêmes couches dont dépendent vos utilisateurs :
curl -v http://127.0.0.1:8080/health
curl -v http://localhost/health
curl -v https://service.example.com/health
Ces trois vérifications répondent à des questions différentes. La première vérifie le port de l'application locale. La seconde peut inclure un proxy inverse local. La troisième vérifie le DNS, TLS, le routage, les règles de pare-feu et le chemin public.
Pour les services de type worker, regardez ce qu'ils consomment ou produisent. Un worker de file d'attente peut nécessiter une vérification de la profondeur de la file d'attente. Un service de sauvegarde peut nécessiter un fichier de sortie récent. Un collecteur de métriques peut nécessiter une requête auprès du backend de métriques. systemctl vous indique si la supervision fonctionne ; les vérifications d'application vous indiquent si le service est utile.
Corriger une variable à la fois
Lorsqu'une unité échoue après un déploiement, il est tentant de modifier plusieurs choses et de redémarrer. Cela peut cacher la véritable cause. Préférez un changement à la fois :
systemctl cat my-app.service
journalctl -u my-app.service --since "30 minutes ago" --no-pager
sudo systemctl edit my-app.service
sudo systemctl daemon-reload
sudo systemctl restart my-app.service
Ensuite, vérifiez le résultat avant de modifier la chose suivante. Si l'échec est un fichier manquant, corrigez le chemin du fichier. S'il s'agit d'une erreur de permission, corrigez la propriété ou le mode. S'il s'agit d'une dépendance, corrigez la relation d'unité ou le comportement de nouvelle tentative de l'application. Un dépannage lent et ennuyeux est souvent plus rapide qu'une boucle de redémarrage avec cinq modifications non suivies.