Dépannage de l'épuisement des ressources Linux : CPU, mémoire et espace disque

Dépanner l'épuisement du CPU, de la mémoire et du disque sous Linux avec des commandes pratiques, des étapes de nettoyage sécurisées et des vérifications des causes racines.

Dépannage de l'épuisement des ressources Linux : CPU, mémoire et espace disque

Lorsqu'un serveur Linux manque de CPU, de mémoire ou d'espace disque, le premier symptôme est généralement vague : le site est lent, SSH se bloque après la connexion, les déploiements échouent ou un service redémarre sans cesse. Le moyen le plus rapide de gérer l'incident est d'identifier quelle ressource est épuisée, puis de trouver le processus ou le système de fichiers responsable.

Effectuez d'abord les vérifications les moins risquées. Les commandes en lecture seule telles que top, free, df, du, vmstat et journalctl vous donnent une image sans modifier la machine. Tuer des processus et supprimer des fichiers peut être nécessaire, mais cela ne constitue pas un diagnostic.

Identifier le coupable : Surveillance des ressources système

Avant de pouvoir résoudre un problème d'épuisement des ressources, vous devez identifier quelle ressource est surutilisée et quel processus en est responsable. Linux fournit un ensemble riche d'outils en ligne de commande à cet effet.

Surveillance de l'utilisation du CPU

Une utilisation élevée du CPU peut rendre votre système lent et non réactif. Elle est souvent causée par un processus incontrôlé, une application exigeante ou un script inefficace.

  • top : C'est un moniteur système en temps réel indispensable. Il affiche une liste dynamique des processus, triés par défaut par utilisation du CPU. Vous pouvez voir l'utilisation globale du CPU, l'utilisation de la mémoire et les détails de chaque processus.

    top
    

    Dans top, appuyez sur 1 pour voir l'utilisation de chaque cœur de CPU. Appuyez sur P pour trier par utilisation du CPU. Recherchez les processus qui consomment constamment un pourcentage élevé de CPU.

  • htop : Une version améliorée et interactive de top. Il est souvent préféré pour sa convivialité, sa sortie colorée et sa navigation plus facile.

    htop
    

    Similaire à top, htop permet de trier par utilisation du CPU et fournit des informations détaillées sur les processus.

  • mpstat : Faisant partie du paquet sysstat, mpstat fournit des statistiques détaillées du CPU, y compris l'utilisation par processeur, le nombre d'interruptions et les changements de contexte.

    mpstat -P ALL 1
    

    Cette commande affiche les statistiques du CPU pour tous les cœurs chaque seconde.

Vérifiez également la charge moyenne par rapport au nombre de CPU :

uptime
nproc

Une charge moyenne de 8 signifie quelque chose de très différent sur une VM à 2 cœurs que sur un hôte à 32 cœurs. La charge inclut également les tâches en attente d'E/S non interruptibles, donc une charge moyenne élevée avec une faible utilisation du CPU peut en fait indiquer un problème de disque ou de stockage réseau.

Surveillance de l'utilisation de la mémoire

Lorsqu'un système manque de RAM et d'espace d'échange disponibles, il commence à utiliser l'espace disque comme mémoire virtuelle, ce qui est considérablement plus lent, entraînant une dégradation sévère des performances.

  • free -h : Affiche la quantité totale de mémoire physique et d'échange libre et utilisée dans le système, ainsi que les tampons et caches utilisés par le noyau. L'option -h rend la sortie lisible par l'homme (par exemple, Mo, Go).

    free -h
    

    Faites attention à la mémoire available et à l'espace d'échange used. Une utilisation élevée de l'échange indique une RAM insuffisante.

  • top / htop : top et htop affichent tous deux l'utilisation de la mémoire par processus. Recherchez les processus avec une valeur élevée de %MEM.

  • vmstat : Rapporte les statistiques de mémoire virtuelle. Il peut afficher des informations sur les processus, la mémoire, la pagination, les E/S bloc, les interruptions et l'activité du CPU.

    vmstat 5
    

    Cette commande rapporte les statistiques toutes les 5 secondes. Regardez les colonnes si (swap-in) et so (swap-out) ; des valeurs élevées indiquent une permutation mémoire importante.

