Le disque atteint 92 %. Les alertes commencent à s’affoler. Quelqu’un ouvre un ticket de « nettoyage » qui paraît inoffensif : faire tourner les logs, élaguer les images, supprimer les fichiers temporaires, vacuum des journaux. Le genre de tâche que vous faites entre deux réunions.
Deux heures plus tard, votre base de données est en lecture seule, votre nœud est expulsé, et le postmortem s’intitule quelque chose comme « Incident de suppression n°7 ». L’outil en cause ? Pas un malware. Pas un attaquant. Un utilitaire de confiance, faisant exactement ce qu’on lui a demandé.
Pourquoi le nettoyage est particulièrement dangereux en production
Le nettoyage est destructeur, généralement irréversible, et souvent effectué sous pression temporelle. C’est la trifecta. Ajoutez un quatrième élément : le travail de nettoyage tend à être délégué au contexte le moins privilégié qui possède encore assez de pouvoir pour ruiner votre journée. Root, cluster‑admin, ou le rôle « maintenance stockage » qui a silencieusement accès à tout parce que « il en a besoin ».
Le vrai piège, c’est que le nettoyage ressemble à du ménage, pas à de l’ingénierie. Vous n’avez pas de revue de conception pour « rm old stuff ». Vous ne faites pas de tests de charge pour « vacuum logs ». Vous ne le mettez pas en staging, parce que vous supprimez des données et que le staging paraît inutile. Toutes ces suppositions sont fausses.
Les systèmes modernes ne stockent pas des « fichiers ». Ils stockent des relations : des conteneurs référant des couches overlay, des bases de données référant des segments WAL, des services référant des sockets et des fichiers de verrou, des snapshots référant l’historique des blocs, des expéditeurs de logs référant des positions d’inode, des outils de sauvegarde référant des checksums. Lorsqu’un « nettoyeur » supprime un objet, il peut casser une relation qui n’a jamais été consignée nulle part.
Une citation, parce que l’industrie l’a apprise à la dure : « Idée paraphrasée » de James Hamilton (reliability engineering) : de petits changements opérationnels provoquent une part surprenante des indisponibilités ; traitez‑les comme de vrais déploiements.
Il y a aussi le facteur humain. Quand le disque est plein, vous ressentez de l’urgence. L’urgence engendre des exploits héroïques. Les héros utilisent --force. Et --force est la version adulte de « je suis sûr que c’est OK ».
Blague n°1 : Les scripts de nettoyage sont comme des chats — ils n’obéissent que lorsqu’il est inconvenant, et ils savent toujours où se trouve la chose coûteuse.
Faits intéressants et contexte historique (court, mais utile)
- Le principe Unix « tout est un fichier » rendait le nettoyage trompeusement simple. Mais il a aussi facilité la suppression de nœuds de périphérique, de sockets et de fichiers d’état qui ne sont pas « des données » jusqu’à ce qu’ils le deviennent.
- Les premiers administrateurs système utilisaient la rotation des logs bien avant l’existence d’outils standards ; les schémas ad‑hoc de « move and truncate » hantent encore les systèmes dont les démons ne rouvrent pas correctement les logs.
- Les systèmes de fichiers avec journalisation (ext3/ext4, XFS) ont amélioré la récupération après crash, pas la récupération d’un « oups ». La suppression reste une suppression ; le journal aide la cohérence, pas le pardon.
- La transition vers les couches de conteneurs a créé de nouveaux garbage collectors (image prune, layer GC). Un « nettoyage de disque » peut maintenant casser la capacité d’ordonnancement d’un cluster entier, pas seulement d’un hôte.
- Le stockage copy‑on‑write (ZFS, btrfs) a élevé les snapshots au rang d’outil opérationnel de première classe. Il a aussi rendu la notion d’espace libre plus complexe : supprimer des fichiers peut ne pas libérer de blocs si des snapshots les référencent encore.
- L’épuisement d’inodes est un classique imposteur de « disque plein » : vous pouvez avoir beaucoup d’octets libres mais zéro inode, généralement à cause de petits fichiers dans des répertoires tmp/log.
- Les sémantiques POSIX permettent aux processus de continuer à écrire dans des fichiers supprimés. L’espace n’est pas récupéré tant que le dernier descripteur de fichier n’est pas fermé, donc « j’ai supprimé le gros fichier » ne signifie pas « le disque a regagné de l’espace ».
- Systemd a introduit des politiques tmpfiles qui peuvent effacer des répertoires que vous supposiez persistants, surtout si vous avez placé de l’état sous /tmp ou mal déclaré un répertoire runtime.
Comment les outils de « nettoyage » tournent mal : modes de défaillance récurrents
1) La cible s’est élargie : globbing, variables et valeurs par défaut « aidantes »
Un outil de nettoyage supprime rarement « une chose ». Il supprime « ce qui correspond ». Cette correspondance peut s’étendre. Les globs s’étendent. Les variables d’environnement s’étendent. Les liens symboliques s’étendent. Des montages apparaissent/disparaissent. Et soudain votre suppression soigneusement limitée devient un incendie à l’échelle du campus.
Coupables typiques : rm -rf $DIR/* où $DIR est vide ; find sans -xdev ; un lien symbolique créé par une étape d’installation ; un bind mount qui a déplacé du contenu dans un chemin « temp ».
2) Espace récupéré ? Pas forcément : descripteurs ouverts et snapshots
Votre disque est plein. Vous supprimez 30 Go. Le disque est toujours plein. Le niveau de panique augmente. Les gens suppriment plus vite. Le vrai problème est souvent soit :
- Fichiers ouverts mais supprimés : les données restent allouées jusqu’à ce que le processus ferme le descripteur.
- Snapshots : les données restent référencées par un snapshot, donc les blocs ne peuvent pas être libérés.
Les nettoyeurs qui « suppriment les vieux logs » peuvent en réalité aggraver la situation s’ils suppriment des fichiers qu’un démon de longue durée écrit encore. Vous avez maintenant masqué le chemin des logs, vous n’avez pas libéré d’espace, et vous avez rendu le dépannage plus difficile.
3) Les nettoyeurs « optimisés » qui concurrencent votre charge de travail
Certains outils sont commercialisés comme si le nettoyage était passif. Ce n’est pas le cas. Scanner des répertoires bousille les caches. Hacher des fichiers brûle du CPU. Les passes de déduplication réveillent les disques. Le rééquilibrage des métadonnées provoque des tempêtes d’I/O. Un nettoyeur peut devenir la charge la plus chaude sur la machine.
En termes de stockage : vous venez d’introduire une charge aléatoire de lectures en arrière‑plan avec une faible localité. Si le système était déjà contraint en I/O, félicitations : vous avez construit un benchmark sans limite et l’avez pointé vers la production.
4) Hypothèses « sans état » qui suppriment de l’état
Nombre de systèmes placent de l’état dans des endroits qui ont l’air temporaires :
/var/tmp, /var/lib, /run, un répertoire de cache local, ou « juste un fichier dans /tmp » devenu verrou, file d’attente ou spool.
Les nettoyeurs qui traitent ces chemins comme « sûrs à effacer » provoquent des défaillances étranges : jobs bloqués, traitement en double, métriques perdues, ou démarrages lents pendant que les caches se reconstruisent sous charge.
5) Logique de rétention qui marche jusqu’à ce que le temps bouge
Les politiques de rétention sont de l’arithmétique sur les dates plus des cas limites. Heure d’été. Dérive d’horloge. Secondes intercalaires. Frontières de nouvelle année. Le moment où vous changez le format des logs ou renommez un répertoire, votre « supprimer plus vieux que 7 jours » peut tout supprimer parce qu’il ne sait plus parser les dates.
6) Outils sûrs seuls, dangereux ensemble
Votre expéditeur de logs garde un curseur. Votre nettoyeur fait tourner les logs. Votre job de compression déplace des fichiers. Votre job de sauvegarde les lit. Chaque outil est « ok ». Ensemble, ils créent des courses : doubles rotations, archives tronquées, segments manquants, et ingestion en double.
La plupart des catastrophes de nettoyage ne proviennent pas d’une seule commande foireuse. Ce sont des échecs d’orchestration entre des outils bien intentionnés.
7) Permissions et identité : le mythe « il ne peut pas supprimer ça »
Les gens supposent qu’un outil tournant sous un compte de service ne peut pas faire de gros dégâts. Puis quelqu’un ajoute le compte à un groupe « temporairement », ou il tourne dans un conteneur privilégié, ou le système de fichiers est monté avec une propriété laxiste, ou les ACL accordent plus que prévu.
Les incidents de nettoyage aiment la dérive des privilèges. C’est discret. C’est pratique. C’est catastrophique.
Blague n°2 : « Je vais juste lancer un nettoyage rapide » est la façon dont les incidents font leur cardio.
Playbook de diagnostic rapide : vérifications première/seconde/troisième
Quand un « nettoyage » a mal tourné, vous avez besoin de vitesse, pas d’élégance. L’objectif est d’identifier le vrai goulot d’étranglement avant de supprimer plus de preuves.
Première étape : vérifier quelle ressource est réellement épuisée
- Octets vs inodes : un système peut être « plein » de deux manières différentes.
- Système de fichiers vs thin pool vs réserve de snapshot : « df dit 90 % » n’est pas toute l’histoire sur LVM thin, ZFS, ou overlays de conteneurs.
- Local au nœud vs stockage distant : les évictions Kubernetes tiennent compte de la pression sur le système de fichiers du nœud, pas de votre SAN sophistiqué.
Deuxième étape : identifier les plus gros consommateurs (et vérifier si la suppression libérera l’espace)
- Top répertoires et fichiers.
- Fichiers ouverts mais supprimés.
- Références de snapshots ou rétention copy‑on‑write.
Troisième étape : évaluer le rayon d’impact et arrêter l’hémorragie
- Désactiver ou mettre en pause le job de nettoyage (cron, timers systemd, runner CI).
- Geler d’autres rotations/suppressions qui pourraient détruire des artefacts forensiques.
- Stabiliser le système : récupérer un peu d’espace en sécurité (même 2–5 %) pour rétablir les opérations normales (journald, gestionnaires de paquets, bases de données).
Règle de décision à garder
Si vous ne pouvez pas expliquer pourquoi supprimer une chose va libérer de l’espace, ne la supprimez pas encore. Mesurez d’abord. Puis supprimez avec un plan de rollback (snapshot, backup, ou au moins un répertoire de quarantaine sur le même système de fichiers).
Tâches pratiques : commandes, sorties et décisions (12+)
Voici les tâches que j’utilise quand un « nettoyage » a déraillé. Chacune inclut : une commande, ce que signifie une sortie typique, et la décision à prendre ensuite. Traitez‑les comme des blocs de construction, pas comme un script à copier aveuglément.
Tâche 1 : Vérifier l’utilisation en octets par système de fichiers (triage rapide)
cr0x@server:~$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme0n1p2 ext4 220G 214G 1.8G 100% /
tmpfs tmpfs 32G 120M 32G 1% /run
/dev/sdb1 xfs 3.6T 2.1T 1.5T 59% /srv
Sens : La racine est effectivement pleine. /srv est correct, mais cela n’aide pas si la charge écrit dans /.
Décision : Concentrez‑vous sur la récupération de quelques Go sur / d’abord pour restaurer la stabilité. Ne « nettoyez pas /srv » simplement parce qu’il est volumineux.
Tâche 2 : Vérifier l’épuisement d’inodes (le moment où « df ment »)
cr0x@server:~$ df -ih
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/nvme0n1p2 14M 14M 0 100% /
Sens : Vous êtes à court d’inodes. Supprimer quelques gros fichiers n’aidera pas si le problème est des millions de petits fichiers.
Décision : Identifiez les répertoires avec un nombre massif de fichiers (spools, caches, temp dirs). Évitez les outils récursifs qui prendront des heures et empireront la charge.
Tâche 3 : Trouver quels répertoires consomment de l’espace (octets)
cr0x@server:~$ sudo du -xhd1 /var | sort -h
120M /var/cache
3.2G /var/log
14G /var/lib
18G /var
Sens : /var/lib est le gros consommateur. C’est généralement de l’état applicatif (bases de données, runtimes de conteneurs), pas des « déchets ».
Décision : Approfondissez avec prudence dans /var/lib ; envisagez un nettoyage conscient des applications plutôt que des suppressions à la hache.
Tâche 4 : Trouver quels répertoires consomment des inodes (nombre de fichiers)
cr0x@server:~$ sudo find /var -xdev -type f -printf '.' | wc -c
12984217
Sens : ~13 millions de fichiers sous /var. C’est énorme. Vous avez probablement des fichiers temporaires en fuite, des fragments de cache, ou un schéma de rotation cassé.
Décision : Identifiez ensuite le répertoire point chaud (ne supprimez pas aveuglément).
Tâche 5 : Localiser les hotspots d’inodes par répertoire
cr0x@server:~$ sudo find /var -xdev -mindepth 1 -maxdepth 3 -type f -printf '%h\n' | sort | uniq -c | sort -nr | head
8420000 /var/lib/app/spool
1960000 /var/log/nginx
510000 /var/tmp/session-cache
Sens : /var/lib/app/spool explose. Les spools sont généralement de la « logique métier », pas des déchets.
Décision : Traitez‑le comme un incident dans la pipeline applicative ; le nettoyage peut n’être qu’un pansement, pas une solution.
Tâche 6 : Vérifier les fichiers ouverts mais supprimés (espace non récupéré)
cr0x@server:~$ sudo lsof +L1 | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
java 2310 app 12w REG 259,2 8.0G 0 9123 /var/log/app/app.log (deleted)
nginx 1882 www 5w REG 259,2 1.2G 0 7742 /var/log/nginx/access.log (deleted)
Sens : Ces processus gardent des descripteurs sur des logs supprimés. Les octets sont toujours alloués.
Décision : Redémarrez ou signalez les processus pour qu’ils rouvrent les logs (par ex. systemctl restart ou kill -HUP), puis revérifiez df.
Tâche 7 : Confirmer l’utilisation de journald avant de vacuumer
cr0x@server:~$ sudo journalctl --disk-usage
Archived and active journals take up 4.1G in the file system.
Sens : Les journaux occupent une place non négligeable. Le vacuum peut libérer de l’espace rapidement, mais vous perdrez des logs forensiques.
Décision : Si vous êtes en plein incident, faites un snapshot ou exportez les logs pertinents d’abord ; puis vacuumez jusqu’à un seuil de rétention connu.
Tâche 8 : Vacuum journald en sécurité vers une taille cible
cr0x@server:~$ sudo journalctl --vacuum-size=800M
Vacuuming done, freed 3.3G of archived journals from /var/log/journal.
Sens : Vous avez récupéré 3.3G depuis les journaux.
Décision : Revérifiez la santé du système. Si ce n’était qu’une mesure d’urgence, corrigez la cause racine qui rempli le disque.
Tâche 9 : Valider la configuration de logrotate sans l’exécuter
cr0x@server:~$ sudo logrotate -d /etc/logrotate.conf
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file nginx
error: nginx:12 duplicate log entry for /var/log/nginx/access.log
Sens : Logrotate se comporterait de manière inattendue ou échouerait, laissant les logs croître sans borne.
Décision : Corrigez la configuration et lancez logrotate manuellement une fois (avec précaution) après validation.
Tâche 10 : Lancer logrotate une fois, en mode verbeux, et observer les changements
cr0x@server:~$ sudo logrotate -vf /etc/logrotate.conf
rotating pattern: /var/log/nginx/*.log after 1 days (14 rotations)
renaming /var/log/nginx/access.log to /var/log/nginx/access.log.1
compressing log with: /bin/gzip
Sens : La rotation a eu lieu ; la compression s’est déclenchée. Si un démon ne rouvre pas les logs, vous pouvez maintenant avoir des fichiers ouverts mais supprimés.
Décision : Assurez‑vous que les actions postrotate signalent correctement les services ; vérifiez avec lsof +L1.
Tâche 11 : Vérifier l’utilisation disque du runtime conteneur (exemple Docker)
cr0x@server:~$ sudo docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 48 12 38.2GB 24.7GB (64%)
Containers 21 6 3.1GB 1.0GB (32%)
Local Volumes 16 10 220GB 0B (0%)
Build Cache 12 0 5.6GB 5.6GB
Sens : Le gros chiffre ce sont les volumes locaux. Le prune des images ne résoudra pas la pression disque ; ce sont des volumes d’état.
Décision : Auditez les volumes et leurs propriétaires. Envisagez une rétention applicative ou déplacer les volumes vers un montage plus grand.
Tâche 12 : Pruner en sécurité (ne pas supprimer des objets en cours d’utilisation)
cr0x@server:~$ sudo docker image prune -a --filter "until=168h"
Deleted Images:
deleted: sha256:3d2b...
Total reclaimed space: 12.4GB
Sens : Vous avez récupéré 12.4G d’images de plus de 7 jours.
Décision : Si c’est un nœud de production, coordonnez‑vous avec le rythme de déploiement ; assurez‑vous de ne pas pruner des images nécessaires pour des rollbacks rapides.
Tâche 13 : Vérifier les symptômes de pression disque sur un nœud Kubernetes
cr0x@server:~$ kubectl describe node worker-3 | sed -n '/Conditions:/,/Addresses:/p'
Conditions:
Type Status LastHeartbeatTime Reason Message
DiskPressure True 2026-01-22T10:11:02Z KubeletHasDiskPressure kubelet has disk pressure
Ready True 2026-01-22T10:11:02Z KubeletReady kubelet is posting ready status
Sens : Le nœud est « Ready » mais sous DiskPressure ; des évictions vont commencer et les workloads vont se dégrader.
Décision : Libérez de l’espace sur le système de fichiers du nœud utilisé par kubelet/runtime conteneur ; ne « nettoyez pas à l’intérieur des pods » comme premier réflexe.
Tâche 14 : Réalité des snapshots ZFS (pourquoi les suppressions ne libèrent pas d’espace)
cr0x@server:~$ sudo zfs list -o name,used,avail,refer,mountpoint tank/app
NAME USED AVAIL REFER MOUNTPOINT
tank/app 980G 120G 240G /srv/app
Sens : Le dataset « USED » est 980G mais « REFER » est 240G. Le delta provient typiquement de snapshots ou d’enfants dataset.
Décision : Inspectez les snapshots avant de supprimer quoi que ce soit ; le nettoyage peut nécessiter des changements de rétention de snapshot.
Tâche 15 : Lister les snapshots et voir ce qui retient l’espace
cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer,creation -s used | tail
tank/app@daily-2026-01-15 22G 240G Mon Jan 15 02:00 2026
tank/app@daily-2026-01-16 27G 240G Tue Jan 16 02:00 2026
tank/app@daily-2026-01-17 31G 240G Wed Jan 17 02:00 2026
tank/app@daily-2026-01-18 35G 240G Thu Jan 18 02:00 2026
tank/app@daily-2026-01-19 39G 240G Fri Jan 19 02:00 2026
tank/app@daily-2026-01-20 44G 240G Sat Jan 20 02:00 2026
tank/app@daily-2026-01-21 48G 240G Sun Jan 21 02:00 2026
Sens : Les snapshots consomment de l’espace significatif. Supprimer des fichiers dans /srv/app ne réduira pas beaucoup USED tant que ces snapshots existent.
Décision : Ajustez la rétention ou répliquez les snapshots ailleurs avant de les élaguer ; faites‑le délibérément, pas dans la panique.
Tâche 16 : Identifier si un nettoyage a traversé des frontières de systèmes de fichiers
cr0x@server:~$ sudo find / -xdev -maxdepth 2 -type d -name 'tmp' -print
/tmp
/var/tmp
Sens : -xdev vous maintient sur un seul système de fichiers. Sans lui, un nettoyage pourrait traverser des volumes montés, y compris des sauvegardes.
Décision : Pour toute suppression basée sur find, ajoutez -xdev sauf si vous pouvez justifier de traverser des systèmes de fichiers par écrit.
Trois mini‑histoires d’entreprise : mauvaise hypothèse, optimisation qui se retourne, victoire ennuyeuse
Mini‑histoire 1 : L’incident causé par une mauvaise hypothèse (« /tmp est toujours sûr »)
Une entreprise de taille moyenne exploitait une pipeline de paiement avec un service Java et un sidecar qui gérait le chiffrement. Le sidecar écrivait des artefacts éphémères dans /tmp. C’était supposé être temporaire : chiffrer, transmettre, supprimer. Simple.
Avec le temps, « temporaire » est devenu « opérationnel ». Le sidecar utilisait aussi /tmp comme file de récupération : si l’API en amont throttlait, il mettait en cache les payloads et réessayait. Personne n’a documenté cela parce que ce n’était pas une fonctionnalité intentionnelle ; c’était un bricolage pragmatique ajouté lors d’un incident passé et jamais revu.
Puis un ingénieur système a activé une politique tmpfiles systemd pour nettoyer les entrées de /tmp plus vieilles qu’un jour. Totalement normal. Cela a réduit le churn d’inodes et gardé les hôtes propres. Le weekend suivant, le trafic a flambé, le sidecar a été plus souvent throttlé, et la file de réessai a grossi. Elle a dépassé le seuil d’un jour. Le nettoyeur a fait son travail.
Le lundi matin, on a eu des « transactions manquantes ». Pas perdues en transit, pas rejetées — supprimées silencieusement de la file de réessai. Les logs du service n’aidaient pas non plus parce qu’ils référenceaient des IDs de requête, mais les payloads avaient disparu.
La correction technique était ennuyeuse : déplacer la file de réessai vers un répertoire dédié sous /var/lib, gérer la rétention explicitement, et ajouter des métriques sur la profondeur de file. La correction culturelle a été plus importante : toute action de « nettoyage » touchant aux politiques tmpfiles OS nécessite désormais la signature du propriétaire applicatif. Parce que la phrase « c’est juste /tmp » est la façon dont l’argent disparaît.
Mini‑histoire 2 : L’optimisation qui s’est retournée contre nous (prune d’images agressif sur runners CI)
Une autre organisation exécutait des runners CI auto‑hébergés sur des machines costaudes. L’utilisation disque augmentait parce que les builds tiraient beaucoup d’images conteneurs. Quelqu’un a eu une idée : un job nocturne pour pruner tout ce qui a plus de 24 heures. L’objectif était noble : arrêter les relances pour « disque à 90 % ».
Ça a marché pendant une semaine. Puis les temps de build ont empiré. Pas un peu. Assez pour que les développeurs relancent des jobs, ce qui a augmenté la charge. Le job de prune tournait la nuit, mais les dégâts n’étaient pas « nocturnes ». Chaque matin, la première vague de builds retéléchargeait les images, martelant le registry et saturant des liens réseau partagés avec des services de production.
Le mode de défaillance n’était pas « nous avons supprimé des choses nécessaires ». C’était « nous avons effacé la localité ». Les caches existent parce que le réseau et le stockage ne sont pas gratuits. En optimisant pour le disque, ils ont créé un déni de service distribué contre leur propre registry et WAN.
La correction : passer d’une suppression basée sur le temps à une rétention basée sur la capacité avec un plancher pour les images de base couramment utilisées. Garder un ensemble chaud. Pruner quand le disque dépasse un seuil, pas selon le calendrier. Aussi : pinner le job de prune dans un cgroup avec limites I/O et CPU, parce que le travail de fond ne doit pas devenir le processus le plus bruyant de l’hôte.
Mini‑histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise (quarantaine, puis suppression)
Une plateforme SaaS avait le problème classique : croissance des logs sur des nœuds gérant du trafic par rafales. Un ingénieur a proposé de supprimer directement les anciens logs dans /var/log. Un autre a insisté sur une « quarantaine »: déplacer les fichiers candidats vers /var/log/.trash sur le même système de fichiers, attendre 24 heures, puis supprimer.
Ça semblait gaspilleur — pourquoi garder des déchets ? Mais l’étape de quarantaine était peu coûteuse. Les opérations de renommage sont rapides. Cela préservait aussi la possibilité de récupérer d’erreurs sans impliquer des backups, des tickets ou des conversations gênantes.
Un jour, un service a mis à jour son format de logs et a commencé à écrire vers un nouveau nom de fichier qui correspondait au glob de nettoyage. Le job de nettoyage a déplacé le log actif en quarantaine. Le service a continué à écrire, mais il a écrit dans un fichier rouvert au chemin original. Pendant ce temps, l’expéditeur de logs a cassé parce que son curseur d’inode suivait le fichier déplacé. Les alertes se sont déclenchées rapidement car l’ingestion avait chuté.
Parce que le fichier était en quarantaine et non supprimé, la récupération a été simple : le remettre, ajuster la correspondance du nettoyage, redémarrer le shipper, et réingérer le trou. Pas de restauration. Pas de perte de données. Le postmortem contenait une phrase rare et agréable : « Aucun impact client. » Cette phrase s’achète presque toujours par des pratiques ennuyeuses que personne ne veut implémenter.
Erreurs courantes : symptôme → cause racine → correctif
Le disque est plein, vous avez supprimé des gros fichiers, mais df ne change pas
Symptôme : df affiche toujours 95–100 % après suppression.
Cause racine : Fichiers ouverts mais supprimés (processus garde le descripteur) ou snapshots retenant des blocs.
Correctif : Vérifiez lsof +L1 et redémarrez/rechargez les services ; pour ZFS/btrfs, inspectez les snapshots et ajustez la rétention délibérément.
Un service plante après un « tmp cleanup », mais le disque semble mieux
Symptôme : Après nettoyage de /tmp ou /var/tmp, un démon ne démarre plus, des jobs disparaissent, ou des pics de taux surviennent.
Cause racine : L’application a détourné les répertoires temporaires pour de l’état (files d’attente, verrous, sockets, caches requis à l’exécution).
Correctif : Déplacez l’état vers un chemin persistant explicite ; codifiez le nettoyage en connaissance de l’application ; ajoutez des tests pour les politiques tmpfiles en staging.
La rotation des logs « fonctionne », mais vous avez perdu des logs ou des trous d’ingestion apparaissent
Symptôme : Des logs compressés existent, mais des trous d’ingestion ou des lignes manquent.
Cause racine : Logs pivotés/tronqués sans signaler le processus ; le shipper suit les inodes et se retrouve confus par les mouvements/troncations.
Correctif : Utilisez les bonnes actions postrotate (HUP/reload), et alignez la configuration du shipper avec la méthode de rotation (copytruncate vs rename).
Le job de nettoyage provoque un pic d’I/O et latence sur l’hôte
Symptôme : La latence monte quand le nettoyage s’exécute ; iowait grimpe ; les bases de données se plaignent.
Cause racine : Le nettoyeur effectue des scans profonds, compression, checksum, ou dédup sans limitation de vitesse.
Correctif : Limitez le débit via ionice/nice, planifiez en heures creuses, réduisez la portée, ou redesign vers un nettoyage incrémental avec métriques.
« On a pruné des images » et maintenant les rollbacks sont lents ou échouent
Symptôme : Le rollback nécessite de tirer des images et expire ; les nœuds churnent.
Cause racine : Un élagage agressif a supprimé des images supposées en cache localement.
Correctif : Gardez un ensemble chaud protégé ; pruniez par capacité avec une rétention minimale ; alignez avec la fréquence de déploiement et la politique de rollback.
Peur de corruption du système de fichiers après une suppression massive
Symptôme : Les applications renvoient des erreurs, des répertoires semblent bizarres, quelqu’un dit « peut‑être corruption ».
Cause racine : Généralement pas de corruption ; il s’agit d’état manquant, de changements de permissions, ou de sockets/verrous supprimés. La vraie corruption est plus rare qu’on le pense.
Correctif : Validez les montages, permissions et l’état applicatif ; vérifiez les logs kernel ; lancez des vérifications de système de fichiers seulement avec un plan et une fenêtre de downtime.
Le nettoyage s’est exécuté sur le mauvais hôte ou le mauvais montage
Symptôme : Un nœud sans rapport avec l’alerte a été « nettoyé », ou un montage de sauvegarde a été vidé.
Cause racine : Absence de garde‑fous : pas de vérification du hostname, pas de vérification de montages, pas de -xdev, automatisation pointée sur le mauvais groupe d’inventaire.
Correctif : Ajoutez des vérifications strictes (UUIDs de montage attendus, marqueurs d’environnement), et exigez une confirmation interactive pour les actions destructrices hors fenêtres de maintenance.
Checklists / plan pas à pas : nettoyer en sécurité sans regrets
Étape 0 : Arrêter d’empirer la situation (5 minutes)
- Mettre en pause le job de nettoyage : désactivez cron/timer systemd/job CI temporairement.
- Capturer des preuves : usage disque/inodes actuel, top répertoires,
lsof +L1, et extraits récents de syslog/journal. - Donner un peu d’air au système : récupérer une petite quantité d’espace en sécurité (vacuum journald ou déplacer des logs en quarantaine).
Étape 1 : Prouver ce qui retient l’espace (15–30 minutes)
- Octets vs inodes : lancez
df -hTetdf -ih. - Localiser les consommateurs :
du -xhd1sur le système plein ; pour les inodes, compter les fichiers par répertoire. - Vérifier les fichiers ouverts supprimés :
lsof +L1. - Si vous utilisez du stockage CoW : inspectez les snapshots et l’utilisation des datasets (ZFS/btrfs).
Étape 2 : Choisir la soupape de secours la moins risquée
- Préférez supprimer des données régénérables : caches de build, caches de paquets, artefacts temporaires recréables.
- Préférez un nettoyage conscient de l’application : vacuum de base via outils vendor, prune conteneur avec filtres de rétention, logrotate avec signaux corrects.
- Évitez de supprimer des inconnus : tout ce qui est dans
/var/libsans connaître le propriétaire est un piège.
Étape 3 : Mettre en place des garde‑fous avant de réactiver l’automatisation
Un job de nettoyage sans garde‑fous n’est pas de « l’automatisation ». C’est juste un risque programmé.
- Quarantaine puis suppression : déplacez les fichiers candidats vers un répertoire caché sur le même système de fichiers ; supprimez après un délai.
- Vérification des montages : contrôlez les points de montage et types de système attendus avant d’exécuter.
- Limites de portée : utilisez
-xdev, chemins explicites, et profondeur maximale explicite. - Exécutions à blanc : enregistrez ce qui serait supprimé. Toujours.
- Limitation de débit : utilisez
niceetionicepour les jobs de fond. - Métriques : alertez sur les tendances de croissance, pas seulement sur des seuils, et traquez les actions de nettoyage comme événements.
Étape 4 : Rendre le processus volontairement ennuyeux
Le meilleur processus de nettoyage est celui dont personne ne parle parce qu’il ne surprend personne. Cela signifie : politiques de rétention documentées, propriétaires assignés, et répertoires « temporaire » traités comme des contrats, pas des impressions.
FAQ
1) Pourquoi supprimer un fichier de log ne libère parfois pas d’espace disque ?
Parce qu’un processus peut garder le fichier ouvert et continuer à y écrire même après son unlink. L’espace n’est libéré que lorsque le dernier descripteur de fichier est fermé. Utilisez lsof +L1 pour les trouver et redémarrez/rechargez le processus.
2) Est‑ce que rm -rf est toujours une mauvaise idée ?
C’est un outil tranchant. Le problème n’est pas rm ; c’est l’ambiguïté. Si vous ne pouvez pas définir précisément la cible et prouver qu’elle est correcte, n’utilisez pas la suppression récursive forcée en production. Préférez des déplacements en quarantaine et un nettoyage conscient des applications.
3) Quel est le « meilleur » espace d’urgence à récupérer rapidement ?
Habituellement les archives journald, les caches des gestionnaires de paquets, ou des caches de build connus — des choses qui se régénèrent. Évitez de supprimer tout ce qui ressemble à de l’état (/var/lib, répertoires de bases de données, montages de volumes) sauf si vous avez confirmé la propriété et la récupération.
4) Pourquoi nettoyer /tmp a‑t‑il cassé une application ?
Parce que l’application stockait de l’état dans un chemin temporaire : sockets, verrous, files d’attente, ou métadonnées cachées nécessaires à l’exécution. Corrigez en déplaçant l’état vers un répertoire persistant explicite et en déclarant correctement les répertoires runtime (surtout avec systemd).
5) Pourquoi ZFS affiche‑t‑il encore une forte utilisation après suppression de fichiers ?
Les snapshots conservent des références aux anciens blocs. Supprimer des fichiers courants peut ne pas libérer d’espace tant que les snapshots ne sont pas détruits. Vérifiez avec zfs list -t snapshot et ajustez la rétention avec précaution — les snapshots sont souvent votre seul rollback rapide.
6) Devons‑nous pruner agressivement les images conteneurs pour garder les disques propres ?
Pas agressivement — stratégiquement. Le prune peut effacer la localité et ralentir les déploiements/rollbacks. Utilisez des seuils de capacité, conservez un ensemble chaud, et coordonnez avec le rythme des releases.
7) Comment empêcher un nettoyage de traverser des volumes montés ?
Utilisez des protections de frontières de système de fichiers comme find -xdev, et validez les points de montage avant d’exécuter. Dans l’automatisation, ajoutez des vérifications du type de système de fichiers et des IDs de périphérique attendus.
8) Est‑ce que « supprimer plus vieux que N jours » est fiable ?
C’est fiable seulement si votre parsing temporel et le nommage des fichiers sont fiables. Les changements DST, les décalages de fuseau, et les renommages cassent la logique de rétention. Préférez la suppression basée sur mtime avec portee explicite et exécutions à blanc, et surveillez le nombre de suppressions.
9) Quel est le plus grand correctif culturel pour les catastrophes de nettoyage ?
Traitez les opérations destructrices comme des déploiements : revue, staging, observabilité, et rollback. Le nettoyage n’est pas du ménage ; c’est un changement en production.
Prochaines étapes concrètes à faire cette semaine
Si vous exploitez des systèmes de production, vous n’avez pas besoin d’un « nettoyeur » meilleur. Vous avez besoin de moins de surprises. La surprise vient de l’ambiguïté : propriété inconnue, rétention mal définie, et outils autorisés à supprimer sans prouver qu’ils suppriment la bonne chose.
- Inventoriez vos mécanismes de nettoyage : cron jobs, timers systemd, maintenance des runners CI, GC de conteneurs, rétention de snapshots. Notez les propriétaires.
- Ajoutez un motif de quarantaine pour tout ce qui est basé sur des fichiers. Renommez/déplacez d’abord, supprimez ensuite.
- Instrumentez la pression disque : octets et inodes, plus les taux de croissance. Les alertes de tendance valent mieux que « 92 % à 3h du matin ».
- Codifiez le « diagnostic rapide » dans vos runbooks : octets vs inodes, fichiers ouverts supprimés, snapshots, usage du runtime conteneur.
- Bridez les nettoyages de fond : votre nettoyeur ne doit jamais être le consommateur principal sur l’hôte.
- Décidez ce qui peut être supprimé et ce qui doit être géré par des outils applicatifs. Si c’est de l’état, traitez‑le comme de l’état.
La propreté en production n’est pas supprimer plus. C’est supprimer avec intention, avec des garde‑fous, et avec un moyen de revenir en arrière lorsque l’intention rencontre la réalité.