docs(incidents): 2026-05-27 — défaillance sdd, corruptions multiples, retrait RAID

Documente l'incident complet :
- Cause racine : sdd défaillant (44 secteurs morts, 6 ans d'utilisation)
  write-back cache masquant les échecs d'écriture → corruption silencieuse
- Corruptions résolues : Qdrant RocksDB, PostgreSQL grafana+litellm,
  Prometheus TSDB, Docker registry, sacrifice-web
- Correctif permanent : sdd retiré du RAID (mdadm.conf + initramfs)
- Actions restantes listées : remplacement sdd, câble sda, APM sdb, UPS, e2fsck

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alkatrazz 2026-05-27 19:43:31 +02:00
parent d39b083342
commit 940234806d

View file

@ -4,6 +4,7 @@
| Date | Composant | Résumé | Sévérité |
|---|---|---|---|
| 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 |
@ -13,6 +14,156 @@
---
## 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 - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry-pvc
namespace: infra
spec:
accessModes: [ReadWriteOnce]
storageClassName: nfs
resources:
requests:
storage: 10Gi
EOF
kubectl scale deployment registry -n infra --replicas=1
```
**sacrifice-web :** image rebuildée et pushée via tunnel SSH.
```bash
# Tunnel SSH pour atteindre le registry depuis le poste perso
ssh -f -N -L 31500:192.168.10.11:31500 storage-01
cd /path/to/Sacrifice/sacrifice-web
podman build -t localhost:31500/sacrifice-web:latest .
podman push localhost:31500/sacrifice-web:latest --tls-verify=false
kubectl rollout restart deployment/sacrifice-web -n sacrifice
```
### Résolution — cause racine (sdd retiré du RAID)
```bash
# Marquer sdd comme défaillant et le retirer
sudo mdadm --manage /dev/md0 --fail /dev/sdd1
sudo mdadm --manage /dev/md0 --remove /dev/sdd1
# → State: clean, degraded [4/3] [UUU_]
# Persister la configuration
sudo mdadm --detail --scan | sudo tee /etc/mdadm.conf
sudo dracut --force # régénérer l'initramfs
```
### État post-incident
| Service | État |
|---|---|
| RAID5 md0 | `[4/3] [UUU_]` — dégradé, **zéro redondance** jusqu'au remplacement de sdd |
| Qdrant | ✅ 308 chunks réindexés |
| PostgreSQL grafana | ✅ Schéma recréé, dashboards reprovisionnés |
| PostgreSQL litellm | ✅ Schéma recréé, config modèles intacte (perte de l'historique spend) |
| Prometheus | ✅ Running — perte des ~2 derniers blocs TSDB (quelques heures de métriques) |
| Docker registry | ✅ PVC propre, image sacrifice-web repushée |
| sacrifice-web | ✅ Running, HTTP 200 |
### Actions requises (non résolues)
- **Remplacer sdd** (1TB+, ex. WD Red ou Seagate IronWolf) et relancer la reconstruction :
```bash
sudo mdadm --manage /dev/md0 --add /dev/sdNEW1
# Reconstruction automatique ~4h, visible dans /proc/mdstat
```
- **Câble SATA sda** : remplacer le câble (UDMA_CRC_Error_Count=6)
- **APM sdb** : désactiver le spin-down (`sudo hdparm -B 254 /dev/sdb`) et persister via udev
- **Onduleur (UPS)** : indispensable — write-back cache activé sur tous les disques
- **e2fsck** : planifier une fenêtre de maintenance pour vérifier les métadonnées ext4 restantes :
```bash
sudo systemctl stop nfs-server qdrant postgresql-16 litellm hermes-agent
sudo umount /srv/data
sudo e2fsck -f /dev/md0
sudo mount /srv/data && sudo systemctl start nfs-server qdrant postgresql-16 litellm hermes-agent
```
---
## 2026-05-14 — Grafana : OOMKilled (limite mémoire trop serrée)
### Symptôme