Pour les éventuels kills OOM, vérifiez le journal du noyau :

dmesg -T | grep -i 'killed process'
journalctl -k --since "1 hour ago" | grep -i oom

Un kill OOM change l'incident. La question immédiate devient quel processus a été tué, pourquoi il a dépassé la mémoire disponible et si systemd ou un orchestrateur l'a redémarré.

Surveillance de l'espace disque

Une partition disque pleine peut empêcher les applications d'écrire des données, provoquer des erreurs et même empêcher le système de démarrer.

  • df -h : Rapporte l'utilisation de l'espace disque du système de fichiers. L'option -h rend la sortie lisible par l'homme.

    df -h
    

    Cette commande liste tous les systèmes de fichiers montés et affiche leur taille totale, l'espace utilisé, l'espace disponible et le point de montage. Recherchez les partitions à ou près de 100% d'utilisation.

  • du -sh <directory> : Estime l'utilisation de l'espace fichier pour un répertoire donné. L'option -s résume, et -h le rend lisible par l'homme.

    du -sh /var/log/*
    

    Utilisez ceci pour trouver quels sous-répertoires consomment le plus d'espace disque.

Vérifiez également l'utilisation des inodes :

df -ih

Un système de fichiers peut avoir des gigaoctets libres et être toujours incapable de créer des fichiers s'il a épuisé les inodes. Cela se produit avec des millions de petits fichiers : entrées de cache, files d'attente de courrier, fichiers de session, artefacts de construction ou journaux mal rotés.

Résoudre les problèmes d'épuisement des ressources

Une fois que vous avez identifié la ressource problématique et le processus incriminé, vous pouvez prendre des mesures pour résoudre le problème.

Gérer une utilisation élevée du CPU

  1. Identifier le processus : Utilisez top ou htop pour trouver l'ID du processus (PID) consommant beaucoup de CPU.
  2. Enquêter sur le processus : Déterminez ce qu'est le processus. Est-ce une application utilisateur, un service système ou quelque chose d'inattendu ?
    • Utilisation légitime élevée : Si une application légitime utilise beaucoup de CPU (par exemple, compilation de logiciels, encodage vidéo), vous devrez peut-être attendre qu'elle se termine, la planifier en dehors des heures de pointe ou mettre à niveau votre matériel.
    • Processus incontrôlé : Si un processus est bloqué dans une boucle ou consomme excessivement du CPU involontairement, vous pouvez essayer de le redémarrer. Si cela ne fonctionne pas, vous devrez peut-être le terminer.
  3. Terminer le processus (À utiliser avec précaution !) : Vous pouvez utiliser la commande kill pour envoyer des signaux aux processus. Les signaux les plus courants sont :
    • SIGTERM (15) : Demande gracieusement au processus de se terminer.
    • SIGKILL (9) : Termine le processus de force immédiatement. Cela devrait être un dernier recours car cela ne permet pas au processus de se nettoyer.
    # Terminer gracieusement le processus avec le PID 1234
    kill 1234
    
    # Terminer de force le processus avec le PID 1234
    kill -9 1234
    
  4. Vérifier les journaux : Examinez les journaux système (par exemple, /var/log/syslog, /var/log/messages, les journaux spécifiques à l'application) pour les erreurs liées au processus problématique.
  5. Optimiser les applications/scripts : Si l'utilisation élevée du CPU est due à une application ou un script inefficace, envisagez d'optimiser le code ou la configuration.

Un CPU élevé n'est pas toujours mauvais. Un travail par lots utilisant tous les cœurs pendant une courte période peut être acceptable. Un processus monothread bloqué à 100% d'un cœur tandis que les requêtes s'accumulent derrière lui est différent. Regardez la durée, l'impact sur l'utilisateur et si le processus est censé être occupé.

Si vous avez besoin de plus de contexte avant de redémarrer un service, capturez un instantané :

ps -fp <pid>
sudo lsof -p <pid> | head
sudo strace -p <pid> -tt -T -f

Utilisez strace avec précaution sur les systèmes de production. Il peut ajouter une surcharge, mais un court échantillon vous dit souvent si le processus boucle, attend des fichiers, échoue des appels réseau ou ouvre à plusieurs reprises la même ressource.

Résoudre les fuites de mémoire et l'épuisement

Une fuite de mémoire se produit lorsqu'un programme ne libère pas la mémoire dont il n'a plus besoin, consommant progressivement toute la RAM disponible. Cela peut entraîner une permutation excessive et une absence de réponse du système.

  1. Identifier le processus : Utilisez top ou htop pour trouver les processus avec une mémoire élevée (%MEM) ou une taille de jeu résident (RSS) qui augmente régulièrement au fil du temps.
  2. Enquêter sur le processus : Déterminez la nature de l'application. Est-ce une application connue avec des problèmes de mémoire potentiels, ou quelque chose de personnalisé ?
  3. Redémarrer l'application/le service : Souvent, le simple fait de redémarrer l'application ou le service peut résoudre temporairement une fuite de mémoire en libérant la mémoire accumulée.
    # Exemple : Redémarrer le serveur web Apache
    sudo systemctl restart apache2
    
  4. Vérifier la surveillance spécifique à l'application : De nombreuses applications (par exemple, serveurs web, bases de données) ont leurs propres outils de surveillance ou journaux qui peuvent aider à diagnostiquer les problèmes de mémoire.
  5. Analyser les vidages mémoire : Pour les applications critiques, vous devrez peut-être activer les vidages mémoire et utiliser des outils de débogage (comme gdb) pour analyser l'état de la mémoire lorsque la fuite se produit. C'est une étape de dépannage avancée.
  6. Augmenter l'espace d'échange (Mesure temporaire) : Si vous ne pouvez pas résoudre immédiatement la fuite, vous pouvez augmenter l'espace d'échange pour fournir plus de mémoire virtuelle. Cependant, c'est une solution de contournement, pas une solution.
  7. Mise à niveau matérielle : Si votre système manque constamment de mémoire pour sa charge de travail, vous devrez peut-être ajouter plus de RAM physique.

Une meilleure enquête sur la mémoire observe le changement au fil du temps. Une seule capture d'écran de top ne dit que qui est gros maintenant. Une fuite est une tendance.

while true; do
  date
  ps -eo pid,comm,rss,%mem --sort=-rss | head -15
  sleep 60
done

Si le même processus grimpe régulièrement d'un échantillon à l'autre sans baisser après une baisse de trafic, vous avez un signal de fuite plus fort. Si de nombreux processus croissent ensemble pendant un trafic de pointe, la charge de travail peut simplement dépasser la capacité ou les limites de concurrence.

Pour les services systemd, vérifiez si des limites de mémoire existent déjà :

systemctl show <service> -p MemoryCurrent -p MemoryMax

Pour les conteneurs, free -h au niveau de l'hôte peut sembler correct tandis qu'un conteneur atteint sa propre limite. Vérifiez docker stats, kubectl top pod, ou les événements de l'orchestrateur pour les kills OOM.

Gérer les partitions disque pleines

Lorsqu'une partition disque se remplit, cela peut provoquer diverses défaillances système. Une action immédiate est généralement requise.

  1. Identifier la partition pleine : Utilisez df -h pour localiser la ou les partitions à 100% de capacité.
  2. Trouver les gros fichiers/répertoires : Utilisez du -sh ou du -h --max-depth=1 <directory> pour naviguer dans l'arborescence des répertoires et trouver ce qui consomme de l'espace.
    # Trouver les plus grands répertoires dans la partition racine
    sudo du -h --max-depth=1 / | sort -rh
    
    Les coupables courants incluent les fichiers journaux (/var/log), les fichiers temporaires (/tmp), les caches de paquets et les données utilisateur.
  3. Nettoyer les fichiers journaux : Les fichiers journaux peuvent devenir très volumineux. Vous pouvez souvent supprimer en toute sécurité les anciens journaux, ou configurer la rotation des journaux (logrotate) pour gérer automatiquement leur taille.
    • Supprimer les anciens journaux : Soyez prudent et assurez-vous de ne pas supprimer les journaux actifs. Vous pouvez utiliser find pour supprimer les fichiers plus anciens qu'un certain nombre de jours.
      # Supprimer les fichiers .log plus anciens que 30 jours dans /var/log/myapp
      sudo find /var/log/myapp -name "*.log" -type f -mtime +30 -delete
      
    • Rotation des journaux : Assurez-vous que logrotate est correctement configuré pour vos services. Il s'exécute généralement quotidiennement et gère l'archivage et la suppression des anciens journaux.
  4. Vider le cache du gestionnaire de paquets : Les gestionnaires de paquets conservent souvent les fichiers de paquets téléchargés. Les effacer peut libérer un espace significatif.
    • Debian/Ubuntu (apt) :
      sudo apt autoremove
      sudo apt clean
      
    • CentOS/RHEL/Fedora (yum/dnf) :
      sudo yum autoremove  # ou dnf autoremove
      sudo yum clean all   # ou dnf clean all
      
  5. Supprimer les paquets inutilisés : Désinstallez les logiciels dont vous n'avez plus besoin.
    • Debian/Ubuntu : sudo apt remove <package_name>
    • CentOS/RHEL/Fedora : sudo yum remove <package_name> ou sudo dnf remove <package_name>
  6. Vérifier les répertoires temporaires : Les fichiers dans /tmp sont souvent sûrs à supprimer, surtout après un redémarrage, mais soyez prudent si des applications les utilisent activement.
  7. Vider la corbeille : Si vous utilisez un environnement de bureau, vérifiez les corbeilles des utilisateurs.
  8. Envisager le redimensionnement des partitions : Si l'espace est constamment un problème et que le nettoyage ne suffit pas, vous devrez peut-être redimensionner les partitions ou ajouter plus de stockage. C'est une opération plus avancée qui peut nécessiter de démonter les partitions ou de démarrer à partir d'un environnement live.

Soyez prudent avec les fichiers supprimés qui sont encore ouverts. df peut montrer un système de fichiers plein même après avoir supprimé un gros fichier journal, car un processus en cours a toujours le descripteur de fichier ouvert.

sudo lsof +L1

Si un fichier supprimé est toujours maintenu ouvert, le redémarrage ou le rechargement du service propriétaire libère l'espace. Faites-le intentionnellement ; ne redémarrez pas une base de données ou un service critique au milieu d'un incident sans comprendre l'impact.

Pour les journaux de journal, préférez le nettoyage journalctl à la suppression manuelle de fichiers :

journalctl --disk-usage
sudo journalctl --vacuum-time=14d

Pour les hôtes Docker, vérifiez les journaux des conteneurs et les images inutilisées :

docker system df
docker ps --size

N'exécutez pas de commandes de nettoyage larges à l'aveugle sur un hôte de production. Elles peuvent supprimer des images, le cache de construction, les conteneurs arrêtés et les réseaux que quelqu'un s'attendait à conserver.

Un ordre de triage qui fonctionne sous pression

Quand tout est lent, utilisez un ordre fixe pour ne pas sauter entre les théories.

  1. Confirmez que l'hôte est joignable et non en lecture seule :

    uptime
    date
    mount | grep ' ro,'
    
  2. Vérifiez le CPU et la charge :

    top
    uptime
    
  3. Vérifiez la mémoire et l'échange :

    free -h
    vmstat 1 5
    
  4. Vérifiez l'espace disque et les inodes :

    df -h
    df -ih
    
  5. Vérifiez les erreurs récentes du noyau et des services :

    journalctl -p warning..alert --since "30 minutes ago"
    journalctl -k --since "30 minutes ago"
    

Cet ordre attrape rapidement les défaillances courantes : saturation du CPU, tempêtes d'échange, systèmes de fichiers pleins, épuisement des inodes, kills OOM et erreurs de stockage.

Choisir la solution immédiate la moins mauvaise

Lors d'une panne, vous aurez peut-être besoin d'une solution à court terme avant que la solution permanente ne soit prête.

Pour l'épuisement du CPU, un redémarrage gracieux du service peut être plus sûr que kill -9, surtout pour les logiciels qui écrivent de l'état. Si un travail en arrière-plan affame le trafic utilisateur, réduisez sa priorité :

sudo renice +10 -p <pid>
sudo ionice -c2 -n7 -p <pid>

Pour l'épuisement de la mémoire, réduire la concurrence est souvent plus sûr que d'ajouter de l'échange et d'espérer. Réduisez le nombre de workers web, mettez en pause les travaux par lots ou désactivez temporairement les fonctionnalités coûteuses. L'échange peut faire gagner du temps, mais un échange important transforme généralement une défaillance claire en une défaillance lente.

Pour l'épuisement du disque, supprimez ou faites pivoter les fichiers que vous comprenez. Les bons candidats sont les anciens journaux compressés, les caches de paquets, les artefacts de construction obsolètes et les fichiers temporaires des travaux arrêtés. Les mauvais candidats sont les fichiers de base de données, les journaux actifs, les fichiers inconnus sous les répertoires de données d'application et tout ce que vous ne pouvez pas expliquer.

Notes sur la cause racine à capturer

Après que le système est stable, notez ce qui a changé. Les notes utiles sont concrètes :

  • Le système de fichiers ou la ressource exacte qui a été épuisé.
  • Le processus, l'utilisateur, le service, le conteneur ou le travail cron impliqué.
  • La sortie de commande qui l'a prouvé.
  • L'action immédiate entreprise.
  • Le correctif permanent nécessaire.

Ce n'est pas de la paperasse pour le plaisir. L'incident suivant est beaucoup plus facile lorsque vous savez que /var s'est rempli parce que les journaux de débogage ont grossi après un déploiement, ou que la pression mémoire a commencé lorsque le nombre de workers a doublé.

Meilleures pratiques pour la prévention

  • Surveillance régulière : Mettez en place une surveillance régulière du CPU, de la mémoire et de l'espace disque à l'aide d'outils comme top, htop, free, df et de solutions de surveillance dédiées (par exemple, Nagios, Zabbix, Prometheus).
  • Automatiser la rotation des journaux : Assurez-vous que logrotate est correctement configuré pour tous les services générant des journaux.
  • Optimiser les configurations d'application : Optimisez les paramètres de l'application pour être plus efficaces en termes de ressources. Par exemple, ajustez les processus workers du serveur web, les pools de connexions de base de données, etc.
  • Configurer des alertes : Configurez des alertes pour une utilisation élevée soutenue, une croissance rapide, les kills OOM, le remplissage des systèmes de fichiers, l'épuisement des inodes et les redémarrages de services. Alertez sur les tendances, pas seulement sur les limites strictes.
  • Mises à jour système : Maintenez votre système et vos applications à jour, car des améliorations de performances et des corrections de bugs sont souvent incluses dans les versions plus récentes.
  • Limites de ressources : Pour les systèmes multi-utilisateurs ou les environnements conteneurisés, envisagez de définir des limites de ressources (par exemple, en utilisant ulimit ou cgroups) pour empêcher un seul processus d'affamer les autres.

Le dépannage de l'épuisement des ressources consiste principalement à réduire le champ de manière disciplinée. Trouvez la ressource contrainte, identifiez le propriétaire, apportez le plus petit changement stabilisateur, puis corrigez la raison pour laquelle cela s'est produit. Les outils de base sont suffisants pour la plupart des incidents si vous les utilisez dans cet ordre et résistez à l'envie de supprimer ou de tuer avant de comprendre ce que vous touchez.