Installation, opération et désinstallation d’un cluster Ceph distribué via
l’opérateur Rook 1.19 (Ceph Tentacle 20.2.1).
Méthode nominale = Ansible (ADR
0049 :
déployer Ceph est une convergence d’état durable → Ansible, comme tout le
reste du socle). Les rôles platform-ceph-cluster / -storageclasses /
-datalake appliquent les manifestes figés de ce dossier (SSA +
force_conflicts sur les CR mutés par Rook), patchent les surcharges de
topologie et gâtent sur la santé réelle (HEALTH_OK + le bon nombre d’OSD
up) :
Sur le banc, c’est bench/lima/run-phases.sh ceph|sc|datalake qui les joue
(et prouve leur idempotence par rejeu, ADR 0052). Les kubectl ci-dessous
restent la référence manuelle : compréhension de la séquence, opération
(capacité, clefs), dépannage (finalizers) et désinstallation — actes de
diagnostic/opération qui ne relèvent pas de la convergence (ADR 0049).
Installation de l’opérateur
Équivalent manuel de platform-ceph-cluster (séquence + gates). Préférer le
playbook bootstrap/ceph-cluster.yaml pour un déploiement reproductible.
Pré-vol matériel/OS (recommandé) — avant de créer le cluster, lancer le
pré-vol Ceph qui vérifie sur chaque nœud de stockage : lvm2 présent (requis
par ceph-volume dès qu’un metadataDevice/block.db est utilisé — sinon
OSD-prepare CrashLoop « binary lvm does not exist »), présence du NVMe
block.db, et nombre de disques data bruts. Il installe lvm2 (idempotent)
et échoue CLAIREMENT si un disque manque, au lieu de laisser le cluster.yaml
échouer tard et obscurément (drift L6) :
Pré-requis critique (rebuild / réinstallation) — avant
kubectl create -f cluster.yaml, vérifier que les 4 nœuds ont bien
/var/lib/rooket leurs disques data effacés. Un reliquat d’un cluster
précédent fait redémarrer les ceph-mon sur un ancien état (fsid divergent)
→ ils refusent de démarrer et le CephCluster reste bloqué. Le wipe est
assuré par
cleanup.sh
(disques) et la réinstallation OS (/var/lib/rook, hébergé sur /var
reformaté — cf.
bootstrap/RUNBOOK.md § Partitionnement). Ne
pas créer le cluster avant d’avoir ≥ 3 hôtes prêts (le quorum mon et le
réplicat ×3 l’exigent).
Fenêtre de terminal
kubectlcreate-fcluster.yaml
S’ajoutent alors des pods pour le FS et le RBD par nœud, des provisioners, les
ceph-mon et ceph-mgr, les crashcollector et les exporter, ainsi qu’un OSD
par disque. Attendre que tous les OSD soient Running :
Environ 4,3 % du stockage est utilisé par des métadonnées sur les disques.
Quand l’inspection est terminée :
Fenêtre de terminal
kubectl-nrook-cephdeletedeploy/rook-ceph-tools
Capacité et dimensionnement (audit P8)
Surveiller le taux de remplissage : un pool Ceph qui approche nearfull (85
% par défaut) dégrade les performances, et full (95 %) bloque les
écritures. Depuis la toolbox :
Fenêtre de terminal
cephdf# %USED par pool + espace brut/dispo
cephosddf# remplissage par OSD (repérer un déséquilibre)
Capacité de ce cluster : 4 nœuds × 12 HDD × 5,5 TiB ≈ 264 TiB brut, soit
~88 TiB utiles en réplicat ×3 (cf.
ADR 0009).
Ajouter de la capacité : remplacer un disque défaillant ou ajouter des HDD
se fait à chaud — useAllDevices: true
(cluster.yaml)
fait détecter et intégrer les nouveaux disques bruts par l’operator (la
découverte automatique étant désactivée, cf. ADR : c’est le redéploiement du
CephCluster qui les prend en compte). Après ajout, Ceph rééquilibre
(backfill) — surveiller ceph status jusqu’au retour HEALTH_OK.
GC du registry : le PVC registry-pvc ne se vide pas tout seul quand on
supprime des tags. Le CronJob de garbage-collection
(garbage-collect-cronjob.yaml)
récupère l’espace ; le déclencher manuellement si le PVC se remplit.
Classes de stockage
rook-ceph-block-replicated est annotée
storageclass.kubernetes.io/is-default-class: "true" — c’est la classe par
défaut du cluster ; les PVC sans storageClassName y atterrissent.
⚠️ EC 2+1 sur 4 hôtes — piège min_size : le min_size par défaut d’un
pool EC k=2, m=1 est k+1 = 3. La perte d’un hôte fait passer le pool
sous min_size et bloque les I/O jusqu’au remplacement, sans perte de
données mais avec interruption. Ces classes restent utiles pour des données
tolérantes (datalake, archives). Pour le critique, utiliser la classe par
défaut rook-ceph-block-replicated (×3, tolère 1 perte sans blocage). Les
pools de métadonnées des classes EC sont désormais en size: 3 +
requireSafeReplicaSize: true (Ceph déconseille fortement size: 2).
⚠️ Comportement destructif : le CephObjectStore est configuré avec
preservePoolsOnDelete: false — supprimer l’objet détruit les pools et
toutes les données S3. Cohérent avec un datalake ré-ingestible. Si les
données doivent survivre à une suppression, basculer à
preservePoolsOnDelete: true avant.
Chiffrement (décision assumée)
Aucun chiffrement Ceph n’est activé : network.connections.encryption.enabled
reste à false dans cluster.yaml, et le datalake RGW expose port: 80 sans
TLS. La décision tient parce que les flux internes au cluster restent confinés
au réseau privé 10.0.0.0/22, et que l’accès externe est limité par le
contrôle d’accès au Service (réseau cluster, ou kubectl port-forward depuis
un poste autorisé à parler à l’API K8s). À revisiter le jour où ces hypothèses
changent (exposition publique, données classifiées, etc.).
Accès distant
L’accès distant aux Services internes (registry, RStudio…) se fait par
kubectl port-forward depuis un poste autorisé à parler à l’API K8s. Aucune
exposition réseau dédiée n’est requise côté cluster.
⚠️ Toujours supprimer les buckets/OBC AVANT le CephObjectStore. Rook
protège les données : il refuse de supprimer un object store tant qu’il reste
des ObjectBucketClaim/buckets. Si on supprime le store en premier, le RGW
part en suppression et l’OBC ne peut plus se deprovisionner → deadlock
mutuel de finalizers (les deux objets restent en Deleting indéfiniment ;
l’operator répète « will not be deleted until all dependents are removed »).
Ordre correct :
Fenêtre de terminal
# 1. Supprimer les OBC (chaque OBC vide puis retire son bucket S3).
kubectl-nrook-cephdeleteobc--all# ou bucket par bucket
# 2. Supprimer le CephObjectStoreUser éventuel.
kubectl-nrook-cephdeletecephobjectstoreuser--all
# 3. Attendre qu'il ne reste plus aucun bucket côté RGW.
Supprimer les StorageClasses et les CephBlockPoolréellement créés par la
section « Bloc » ci-dessus (réplicat ×3 + les deux variantes EC). Le delete
d’une ressource inexistante renvoie NotFound sans rien casser.
Adapter si seul un sous-ensemble a été appliqué. La SC objet
rook-ceph-datalake se retire séparément (cf. § Object store ci-dessus). Les
ressources rook-ceph-block / rook-ceph-block-pool du dossier
storageClass/examples/
ne sont pas créées par ce RUNBOOK (réplicat ×1, démonstration uniquement).