107% d'usure : chronique d'un changement de disques mouvementé

107% d'usure : chronique d'un changement de disques mouvementé

Si vous avez vécu quelques downtimes inhabituels ces derniers jours, voici l'histoire de ce qui s'est passé en coulisses.

Le problème

Tout a commencé par un email de monitoring assez peu rassurant : les deux SSD NVMe du serveur de Leek Wars affichaient 107% d'usure. Pour ceux qui se demandent comment un disque peut être usé à plus de 100% : les fabricants donnent une endurance estimée (en téraoctets écrits), au-delà de laquelle ils ne garantissent plus rien. Le SMART continue à compter au-delà, et 107%, ça veut dire "techniquement, ce truc devrait déjà être mort".

Les deux disques en RAID 1 (miroir) étaient des jumeaux nés en même temps, vieillissant au même rythme. Bref : intervention OVH en urgence pour les remplacer.

Phase 1 : la paranoïa

Avant toute intervention, j'ai voulu m'assurer qu'on avait des sauvegardes complètes ailleurs. Les sauvegardes habituelles couvrent la base PostgreSQL principale et les dossiers critiques, mais certaines tables historiques étaient exclues du backup quotidien pour des raisons de volume.

Quelques heures de pg_dump plus tard, ces tables étaient en sécurité, ainsi que les volumes Docker critiques. On peut respirer.

Phase 2 : premier disque, premier piège

OVH remplace le premier disque. Le serveur reboote... en mode rescue. Pas grave, on bascule en boot disque, et le système revient. Sauf que Traefik refuse de démarrer avec un message cryptique :

Sauf que rien n'écoute sur ce port. Sauf si... Docker garde des entrées fantômes dans sa base interne local-kv.db, qui pointent vers une vieille IP de bridge réseau (172.18.0.6) qui n'existe plus. Au reboot, Docker recrée mécaniquement des docker-proxy orphelins qui squattent les ports exposés par les services, empêchant Traefik de les utiliser.

Solution : arrêter Docker, supprimer le local-kv.db, redémarrer Docker. Il reconstruit son état proprement depuis le Swarm. Service rétabli.

Premier disque ajouté au RAID, resync (~40 min), boot installé sur le nouveau disque. Tout va bien.

Phase 3 : deuxième disque, vraie galère

OVH revient et nous annonce que le deuxième disque (celui qu'on n'avait pas encore remplacé) a aussi failli son SMART. Pas surprenant. On planifie le remplacement.

Le swap s'effectue. Le serveur reboote... et atterrit dans un shell UEFI. Le firmware ne trouve aucune entrée de boot valide. Forcément : on avait installé GRUB sur le disque qu'OVH vient de remplacer.

Direction le mode rescue. Là, opération à cœur ouvert :

1. Monter le RAID dégradé (nvme1n1 a survécu, il a tout l'OS) 2. Formater la partition EFI vide du nouveau disque 3. Chrooter, réinstaller GRUB 4. Créer manuellement l'entrée EFI dans le NVRAM avec efibootmgr 5. Repartitionner le nouveau disque pour matcher l'ancien 6. L'ajouter au RAID, lancer la resync 7. Reboot

Le serveur reboote, GRUB charge le kernel, Linux démarre... et puis plus rien. Ping OK, mais SSH refuse les connexions. Pendant ce temps, dans la console KVM, on voit le firewall logger des connexions bloquées : signe que le système tourne, mais que les services applicatifs ne sont pas lancés.

Phase 4 : l'investigation

Ça fait deux heures que le site est inaccessible. Retour en mode rescue, je monte le filesystem de production et je consulte le journal systemd du dernier boot. Et là, le coupable apparaît :

Emergency mode. C'est là que systemd se réfugie quand un mount critique échoue. En emergency mode, aucun service réseau ne démarre : pas de SSH, pas de Docker, rien. Mais le kernel reste actif, donc ping et firewall fonctionnent. Le piège parfait.

La cause racine ? Le /etc/fstab mentionne :

Quand j'ai formaté les partitions EFI des nouveaux disques avec mkfs.vfat, j'ai oublié de leur poser le label EFI_SYSPART. Du coup, systemd attend 90 secondes une partition qui n'existe pas, abandonne, et fait tomber tout local-fs.target en cascade.

Un coup de fatlabel /dev/nvme0n1p1 EFI_SYSPART plus tard, vérifications croisées sur tous les mounts du fstab, reboot. Cette fois c'est la bonne : SSH répond en moins de 2 minutes, tous les services démarrent, le site est de retour.

Le bilan

Au final :

Merci pour votre patience pendant ces interruptions. Le serveur est désormais reparti pour des années avec ses nouveaux disques. À la prochaine !