# Incidents — Historique et résolutions ## Index | Date | Composant | Résumé | Sévérité | |---|---|---|---| | 2026-05-29 | RAID5 / sdb + storage-01 | sdb ATA bus errors sous I/O — migration /srv/data du RAID vers NVMe | Important | | 2026-05-27 | RAID5 / sdd | Disque sdd défaillant (44 secteurs morts) — corruptions multiples en cascade | Critique | | 2026-05-14 | Grafana | OOMKilled — limite 256Mi trop serrée pour Grafana 13 | Warning | | 2026-05-13 | AlertManager | Receiver "null" non défini — ReconciliationFailed | Warning | | 2026-05-13 | llama-server | `/metrics` retourne 501 Not Implemented — flag `--metrics` absent | Warning | | 2026-05-13 | nftables storage-01 | Règle monitoring ajoutée après le drop — paquets bloqués | Warning | | 2026-05-13 | storage-01 | Corruption EXT4 + réinstallation hermes-agent | Critique | | 2026-05-11 | storage-01 | Boucle fsck après coupure de courant — XFS corrompu | Critique | --- ## 2026-05-29 — Migration /srv/data : RAID5 → NVMe (sdb ATA bus errors) ### Contexte Suite à l'incident du 2026-05-27 (sdd retiré), le RAID5 tournait déjà en dégradé `[4/3] [UUU_]`. Décision prise de migrer `/srv/data` du RAID vers le LV NVMe (`almalinux-home`, 845 GB XFS) pour sortir les données d'un RAID en mauvais état. ### Symptômes déclencheurs Lors du lancement du rsync de migration, le processus se bloque en état `D` (uninterruptible sleep) : ``` dmesg: [ 1341.231068] sd 1:0:0:0: [sdb] FAILED Result: hostbyte=DID_OK [ 1341.231082] I/O error, dev sdb, sector 582656 op 0x0:(READ) [ 1358.639065] ata2.00: res 40/00:ff:ff:00:00/... Emask 0x50 (ATA bus error) [ 1451.541751] md/raid:md0: Disk failure on sdb2, disabling device. ``` `sdb` génère des ATA bus errors sous charge I/O soutenue (câble SATA ou port instable). SMART passe (`PASSED`, aucun secteur défaillant) mais `Raw_Read_Error_Rate = 124014439` — problème d'interface, pas de plateau. ### Résolution — migration complète **Étape 1 — Stopper les services** ```bash sudo systemctl stop hermes-agent hermes-dashboard litellm qdrant postgresql-16 alertmanager-webhook ``` **Étape 2 — Préparer la destination NVMe** ```bash sudo mkdir -p /home/data sudo mount --bind /home/data /srv/data-new # vérification préalable ``` **Étape 3 — Gérer sdb (blocage rsync)** Le premier rsync (avec sdb actif) se bloque en état `D`. Solution : marquer sdb comme défaillant pour que le RAID lise depuis sda/sdc/sdd uniquement. ```bash sudo kill sudo mdadm --manage /dev/md0 --fail /dev/sdb2 # → [4/3] [U_UU] — sdb hors circuit ``` **Étape 4 — Rsync (RAID → NVMe)** ```bash sudo nohup rsync -aHX --info=progress2 /srv/data/ /home/data/ > /tmp/rsync-migration.log 2>&1 & # Durée : ~35s — 205 MB/s — 5106 fichiers — exit code 23 (xattr SELinux non critiques) ``` **Étape 5 — Corriger la corruption Qdrant** Un `version.info` de segment RocksDB copié depuis le RAID avec sdb défaillant était corrompu : ```bash sudo cat /srv/data/qdrant/storage/collections/funk-docs/0/segments/784eab54-.../version.info # → 0.D\0 (corrompu — devrait être 0.6.0) printf '0.6.0' | sudo tee /srv/data/qdrant/storage/collections/funk-docs/0/segments/784eab54-.../version.info ``` **Étape 6 — Basculer /srv/data vers NVMe** ```bash sudo umount /srv/data # démonte le RAID sudo umount /srv/data-new # démonte le mount intermédiaire sudo mount --bind /home/data /srv/data ``` **Étape 7 — Mettre à jour fstab** ```bash # Remplacer l'entrée RAID par le bind mount # Avant : UUID=3add8360-... /srv/data ext4 defaults,noatime,nodiratime 0 0 # Après : echo '/home/data /srv/data none bind 0 0' | sudo tee -a /etc/fstab # (commenter l'ancienne ligne UUID=3add8360) ``` **Étape 8 — Redémarrer les services** ```bash sudo systemctl start postgresql-16 qdrant litellm hermes-agent hermes-dashboard alertmanager-webhook ``` ### État post-migration | Composant | Avant | Après | |---|---|---| | `/srv/data` | RAID5 ext4 `/dev/md0` (dégradé) | NVMe XFS bind-mount `/home/data` | | Espace disponible | 2.6 TB RAID (dégradé, risqué) | 801 GB NVMe (sûr) | | RAID5 md0 | `[4/3] [UUU_]` actif | `[4/3] [U_UU]` — sdb `(F)`, **plus monté** | | Tous les services | Stoppés | ✅ Actifs | ### Actions restantes - **Retirer sdb physiquement** (ou le supprimer du RAID) : ```bash sudo mdadm --manage /dev/md0 --remove /dev/sdb2 ``` - **Décider du sort du RAID** : les données sont sur NVMe. Le RAID peut être démonté définitivement ou conservé pour une future migration vers un NAS. - Vérifier câble SATA de sdb (ATA bus errors = câble ou port, pas plateau). --- ## 2026-05-27 — RAID5 : défaillance sdd — corruptions multiples en cascade ### Symptômes Au démarrage du cluster (`funk-start --k8s`) : - Qdrant en `CrashLoopBackOff` : `RocksDB open error: Corruption: no log_file_number ... MANIFEST-000033 may be corrupted` - Grafana en `CrashLoopBackOff` : `pq: relation mapping file "base/24737/pg_filenode.map" contains invalid data` - LiteLLM DB : `ERROR: invalid page in block 0 of relation base/16385/2838` - Prometheus en `CrashLoopBackOff` : `corrupted block 01KSGFC9WP7STGTXWDNECY2FS0: read symbols: invalid checksum` - Docker registry retournant 500 sur toutes les requêtes : `filesystem: stat ... data: input/output error` - `sacrifice-web` en `ImagePullBackOff` (registry inaccessible) Pattern observé : corruptions récurrentes tous les 3-4 démarrages depuis ~7 semaines. ### Cause racine Disque `sdd` (WDC WD10EALX-009BA0, S/N WD-WCATR9001223) en défaillance progressive : ``` Current_Pending_Sector : 44 ← secteurs illisibles, non réalloués Offline_Uncorrectable : 44 ← secteurs confirmés irrécupérables Power_On_Hours : 52816 ← 6 ans d'utilisation (MTBF constructeur = 5 ans) ``` Historique des self-tests SMART (tous en échec) : ``` #1 Short LBA 1555355176 read failure (nouveau secteur mort) #2 Short LBA 1413976229 read failure #4 Extended LBA 1413976229 read failure (premier secteur mort, découvert il y a ~49 jours) ``` **Mécanisme de corruption silencieuse :** Le RAID dit `[4/4] [UUUU]` et `State: clean` car sdd ne retourne pas d'erreur au moment de l'écriture — son write-back cache (activé) acquitte l'écriture avant de la commettre sur le plateau. La donnée qui tombait sur les secteurs défaillants était silencieusement perdue, la parité RAID5 devenait incohérente avec les données réelles. Le RAID n'en savait rien. À chaque session d'utilisation (~10-12h), les services NFS/k8s écrivaient sur `/srv/data`. Une fraction des writes tombait sur les zones corrompues de sdd et accumulait de la corruption dans les métadonnées ext4 (directory blocks, btree). Au bout de 3-4 sessions, assez de structures critiques étaient corrompues pour faire crasher les services. **Problèmes secondaires identifiés :** - `sda` : `UDMA_CRC_Error_Count = 6` → câble SATA défaillant ou port SATA instable - `sdb` : `Start_Stop_Count = 17780` pour 8847h → spin-down APM trop agressif (~49 cycles/jour) - Tous les disques : write-back cache activé sans onduleur → risque de corruption sur coupure de courant ### Résolution — corruptions de données **Qdrant :** collection `funk-docs` supprimée et réingérée. ```bash sudo systemctl stop qdrant sudo rm -rf /srv/data/qdrant/storage/collections/funk-docs sudo systemctl start qdrant rag-ingest # → 308 chunks réindexés ``` **PostgreSQL — bases grafana et litellm :** ```bash sudo systemctl stop litellm sudo -u postgres psql -c "DROP DATABASE litellm;" sudo -u postgres psql -c "CREATE DATABASE litellm OWNER litellm;" sudo -u postgres psql -c "DROP DATABASE grafana;" sudo -u postgres psql -c "CREATE DATABASE grafana OWNER grafana;" sudo systemctl start litellm kubectl rollout restart deployment/kube-prometheus-stack-grafana -n monitoring # → Grafana rejoue 709 migrations, recrée le schéma ``` **Prometheus TSDB :** deux blocs corrompus supprimés du NFS. ```bash PROM_NFS="/srv/data/nfs/k8s/monitoring-prometheus-...-pvc-aa1a187f-.../prometheus-db" sudo rm -rf "$PROM_NFS/01KSGF0DXNXJ4HC5CEZX9THT5B" sudo rm -rf "$PROM_NFS/01KSGFC9WP7STGTXWDNECY2FS0" kubectl delete pod prometheus-kube-prometheus-stack-prometheus-0 -n monitoring ``` **Docker registry :** PVC corrompu recréé (NFS provisioner génère un répertoire propre). ```bash kubectl scale deployment registry -n infra --replicas=0 kubectl delete pvc registry-pvc -n infra kubectl delete pv pvc-c5e1e86e-da56-4b31-bf52-07d5d619c9ea # Recréer la PVC — le NFS provisioner provisionne un nouveau répertoire kubectl apply -f - < Lors du `sudo rm -rf`, ne pas rester dans le répertoire supprimé — le shell perd le CWD et le script d'installation échoue avec `getcwd: cannot access parent directories`. **Résultat** : hermes-agent réinstallé dans `/opt/hermes/.hermes/hermes-agent/` (SSD OS, plus de RAID5). Tous les profils (`funk-ai`, `brain`, `system`, `monitor`) intacts dans `/srv/data/hermes/profiles/`. ### Changement d'architecture post-incident | Avant | Après | |---|---| | Code hermes-agent : `/srv/data/hermes/hermes-agent/` (RAID5) | Code hermes-agent : `/opt/hermes/.hermes/hermes-agent/` (SSD OS) | | Venv : `/srv/data/hermes/hermes-agent/venv/` | Venv : `/opt/hermes/.hermes/hermes-agent/venv/` | | Profils/données : `/srv/data/hermes/` | Profils/données : `/srv/data/hermes/` (inchangé) | Le code étant désormais sur le SSD, une corruption future du RAID5 n'impactera plus l'installation — seulement les profils et données. ### Surveillance post-incident ```bash # Santé RAID et disques cat /proc/mdstat smartctl -H /dev/sdb # à surveiller # Vérifier que e2fsck n'a pas schedulé un check au prochain boot sudo tune2fs -l /dev/md0 | grep -E "check|count|error" ``` --- ## 2026-05-11 — storage-01 : boucle fsck après coupure de courant ### Symptômes - Boucle infinie de `fsck` au démarrage sur `/dev/md0` - `You are in emergency mode. Give root password for maintenance` — mot de passe impossible à saisir (messages défilants) - Après résolution : `hermes-agent` en boucle d'erreurs (cause : `/srv/data` non monté) ### Architecture concernée | Composant | Détail | |---|---| | Disque système | NVMe `nvme0n1` — LVM (`almalinux-root` XFS 70G, swap 14.7G, home 845G) | | RAID données | RAID5 software `md0` — 4 disques SATA 931.5G (`sda1`, `sdb2`, `sdc1`, `sdd1`) | | Point de montage | `/srv/data` (ext4) | ### Cause racine La coupure de courant a corrompu le système de fichiers **XFS** sur `almalinux-root`. Au redémarrage, systemd tentait de vérifier `/srv/data` avant que le RAID `md0` soit assemblé → boucle bloquante. ### Résolution étape par étape **1. Shell de secours via GRUB** Au démarrage, appuyer sur `Shift` pour afficher le menu GRUB. Appuyer sur `e` pour éditer la ligne `linux` : - Remplacer `ro` par `rw` - Ajouter `init=/bin/bash` en fin de ligne Démarrer avec `Ctrl+X`. **2. Activer le LVM** ```bash lvm vgchange -ay # 3 logical volume(s) in volume group "almalinux" now active ``` **3. Réparer le XFS (pas fsck)** XFS nécessite `xfs_repair`, pas `fsck` : ```bash umount /dev/mapper/almalinux-root xfs_repair /dev/mapper/almalinux-root # Phases 1 à 7 — succès ``` **4. Désactiver temporairement `/srv/data` dans fstab** ```bash vi /etc/fstab # Commenter la ligne /srv/data pour permettre le boot sans RAID ``` **5. Reboot** → système normal, RAID intact `[4/4] [UUUU]`. ### Fix permanent — fstab Modifier la ligne `/srv/data` dans `/etc/fstab` : ``` # Avant UUID=3add8360-fa01-47eb-0aa1-0e84bacbbc15 /srv/data ext4 defaults,noatime,nodiratime 0 2 # Après UUID=3add8360-fa01-47eb-0aa1-0e84bacbbc15 /srv/data ext4 defaults,noatime,nodiratime,_netdev 0 0 ``` | Changement | Effet | |---|---| | `0 2` → `0 0` | Désactive la vérification fsck automatique au boot | | `_netdev` | Force systemd à attendre que tous les périphériques (RAID) soient prêts avant de monter | ### Surveillance post-incident ```bash # État du RAID cat /proc/mdstat # Santé des disques (sdb a généré des erreurs I/O — à surveiller) smartctl -a /dev/sda smartctl -a /dev/sdb smartctl -a /dev/sdc smartctl -a /dev/sdd # Monter /srv/data manuellement si besoin mount /srv/data # Logs de boot journalctl -xb | grep -i "error\|fail" ``` ### Points d'attention - `sdb` a généré des erreurs I/O pendant l'incident — il est revenu opérationnel mais doit être surveillé régulièrement avec `smartctl`. - Envisager un **onduleur (UPS)** pour prévenir ce type d'incident sur coupure de courant. - Le fix fstab (`_netdev`, `0 0`) est permanent — ne pas revenir aux valeurs précédentes.