ajoute une démo Ceph mono-serveur (bloc C, premier chantier)

Cluster cephadm minimal (1 mon, 1 mgr, 1 OSD sur fichier épars),
vérifié par une vraie écriture/lecture d'objet. Pas branché à
OpenStack (Cinder désactivé sur ce déploiement) : démo de
compréhension avant le vrai cluster au 2e serveur. SSH via adam, pas
root, pour ne pas affaiblir le durcissement SSH de la semaine 1.

Découverte en vérifiant l'état réel avant d'agir : le serveur a 31 Go
de RAM et 230 Go RAID 1, pas 64 Go / 2x500 Go comme écrit dans le
CLAUDE.md — noté en dette, démo faite quand même sous surveillance de
la RAM après accord d'Adam.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-14 12:20:48 +02:00
parent 6ea7a1cc16
commit cdf79d2823
5 changed files with 212 additions and 0 deletions

View file

@ -0,0 +1,89 @@
# ADR 0007 — Ceph : démo mono-serveur avec cephadm, image Reef, OSD en mode raw
- **Date** : 2026-10-14
- **Statut** : accepté
## Contexte
Bloc C du CLAUDE.md : « Ceph comme stockage d'OpenStack (Glance, Cinder) :
démo mono-serveur d'abord, vrai cluster au 2ᵉ serveur. » Avant de commencer,
vérification de l'état réel du serveur (`free -h`, `lsblk`) : **31 Go de RAM
réels, pas 64 Go** comme décrit dans le CLAUDE.md, dont 400-800 Mo
« libres » mais ~6-7 Go « disponibles » (`available`, ce qui compte vraiment :
mémoire + cache récupérable) au moment du chantier. Décision d'Adam
(2026-10-14, après avoir vu ces chiffres) : démo quand même, a minima (1 mon,
1 mgr, 1 OSD, sans pile de supervision intégrée), sous surveillance de la RAM
à chaque étape.
`enable_cinder: "no"` dans `/etc/kolla/globals.yml` : Cinder n'est pas
activé sur ce déploiement, donc cette démo Ceph n'a aucune interaction avec
OpenStack pour l'instant — elle est entièrement isolée.
## Décisions et pourquoi
**`cephadm`, pas une installation manuelle des paquets `ceph-mon`/`ceph-osd`.**
C'est l'outil de déploiement officiel et le plus proche de ce qu'opère une
équipe SRE en production (conteneurs gérés, upgrade orchestré). Installé
depuis les dépôts Debian (paquet `cephadm`), pas par `curl | bash` (même
leçon que NodeSource, voir `docs/dette.md`).
**`--ssh-user adam`, pas root.** cephadm gère même l'hôte local par SSH (son
modèle d'orchestrateur), avec `root` par défaut. Notre durcissement SSH de la
semaine 1 interdit `PermitRootLogin` (`/etc/ssh/sshd_config.d/99-durcissement.conf`).
Plutôt que d'affaiblir cette règle pour un chantier de démo, cephadm utilise
le compte `adam` (déjà en sudo sans mot de passe, déjà seul compte autorisé
en SSH) : aucune modification de la configuration SSH.
**Image `quay.io/ceph/ceph:v18` (Reef), pas la `v16` (Pacific) par défaut
du paquet Debian 12.** `ceph-volume lvm batch` (le code qui prépare un
disque pour un OSD) plante avec une erreur interne (`IndexError:
list index out of range`, bug de classification des périphériques loop)
sur Pacific **et** sur Reef — le changement de version n'a donc pas corrigé
ce bug précis, mais Reef reste la version utilisée (plus récente, mieux
suivie) pour tout le reste. Il a fallu ajouter le dépôt APT officiel Ceph
Reef (clé GPG vérifiée, `download.ceph.com/debian-reef`) car `cephadm`
refuse de piloter une image d'une version différente de la sienne
(`Container release reef != cephadm release pacific`).
**OSD en mode `raw`, pas `lvm` (défaut).** La vraie cause du plantage :
`ceph-volume` classe à tort un périphérique loop comme « déjà LVM » puis
plante en cherchant un volume logique qui n'existe pas. Contournement
trouvé : `ceph orch daemon add osd <hôte>:<périphérique> raw` (syntaxe à
deux arguments séparés, pas `device,method=raw` qui est refusé). Le mode
`raw` ne construit pas de volume logique par-dessus le périphérique — il
évite entièrement le code de classification fautif.
**Périphérique loop sur un fichier épars (20 Go), pas un disque dédié.**
Les deux disques du serveur sont entièrement pris par le RAID 1 `/` — aucun
disque ni partition libre pour un vrai OSD. `/var/lib/ceph-osd-demo/osd0.img`
(`fallocate`, 20 Go, espace alloué à l'usage réel seulement) monté en
`/dev/loop0`. Rendu permanent par un service systemd dédié
(`infra/ceph/ceph-osd-demo-loop.service`, réattache le fichier au démarrage,
avant que Ceph ne cherche son disque). Pas destiné à durer : le « vrai
cluster » du CLAUDE.md, avec de vrais disques, arrivera au 2ᵉ serveur.
**`osd_pool_default_size`/`min_size` à 1.** Avec un seul OSD, aucune
réplication n'est possible. Valeur acceptée uniquement parce que c'est une
démo sans donnée réelle — jamais à reproduire pour un usage réel.
**Pile de supervision Ceph (Prometheus/Grafana/Alertmanager intégrés à
cephadm) désactivée (`--skip-monitoring-stack`), pas de tableau de bord
(`--skip-dashboard`).** Pour limiter l'empreinte mémoire ; Paillasse a déjà
son propre Prometheus/Grafana (CX23, hors de ce serveur) — un exporter Ceph
pourrait y être ajouté plus tard si le besoin de supervision réel se
confirme.
## Conséquences
- Cluster à 1 mon, 1 mgr (+ 1 mgr standby), 1 OSD, fonctionnel, vérifié par
une vraie écriture/lecture d'objet (`rados put`/`rados get`, contenu
identique). Aucune intégration avec Glance/Cinder (Cinder est désactivé).
- RAM disponible restée stable (~6-7 Go) pendant tout le chantier — pas
d'incident, mais marge réelle plus faible que ce que suppose le CLAUDE.md.
Voir `docs/dette.md`.
- Pas de rejouabilité Ansible pour l'instant (bootstrap fait à la main, comme
celui de Kolla à l'étape 2) : à écrire si cette démo doit durer au-delà de
l'évaluation du bloc C.
- Risque pour la suite : ajouter des daemons Ceph supplémentaires (plus
d'OSD, dashboard, supervision) sur ce même serveur réduira encore la marge
mémoire déjà tendue. Le « vrai cluster » attendra le 2ᵉ serveur.

View file

@ -36,3 +36,6 @@ retirer la ligne (et le noter dans le journal) quand c'est fait.
| « Mes cours » : un seul lab (08) a un vrai cours.md | Les séquences 01 à 07 n'ont pas de cours rédigé (Adam écrit ce contenu lui-même, voir la banque de quiz). La page reste honnête : vide pour un élève qui n'a pratiqué que ces labs, jamais de contenu inventé pour combler. | Quand Adam rédige les cours | 2026-10-14 | | « Mes cours » : un seul lab (08) a un vrai cours.md | Les séquences 01 à 07 n'ont pas de cours rédigé (Adam écrit ce contenu lui-même, voir la banque de quiz). La page reste honnête : vide pour un élève qui n'a pratiqué que ces labs, jamais de contenu inventé pour combler. | Quand Adam rédige les cours | 2026-10-14 |
| « Mes notes » : pas de notion de compétence pour les devoirs maison (seulement pour les labs, via `labs.competences`) | Un devoir maison n'est lié à aucune compétence du référentiel ; ses notes sortent sous « Sans compétence associée ». Ajouter un champ compétence(s) sur `Devoir` si besoin. | Si ça gêne en usage réel | 2026-10-14 | | « Mes notes » : pas de notion de compétence pour les devoirs maison (seulement pour les labs, via `labs.competences`) | Un devoir maison n'est lié à aucune compétence du référentiel ; ses notes sortent sous « Sans compétence associée ». Ajouter un champ compétence(s) sur `Devoir` si besoin. | Si ça gêne en usage réel | 2026-10-14 |
| Stockage S3 des devoirs maison : bucket Hetzner Object Storage pas encore créé | Code déployé et vérifié (`Storage::fake('s3')` en test, `disponible() === false` confirmé en réel) mais jamais exercé contre un vrai bucket — pas à Claude de le créer (CLAUDE.md, commandes et dépenses). Le dépôt de fichier reste masqué côté élève jusque-là, texte libre toujours disponible. Marche à suivre : `docs/runbooks/stockage-s3.md`. | Quand Adam crée le bucket | 2026-10-14 | | Stockage S3 des devoirs maison : bucket Hetzner Object Storage pas encore créé | Code déployé et vérifié (`Storage::fake('s3')` en test, `disponible() === false` confirmé en réel) mais jamais exercé contre un vrai bucket — pas à Claude de le créer (CLAUDE.md, commandes et dépenses). Le dépôt de fichier reste masqué côté élève jusque-là, texte libre toujours disponible. Marche à suivre : `docs/runbooks/stockage-s3.md`. | Quand Adam crée le bucket | 2026-10-14 |
| **Serveur réel : 31 Go de RAM et 230 Go RAID 1, pas 64 Go / 2×500 Go comme écrit dans le CLAUDE.md (section 3)** | Constaté en vérifiant l'état réel avant la démo Ceph (`free -h`, `lsblk`). Change la vraie marge de capacité (hot pool + OpenStack + portail + tout chantier futur) : à corriger dans le CLAUDE.md, ou à traiter avec une vraie mise à niveau matérielle si le pilote (semaine 8) montre que ça manque. | Avant le pilote si la capacité manque | 2026-10-14 |
| Ceph : démo mono-serveur seulement (1 OSD sur fichier épars, pas de réplication, pas branché à Cinder/Glance) | `ceph_pool_default_size=1` et un seul OSD acceptés uniquement parce que c'est une démo de compréhension, sans donnée réelle. Le vrai cluster (plusieurs OSD, réplication, intégré à Cinder) attend le 2ᵉ serveur du CLAUDE.md. Voir [ADR 0007](adr/0007-ceph-demo-mono-serveur.md). | 2ᵉ serveur (bloc C) | 2026-10-14 |
| Ceph : bootstrap fait à la main, pas encore rejouable par Ansible | Comme Kolla à l'étape 2 : acceptable pour une démo, à automatiser si ce cluster doit durer. Le fichier systemd du loop device est suivi dans `infra/ceph/` mais déployé à la main. | Si la démo devient durable | 2026-10-14 |

View file

@ -1175,3 +1175,27 @@ Le dernier bug (suppression accidentelle d'un fichier conservé) est le genre d'
**Suite** **Suite**
Le bloc B du CLAUDE.md est maintenant complet (API publique, cache Redis, optimisation MariaDB, stockage S3). La suite reste au choix d'Adam : créer le bucket S3 (runbook ci-dessus), avancer sur le bloc C, ou organiser le pilote de la semaine 8 du bloc A. Le bloc B du CLAUDE.md est maintenant complet (API publique, cache Redis, optimisation MariaDB, stockage S3). La suite reste au choix d'Adam : créer le bucket S3 (runbook ci-dessus), avancer sur le bloc C, ou organiser le pilote de la semaine 8 du bloc A.
## 2026-10-14 — Ceph, démo mono-serveur (bloc C)
Premier chantier du bloc C : comprendre et opérer Ceph, en démo sur le serveur actuel avant le vrai cluster au 2ᵉ serveur (CLAUDE.md).
**Découverte avant de commencer**
En vérifiant l'état réel du serveur avant de toucher au stockage (réflexe de prudence, pas une étape prévue) : **31 Go de RAM réels et 230 Go en RAID 1, pas 64 Go / 2×500 Go** comme écrit dans le CLAUDE.md — et seulement ~580 Mo « libres » au sens strict, bien que ~6-7 Go restent « disponibles » (mémoire + cache récupérable, la vraie mesure qui compte). Un seul serveur fait tourner OpenStack (Kolla, MariaDB Galera, Nova/qemu pour les VM d'élèves) et le portail Laravel ensemble, pas deux serveurs séparés comme le schéma d'architecture le suggère. Remonté à Adam avant d'installer quoi que ce soit (Ceph consomme facilement 2-3 Go pour mon+mgr+OSD) ; décision d'Adam : démo quand même, a minima, sous surveillance de la RAM à chaque étape — faite sans incident, la RAM « disponible » est restée stable entre 6 et 7 Go du début à la fin.
**Fait**
- `cephadm` installé depuis les dépôts Debian (pas de `curl | bash`), cluster amorcé avec `--ssh-user adam` (notre durcissement SSH interdit le login root, y compris pour cephadm qui veut gérer même l'hôte local par SSH), sans dashboard ni pile de supervision intégrée (économie de RAM, Grafana/Prometheus existent déjà côté CX23).
- Bug trouvé et contourné : `ceph-volume lvm batch` plante (`IndexError`) sur un périphérique loop, classé à tort comme « déjà LVM » — reproduit à l'identique sur Pacific (image par défaut du paquet Debian) et sur Reef (après avoir ajouté le dépôt APT officiel Ceph pour avoir un `cephadm` de version assortie). La vraie cause n'était pas la version mais le *mode* : `ceph orch daemon add osd <hôte>:<périphérique> raw` (mode brut, sans LVM par-dessus, en argument séparé — la syntaxe `périphérique,method=raw` est refusée) évite entièrement le code de classification fautif.
- 1 OSD de 20 Go sur un fichier épars (`/var/lib/ceph-osd-demo/osd0.img`, aucun disque libre sur ce serveur), rendu permanent au redémarrage par un service systemd dédié (suivi dans `infra/ceph/`).
- Vérifié avec de vraies données : écriture et relecture d'un objet (`rados put`/`get`), contenu identique, pool de test ensuite supprimé. Cluster laissé dans l'état `HEALTH_WARN` attendu (1 seul OSD, pas de réplication possible) — pas une alerte à traiter.
- Détail complet des choix et contournements : [ADR 0007](adr/0007-ceph-demo-mono-serveur.md), procédures : `docs/runbooks/ceph.md`.
**Comprendre**
Deux leçons distinctes : d'abord, ne jamais faire confiance à la documentation d'architecture sans vérifier l'état réel avant une action qui consomme des ressources critiques — le CLAUDE.md décrivait un serveur deux fois plus gros que la réalité, et je ne l'aurais pas su sans lancer `free -h`/`lsblk` par réflexe avant Ceph plutôt qu'après un incident. Ensuite, un contournement de bug peut avoir l'air d'être « la mauvaise version du logiciel » alors que c'est autre chose : changer d'image Ceph (Pacific → Reef) n'a rien résolu, parce que le vrai problème était le choix entre deux modes de création d'OSD (`lvm` vs `raw`), pas la version — la bonne piste est venue de relire l'aide de la commande (`ceph orch daemon add osd --help`) plutôt que de continuer à changer des variables au hasard.
**Suite**
Prochain chantier du bloc C, annoncé par Adam : WebDAV, puis ElasticSearch.

82
docs/runbooks/ceph.md Normal file
View file

@ -0,0 +1,82 @@
# Runbook — Ceph (démo mono-serveur)
Démo du bloc C du CLAUDE.md : comprendre et savoir opérer Ceph, avant le
« vrai cluster » prévu au 2ᵉ serveur. **Pas branché à OpenStack** (Cinder est
désactivé sur ce déploiement — `enable_cinder: "no"`), pas de réplication (1
seul OSD), pas de stockage réel de l'application. Voir
[ADR 0007](../adr/0007-ceph-demo-mono-serveur.md) pour le détail des choix et
des contournements de bugs.
## État attendu
| Composant | Attendu |
|---|---|
| mon | 1, `sd-124443` |
| mgr | 1 actif + 1 standby |
| osd | 1, up et in, mode `raw` sur `/dev/loop0` |
| Pools | 0 en temps normal (démo seulement, rien de permanent stocké) |
```
sudo /usr/sbin/cephadm shell -- ceph -s
```
`HEALTH_WARN` est normal et attendu (1 seul OSD < taille de réplication par
défaut) — pas une alerte à traiter.
## Où sont les choses
- Config et clés : `/etc/ceph/ceph.conf`, `/etc/ceph/ceph.client.admin.keyring`.
- Fichier épars de l'OSD (20 Go, alloué à l'usage réel) : `/var/lib/ceph-osd-demo/osd0.img`.
- Service qui réattache ce fichier en `/dev/loop0` au démarrage : `/etc/systemd/system/ceph-osd-demo-loop.service` (copie suivie dans le dépôt : `infra/ceph/ceph-osd-demo-loop.service`, pas encore déployé par Ansible).
- cephadm gère les daemons comme des conteneurs podman (`sudo podman ps`), pas docker (utilisé par Kolla et le portail) — deux runtimes de conteneurs coexistent sur ce serveur, sans conflit.
## Commandes utiles
```
# Santé du cluster
sudo /usr/sbin/cephadm shell -- ceph -s
# Lister les daemons
sudo /usr/sbin/cephadm ls
# RAM : à surveiller avant/après toute action Ceph (colonne "available",
# pas "free" — c'est elle qui compte vraiment)
free -h
```
## Pourquoi RAM et disque sont serrés
Le serveur a réellement **31 Go de RAM** et **230 Go en RAID 1** (pas 64 Go /
2×500 Go comme décrit dans le CLAUDE.md — à corriger si une vraie mise à
jour matérielle est faite). OpenStack (Kolla, MariaDB Galera, Nova/qemu) et
le portail Laravel tournent déjà sur cette même machine. Avant d'ajouter
quoi que ce soit à ce cluster (dashboard, supervision, un 2ᵉ OSD), vérifier
`free -h` : viser au moins 2 Go « disponibles » de marge.
## Nettoyer entièrement la démo (si besoin de récupérer la RAM/le disque)
```
ssh paillasse
sudo /usr/sbin/cephadm ls # récupérer le fsid
sudo /usr/sbin/cephadm rm-cluster --fsid <fsid> --force
sudo losetup -d /dev/loop0
sudo systemctl disable --now ceph-osd-demo-loop.service
sudo rm /etc/systemd/system/ceph-osd-demo-loop.service
sudo rm -rf /var/lib/ceph-osd-demo
sudo rm /etc/apt/sources.list.d/ceph.list /usr/share/keyrings/ceph.gpg
sudo apt-get update
```
## Écueils rencontrés (pour ne pas les redécouvrir)
- **`ceph orch daemon add osd <hôte>:<périphérique>` plante** sur un
périphérique loop (`IndexError`, bug de classification de `ceph-volume`,
reproduit sur Pacific et Reef). Contournement : ajouter `raw` en second
argument séparé : `ceph orch daemon add osd <hôte>:<périphérique> raw`
(la syntaxe `périphérique,method=raw` est refusée par la CLI).
- **cephadm veut du SSH root** même pour gérer l'hôte local — incompatible
avec `PermitRootLogin no`. Toujours bootstrapper avec `--ssh-user adam`.
- **Mélanger une image Ceph et un `cephadm` de version différente échoue**
(`Container release reef != cephadm release pacific`) : installer le
`cephadm` du dépôt officiel de la même version que l'image voulue, pas
forcer avec `--allow-mismatched-release`.

View file

@ -0,0 +1,14 @@
[Unit]
Description=Attache le fichier épars de l'OSD Ceph de démo sur /dev/loop0
DefaultDependencies=no
Before=ceph.target local-fs.target
After=systemd-udevd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/losetup /dev/loop0 /var/lib/ceph-osd-demo/osd0.img
ExecStop=/sbin/losetup -d /dev/loop0
[Install]
WantedBy=local-fs.target