ITSkillsCenter
Blog

Dépannage Linux méthodique : du symptôme à la cause — tutoriel pas-à-pas

14 دقائق للقراءة

📍 Article principal du programme : Linux fondamentaux 2026 — commandes, services, dépannage
Ce tutoriel fait partie du programme « Linux fondamentaux ». Pour la vue d’ensemble, lisez d’abord le guide principal.

Introduction

Le bon administrateur ne devine pas. Il observe, formule une hypothèse, teste, conclut, et documente. Ce tutoriel détaille la méthode de dépannage Linux qui fait passer un débutant qui essaie au hasard à un opérateur qui isole une cause en quinze minutes — méthode qui a fait ses preuves sur des dizaines de milliers d’incidents en production. Elle tient en cinq étapes ordonnées que vous appliquerez sans variation à chaque fois, parce que la discipline méthodologique est le meilleur antidote à la panique. Nous l’illustrerons sur un cas réaliste : un site web qui renvoie soudainement des erreurs 502 alors qu’il fonctionnait il y a une heure.

Prérequis

  • Un serveur Linux et un compte avec accès sudo (Ubuntu 24.04/26.04 LTS, Debian 13, AlmaLinux 9, Rocky Linux 9).
  • Connaissance des outils des autres tutoriels du programme : journalctl, systemctl, ss, ps, top.
  • Niveau attendu : intermédiaire.
  • Temps estimé : 90 minutes.

Étape 1 — Isoler le périmètre

Avant toute commande, posez la question : qui est touché, où, depuis quand ? Une panne « tout est cassé » se résout différemment d’une panne « seulement les utilisateurs en Europe » ou « seulement depuis le déploiement de 14 h 30 ». Cette première phase prend deux minutes et élimine la moitié des fausses pistes.

# Le serveur est-il joignable du tout ?
ping -c 4 adresse-du-serveur

# Le service répond-il en local mais pas de l'extérieur ?
ssh user@serveur
curl -I http://localhost/

# Quand l'incident a-t-il commencé ?
last reboot
last -F | head -5
journalctl --since "1 hour ago" | head -50

Quatre questions à se poser dans l’ordre. Premièrement : la panne touche-t-elle une seule URL, un seul service, une seule machine, ou tout l’environnement ? Si seul un service est touché, vous gagnez 80 % du périmètre. Deuxièmement : la panne est-elle reproductible ? Une 502 intermittente raconte une histoire différente d’une 502 systématique. Troisièmement : qu’a-t-on changé récemment ? Un déploiement, une mise à jour de paquets, un cron qui a tourné, une rotation de logs. La sortie de journalctl --since "1 hour ago" | grep -i "Started\|Stopped" liste les événements systemd des dernières heures. Quatrièmement : la panne touche-t-elle d’autres ressources que celles supposées ? Si la base de données ralentit en même temps que le site, vous avez probablement une cause système commune (disque saturé, mémoire pleine).

Étape 2 — Lire les journaux

Dans 80 % des incidents, la cause exacte est inscrite dans le journal en clair, à condition de savoir où regarder. Ne tapez pas une seule commande de modification avant d’avoir lu les logs récents — c’est l’erreur la plus coûteuse en temps et la plus tentante sous pression.

# Cas Nginx 502 : on commence par le service le plus exposé
sudo journalctl -u nginx -n 200 --no-pager

# Logs d'erreur Nginx (fichier classique)
sudo tail -100 /var/log/nginx/error.log

# Et l'application sous-jacente ?
sudo journalctl -u mon-api -n 200 --no-pager

# Système entier sur la dernière heure, niveau erreur ou plus
sudo journalctl -p err --since "1 hour ago" --no-pager

Lisez du plus récent au plus ancien, en cherchant des marqueurs : « FATAL », « ERROR », « connection refused », « out of memory », « no such file ». Une 502 Nginx avec un message « connect() failed (111: Connection refused) while connecting to upstream » dans error.log est un diagnostic complet : Nginx essaie de joindre l’application sur son socket, et l’application n’écoute pas. Reste à savoir pourquoi elle n’écoute pas — soit elle a planté, soit elle n’a jamais démarré, soit elle s’est mise à écouter ailleurs. Trois sous-questions à creuser à l’étape 4. Si rien d’évident n’apparaît, élargissez : journalctl --since "30 min ago" sans filtre, vous y verrez peut-être un événement collatéral (un OOM, un disque qui se plaint, une mise à jour automatique).

