diff --git a/CLAUDE.md b/CLAUDE.md index 2942d7f..4eb3804 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -54,6 +54,7 @@ Journal de progression : `PROGRESS.md` → `progress/YYYY-MM-DD.md` ### Commandes via Makefile (depuis la racine du repo) ```bash +python3 -m venv .venv # créer le venv (une seule fois, avant make install) make install # pip install + ansible-galaxy (à faire une fois) make ping # vérifier la connectivité vers tous les hôtes make check # dry-run site.yml (storage-01 + gpu-01) @@ -187,7 +188,11 @@ rag-query "hermes profils litellm modèles" --top 3 Scripts installés sur storage-01 : `/usr/local/bin/rag-query`, `/usr/local/bin/rag-ingest` -Après modification de `admin/`, re-déployer via `make apply-storage --tags rag` (exécute `rag-ingest`). Le script `admin/index_knowledge.py` est l'ingesteur Python brut. +Après modification de `admin/`, re-déployer via la commande directe (voir section Ansible) : +```bash +ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags rag +``` +Le script `admin/index_knowledge.py` est l'ingesteur Python brut. ### Hermes Skills — `hermes-skills/` @@ -217,7 +222,8 @@ admin/ ├── infra/ # dnsmasq, nfs, réseau, ssh, email ├── install/ # procédures installation storage-01, gpu-01, k8s ├── k8s/ # argocd, talos, monitoring -└── ops/ # ansible, cluster, système +├── ops/ # ansible, cluster, système +└── incidents.md # historique des incidents matériel/service avec résolutions ``` --- @@ -229,7 +235,10 @@ admin/ - MetalLB pool : `192.168.10.200-230` (IP virtuelles Traefik/services) - DNS wildcard `*.lab.local` via dnsmasq → Traefik -nftables géré par le rôle `gateway` sur storage-01. Modifier `ansible/roles/gateway/templates/nftables.conf.j2` puis `make apply-storage --tags gateway`. +nftables géré par le rôle `gateway` sur storage-01. Modifier `ansible/roles/gateway/templates/nftables.conf.j2` puis : +```bash +ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags gateway +``` --- diff --git a/admin/incidents.md b/admin/incidents.md index 64e7918..003507c 100644 --- a/admin/incidents.md +++ b/admin/incidents.md @@ -4,6 +4,7 @@ | 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 | @@ -14,6 +15,105 @@ --- +## 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 diff --git a/progress/2026-05-29.md b/progress/2026-05-29.md new file mode 100644 index 0000000..c4a650b --- /dev/null +++ b/progress/2026-05-29.md @@ -0,0 +1,95 @@ +# 2026-05-29 — Migration /srv/data RAID → NVMe + +## Résumé + +Migration complète des données de `/srv/data` depuis le RAID5 dégradé vers le LV NVMe (`almalinux-home`). Tous les services opérationnels sur NVMe. + +--- + +## CLAUDE.md — corrections mineures + +Trois corrections appliquées au `CLAUDE.md` du projet : + +1. **Bootstrap venv manquant** : ajout de `python3 -m venv .venv` avant `make install` (le Makefile appelle `.venv/bin/pip` directement, échoue silencieusement sans venv). + +2. **`make apply-storage --tags X` invalide** : GNU make interprète `--tags` comme une cible. Remplacé par les commandes `ansible-playbook` directes dans les sections gateway et RAG. + +3. **`admin/incidents.md`** : ajouté dans la liste des fichiers `admin/`. + +--- + +## Évaluation RAID et décision d'architecture + +Contexte : RAID5 déjà dégradé `[UUU_]` après retrait de sdd (incident 2026-05-27). + +Analyse de l'état des disques restants : +- `sda` : `UDMA_CRC_Error_Count=6` (câble SATA suspect) +- `sdb` : ATA bus errors sous charge I/O (câble/port instable) +- `sdc`, `sdd` : pas d'erreurs notables + +**Décision** : migrer `/srv/data` vers le NVMe plutôt que de maintenir les données sur un RAID avec zéro redondance et deux disques à risque. + +**Plan retenu** : utiliser l'espace libre de `almalinux-home` (LV NVMe, 845 GB, 6 GB utilisés sur 845 GB) — créer `/home/data/` et bind-monter sur `/srv/data`. Zero opération LVM, zero risque sur `/home`. + +--- + +## Migration — déroulé + +### Problème : rsync bloqué sur sdb + +Premier rsync lancé → bloque immédiatement en état `D` (uninterruptible sleep). `dmesg` montre des ATA bus errors sur sdb sous forte I/O. 4 KB copiés en 5 minutes. + +**Résolution** : `mdadm --manage /dev/md0 --fail /dev/sdb2` → RAID lit depuis sda/sdc/sdd uniquement. + +### rsync réussi + +``` +Durée : ~35 secondes +Débit : 205 MB/s +Fichiers : 5106 transférés (31367 vérifiés) +Exit code : 23 (xattr SELinux — non critique) +``` + +Modèles (37 GB, 24 fichiers) : intégrité vérifiée. + +### Corruption Qdrant corrigée + +Un `version.info` de segment RocksDB était corrompu (octets `0.D\0` au lieu de `0.6.0`), copié depuis le RAID pendant la tentative avec sdb actif. Qdrant crashait au démarrage. + +```bash +printf '0.6.0' | sudo tee /srv/data/qdrant/storage/collections/funk-docs/0/segments/784eab54-.../version.info +``` + +### Bascule /srv/data + +```bash +sudo umount /srv/data # RAID démonté +sudo mount --bind /home/data /srv/data +# fstab : UUID RAID5 commenté → /home/data /srv/data none bind 0 0 +``` + +--- + +## État final + +| Service | État | +|---|---| +| postgresql-16 | ✅ active | +| qdrant | ✅ active | +| litellm | ✅ active | +| hermes-agent | ✅ active | +| hermes-dashboard | ✅ active | +| alertmanager-webhook | ✅ active | + +| Stockage | Avant | Après | +|---|---|---| +| `/srv/data` | RAID5 ext4 dégradé | NVMe XFS 801 GB libres | +| RAID5 md0 | monté, `[U_UU]` sdb(F) | démonté, non utilisé | + +--- + +## Prochaines étapes + +- Retirer sdb du RAID (`mdadm --remove /dev/sdb2`) et décider du sort du RAID +- Vérifier câble SATA de sdb (ATA bus error = interface, pas plateau) +- Relancer `rag-ingest` pour vérifier l'intégrité de la collection Qdrant funk-docs