Étape 3 — Vérifier les ressources

Le second réflexe, avant de fouiller le code applicatif : vérifier que les ressources fondamentales sont saines. Une panne applicative est rarement la conséquence d’un bug introduit cinq minutes plus tôt ; elle est souvent la conséquence d’une saturation lente qui finit par tout entraîner.

df -h                                  # disque, toutes partitions
df -i                                  # inodes — saturation invisible avec df -h seul
free -h                                # mémoire utilisée / disponible
uptime                                 # charge moyenne 1/5/15 min
vmstat 1 5                             # CPU et swap en mouvement
iostat -xz 1 5                         # disque par périphérique (paquet sysstat)

Quatre seuils valent comme alarmes. Disque à plus de 90 % : Postgres, MariaDB, Nginx commencent à échouer leurs écritures, parfois silencieusement. Inodes saturés (df -i au-dessus de 95 %) : impossibilité de créer de nouveaux fichiers même si df -h dit qu’il reste de la place — typique des serveurs de mail ou de cache mal configurés. Swap actif (colonnes si/so de vmstat non nulles) : la machine paginate et s’écroule à mesure que la latence disque s’effondre. Charge supérieure au double du nombre de cœurs sur la moyenne 5 minutes : saturation CPU ou IO durable. Si l’une de ces alarmes est positive, vous avez votre cause système ; corrigez-la avant de toucher au code.

Étape 4 — Tester les couches une par une

Une fois les causes système écartées, descendez méthodiquement à travers les couches du service défaillant. Pour notre cas Nginx 502, l’enchaînement type est : Nginx fonctionne ? écoute-t-il sur le bon port ? l’application sous-jacente fonctionne ? écoute-t-elle sur le bon socket ? le pare-feu laisse-t-il passer ? la configuration est-elle valide ?

# Service Nginx vivant ?
sudo systemctl status nginx
sudo nginx -t                          # validité de la config

# Nginx écoute-t-il sur 80/443 ?
sudo ss -tlnp | grep nginx

# Application sous-jacente vivante ?
sudo systemctl status mon-api
sudo ss -tlnp | grep ':3000'

# Test de bout en bout local, en court-circuitant Nginx
curl -v http://localhost:3000/

# Pare-feu ?
sudo ufw status
sudo iptables -L -n

Cinq résultats possibles, cinq corrections possibles. Si systemctl status mon-api dit « failed », la cause de l’échec est dans journalctl -u mon-api (étape 2 bis). Si l’application tourne mais n’écoute plus sur le port attendu, sa configuration a peut-être été modifiée ou l’environnement a changé. Si l’application répond en local mais pas à travers Nginx, regardez la configuration de l’upstream Nginx — un changement de port côté application sans miseà jour de Nginx provoque exactement ce symptôme. Si le pare-feu bloque, la règle a peut-être été ajoutée par erreur ; sudo ufw status numbered liste les règles avec leur ordre. À chaque étape, validez avec une commande de test (curl, ss, systemctl status) avant de passer à la suivante.

Étape 5 — Documenter pendant et après

La discipline qui transforme un dépannage en capital opérationnel : tenir un fichier au fil de l’eau, pas après coup. Ouvrez un éditeur en parallèle de votre session SSH et notez horodatage, hypothèse, commande lancée, résultat. Cinq minutes de prise de notes pendant l’incident vous économisent une heure de reconstitution si la même panne se reproduit dans six mois.

# Incident 2026-05-04 — Nginx 502 sur production

**Heure début** : 14:32 UTC
**Heure fin** : 14:51 UTC
**Impact** : 100% des requêtes en erreur 502 pendant 19 minutes

## Chronologie
- 14:32 — alerte uptime monitor sur https://exemple.com
- 14:34 — connexion SSH au serveur, ping/curl OK
- 14:35 — `journalctl -u nginx -n 100` → "connect() failed (111)"
- 14:36 — `systemctl status mon-api` → failed (status=137)
- 14:37 — `journalctl -u mon-api -n 200` → "JavaScript heap out of memory"
- 14:38 — `journalctl -k -b | grep oom` → OOM Killer a tué le PID 1247 (mon-api)
- 14:40 — `free -h` → 50 Mo libres, swap à 90%
- 14:42 — hypothèse : fuite mémoire dans le déploiement de 13:00
- 14:45 — rollback déploiement vers commit précédent
- 14:48 — `systemctl restart mon-api` puis `restart nginx`
- 14:51 — service redevenu OK

## Cause racine
Régression mémoire introduite par la PR #4521 fusionnée à 12:55.
Fuite confirmée par profilage en pré-production.

## Actions correctives
- [x] Rollback en production (14:48)
- [ ] Fix de la fuite avant remise en production (PR #4528)
- [ ] Ajouter `MemoryMax=1G` dans mon-api.service pour borner les futurs incidents
- [ ] Ajouter une alerte sur la mémoire disponible < 100 Mo

Ce format simple — chronologie, cause racine, actions — est suffisant pour neuf incidents sur dix. Ne tombez pas dans le piège du post-mortem léché écrit après coup : la mémoire des détails opérationnels s’évapore en quelques heures. Tenez le document pendant l’intervention. Pour les organisations plus structurées, le format 5 Whys (cinq pourquoi successifs) ou RCA (Root Cause Analysis) plus formel s’applique sur ce socle. Le dossier d’incidents conservé sous Git devient en six mois la meilleure formation possible pour les nouveaux arrivants.

Étape 6 — Cas réels et schémas répétitifs

Au-delà du cas Nginx 502, certains schémas reviennent plusieurs fois par an. Les reconnaître à la première minute fait gagner des dizaines d’heures sur la durée d’une carrière. Voici les cinq plus fréquents et leur signature.

Symptôme Diagnostic rapide Cause typique
Site qui devient lent en fin de mois df -h et journalctl --disk-usage Logs jamais rotation, disque à 95 %
Erreur 502 quelques minutes après chaque déploiement journalctl -u app -n 200 Healthcheck applicatif trop strict, l’app n’a pas le temps de démarrer
Connexions SSH lentes (10-30 s) ssh -v côté client Reverse DNS échoue, ajouter UseDNS no sur le serveur
Cron silencieux qui ne s’exécute pas journalctl -u cron --since today Heure du serveur dérivée, NTP cassé, timedatectl
Service qui crashe une fois par jour à la même heure Corréler avec journalctl --since "08:00" --until "09:00" Backup ou updatedb qui sature le disque IO

Un classeur personnel de schémas-symptômes-causes-corrections est l’un des outils les plus rentables qu’un opérateur puisse construire. Au bout d’un an, vous ouvrez votre fichier, vous tapez quelques mots-clés, et vous tombez sur l’incident similaire de l’an passé avec sa résolution. Cette pratique remplace efficacement la mémoire individuelle, qui est le pire des supports de connaissance opérationnelle.

Étape 7 — Limiter le rayon d’action des actions correctives

Sous pression, la tentation est forte de « tout redémarrer pour voir ». Cette approche a deux inconvénients majeurs : elle masque la cause racine (qui se reproduira), et elle peut aggraver l’incident si une dépendance subtile dépend de l’ordre. La discipline professionnelle consiste à appliquer des corrections proportionnées et réversibles, dans l’ordre.

Premièrement, privilégier systemctl reload à systemctl restart quand le service le supporte (Nginx, sshd, postfix, certains démons applicatifs). Le reload ne coupe pas les connexions en cours et n’a presque jamais d’effet de bord. Deuxièmement, redémarrer un service à la fois, observer le journal pendant trente secondes, puis seulement passer au suivant. Trois services redémarrés en parallèle qui partagent une dépendance peuvent boucler. Troisièmement, garder une voie de rollback explicite : si vous modifiez un fichier de configuration, créez une copie horodatée (cp file.conf file.conf.bak.20260504-1432) avant la modification, et notez la commande de rollback en commentaire dans votre journal d’incident. Quatrièmement, éviter le redémarrage du serveur entier sauf en dernier recours absolu : un reboot peut révéler des fichiers non persistants, des montages cassés, des règles de pare-feu non sauvegardées, qui transformeront un incident d’une heure en panne d’un jour.

Étape 8 — Vérification finale

Après chaque dépannage, validez explicitement que le service est revenu à son état nominal avant de fermer la session. Un service qui paraît OK à 14:51 mais qui se remet à crasher à 14:53 est un dépannage raté. La séquence canonique de validation tient en cinq commandes.

systemctl status nginx mon-api          # actif et stable depuis quelques minutes
journalctl -u nginx -u mon-api --since "5 min ago" -p err   # aucune erreur récente
curl -I https://exemple.com              # 200 attendu
curl -s -o /dev/null -w "%{time_total}s\n" https://exemple.com   # latence raisonnable
df -h && free -h                         # ressources saines

Si toutes ces commandes retournent un état sain, fermez l’incident, mettez à jour votre journal, et envoyez la note finale aux parties prenantes. Si l’une échoue ou montre un signal faible, restez sur le pont quinze minutes de plus — la rechute est plus courante qu’on ne le pense, et c’est précisément là que la discipline d’observation paie. Cette dernière étape, souvent négligée par les juniors, est ce qui transforme un dépannage moyen en dépannage de qualité.

Erreurs fréquentes

Erreur Cause Solution
« Tout redémarrer » à l’aveugle Panique, manque de méthode Imposer la lecture des logs avant toute commande de modification
Diagnostic interrompu par un coéquipier Communication parallèle non gérée Annoncer « je suis dans journalctl, je donne un point dans 5 min »
Cause racine confondue avec symptôme Arrêt du diagnostic à la première trouvaille Demander 3 fois « pourquoi ? », jusqu’à une cause actionnable
Modification non documentée Pression, oubli Tenir le journal d’incident en parallèle de la session SSH
Vérification finale oubliée Soulagement prématuré Exécuter la séquence de l’étape 8 avant de fermer la session

Tutoriels associés

Dans la continuité

FAQ

Combien de temps consacrer au diagnostic avant d’appeler un coéquipier ?
La règle pratique : quinze à trente minutes seul, puis demander de l’aide. Au-delà, la fatigue cognitive entraîne des erreurs et la perspective fraîche d’un binôme accélère la résolution. Pour les incidents critiques avec impact utilisateur, ne pas attendre — un binôme dès la troisième minute partage la pression et double la probabilité de voir l’indice clé dans les logs.

Faut-il documenter même les petits incidents ?
Oui, surtout eux. Les gros incidents font toujours l’objet d’un post-mortem ; ce sont les petits qui s’oublient et reviennent. Cinq lignes dans un fichier incidents.md avec date, symptôme, cause, correction sont suffisantes — l’important est l’exhaustivité, pas le formalisme. Au bout de six mois, la recherche dans ce fichier devient l’outil le plus rapide de votre boîte à outils.

Comment se former au dépannage sans casser la production ?
Trois pratiques. Premièrement, lire les post-mortems publics des grandes infrastructures (Cloudflare, GitHub, Vercel, Discord publient régulièrement) — c’est la classe de maître la plus accessible qui existe. Deuxièmement, faire des game days sur un environnement de test : un coéquipier introduit volontairement une panne, vous la diagnostiquez sous chronomètre. Troisièmement, prendre des notes sur tous les incidents que vous résolvez, même par hasard ; en trois mois, vous aurez votre catalogue personnel.

Quels signaux faibles surveiller pour anticiper les incidents ?
Quatre métriques valent leur poids : la croissance du disque (un disque qui grossit linéairement et sera plein dans X jours), la latence p99 d’une API (un doublement progressif annonce un goulet à venir), le taux d’erreur 5xx (une dérive lente est plus alarmante qu’un pic isolé), et la charge moyenne 15 minutes en heure de pointe (sa courbe sur six mois révèle si la machine vit ses derniers mois). Un tableau de bord simple avec ces quatre courbes vous fait passer du dépannage réactif à l’anticipation.

Comment gérer un incident pendant les heures non ouvrées ?
Trois principes. Premièrement, savoir si l’incident exige une intervention immédiate : la perte de chiffre d’affaires ou de données justifie d’être tiré du lit, le ralentissement d’un outil interne attend le matin. Deuxièmement, avoir un runbook à jour qui permet à un opérateur de garde, même peu familier du système, de poser les bons gestes (redémarrer un service, escalader, communiquer aux utilisateurs). Troisièmement, après chaque réveil nocturne, demander : pourquoi cet incident n’a-t-il pas été évité, et comment éviter sa répétition ?

Quand abandonner et appeler le support de l’hébergeur ?
Quand vos commandes côté serveur ne révèlent rien d’anormal mais que la connectivité ou les performances sont dégradées. Un MTR qui montre une perte de paquets sur les premiers sauts (ceux du datacenter), des E/S disque anormalement lentes sans charge applicative, ou une latence vers les autres serveurs du même hébergeur sont des signaux d’incident côté infrastructure. Ouvrir un ticket avec les mesures précises (timestamps, traceroute, iperf3) accélère considérablement la résolution chez le support.

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité