🐙 Ceph + Kubernetes — Guide d'Intégration StorageClass
RBD Block Storage (RWO) | CephFS Filesystem (RWO/RWX) | Production Ready
📋 Informations du Cluster
| Paramètre | Valeur |
|-----------|--------|
| Cluster ID | d08e3e42-115e-11f0-a5ad-005056b31542 |
| MON 1 | 192.168.1.231:6789 (INFRA-CEPH-01) |
| MON 2 | 192.168.1.232:6789 (INFRA-CEPH-02) |
| MON 3 | 192.168.1.233:6789 (INFRA-CEPH-03) |
| Ceph Version | 16.2.15 Pacific (stable) |
| OSD | 9 OSDs : 9 up, 9 in — 279 GiB total |
| MDS | myfs (actif) + prd-k8s-fs (actif) |
🏗️ Architecture
Ceph Cluster ──► Ceph-CSI Driver ──► StorageClass ──► PVC / PV
(192.168.1.231-233) (K8s namespace) (ceph-rbd-prd (Applications)
ceph-filesystem-prd)
PARTIE 1 — RBD Block Storage (RWO)
Ceph RBD (RADOS Block Device) fournit un stockage bloc haute performance. Il supporte uniquement le mode ReadWriteOnce (RWO) — un seul node à la fois. Idéal pour les bases de données, applications stateful.
STEP 1 — Créer le Pool RBD sur Ceph
```bash
Sur INFRA-CEPH-01
Créer le pool dédié K8s
ceph osd pool create prd-k8S 64 64
Initialiser pour RBD
rbd pool init prd-k8S
Vérifier
ceph osd pool ls ```
✅ Résultat : pool 'prd-k8S' created
STEP 2 — Créer l'Utilisateur Ceph pour K8s
```bash ceph auth get-or-create client.prd-k8S \ mon 'profile rbd' \ osd 'profile rbd pool=prd-k8S' \ mgr 'profile rbd pool=prd-k8S'
Récupérer la clé user
ceph auth get-key client.prd-k8S
→ AQBc8a5pqH70DhAAysOtN/D1WV0bF48uhl2nNw==
Récupérer la clé admin
ceph auth get-key client.admin
→ AQAJ6e9nOPc0NRAAJ1fw+KheU/jSxY5s58jy4Q==
Cluster ID
ceph fsid
→ d08e3e42-115e-11f0-a5ad-005056b31542
```
STEP 3 — Installer Ceph-CSI RBD sur Kubernetes
```bash
Ajouter le repo Helm
helm repo add ceph-csi https://ceph.github.io/csi-charts helm repo update
Créer le namespace
kubectl create namespace ceph-csi-rbd ```
Créer le fichier values-ceph-csi.yaml :
```yaml
values-ceph-csi.yaml
csiConfig: - clusterID: "d08e3e42-115e-11f0-a5ad-005056b31542" monitors: - "192.168.1.231:6789" - "192.168.1.232:6789" - "192.168.1.233:6789"
provisioner: replicaCount: 2
storageClass: create: false
secret: create: false ```
```bash
Installer
helm install ceph-csi-rbd ceph-csi/ceph-csi-rbd \ --namespace ceph-csi-rbd \ --values values-ceph-csi.yaml
Vérifier tous les pods Running
kubectl get pods -n ceph-csi-rbd -w ```
STEP 4 — Créer le Secret Kubernetes pour RBD
```yaml
ceph-secret.yaml
apiVersion: v1 kind: Secret metadata: name: csi-rbd-secret-prd namespace: ceph-csi-rbd stringData: userID: prd-k8S userKey: AQBc8a5pqH70DhAAysOtN/D1WV0bF48uhl2nNw== ```
bash
kubectl apply -f ceph-secret.yaml
kubectl get secret -n ceph-csi-rbd
STEP 5 — Créer la StorageClass RBD
```yaml
storageclass-ceph-rbd.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ceph-rbd-prd annotations: storageclass.kubernetes.io/is-default-class: "false" provisioner: rbd.csi.ceph.com parameters: clusterID: "d08e3e42-115e-11f0-a5ad-005056b31542" pool: prd-k8S imageFormat: "2" imageFeatures: layering csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret-prd csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret-prd csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret-prd csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd reclaimPolicy: Delete allowVolumeExpansion: true mountOptions: - discard ```
bash
kubectl apply -f storageclass-ceph-rbd.yaml
kubectl get storageclass
STEP 6 — Tester avec un PVC RWO
```yaml
test-pvc-prd.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc-ceph-prd namespace: default spec: accessModes: - ReadWriteOnce storageClassName: ceph-rbd-prd resources: requests: storage: 1Gi ```
```bash kubectl apply -f test-pvc-prd.yaml
Doit passer Pending → Bound en ~10s
kubectl get pvc test-pvc-ceph-prd -w ```
✅ Résultat confirmé :
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS
test-pvc-ceph-prd Bound pvc-dfc90a02-dee5-474a-a33b-f013436327a6 1Gi RWO ceph-rbd-prd
PARTIE 2 — CephFS Filesystem (RWO + RWX)
CephFS est un système de fichiers distribué qui supporte à la fois ReadWriteOnce (RWO) et ReadWriteMany (RWX). Idéal pour les fichiers partagés, logs, media, configurations.
STEP 1 — Créer les Pools et le Filesystem dédié K8s
```bash
Sur INFRA-CEPH-01
Créer le pool metadata
ceph osd pool create prd-k8s-cephfs-meta 32 32
Créer le pool data
ceph osd pool create prd-k8s-cephfs-data 64 64
Créer le nouveau filesystem
ceph fs new prd-k8s-fs prd-k8s-cephfs-meta prd-k8s-cephfs-data
Vérifier
ceph fs ls ```
✅ Résultat :
name: myfs, metadata pool: cephfs.myfs.meta, data pools: [cephfs.myfs.data]
name: prd-k8s-fs, metadata pool: prd-k8s-cephfs-meta, data pools: [prd-k8s-cephfs-data]
STEP 2 — Déployer les Daemons MDS pour prd-k8s-fs
⚠️ CRITIQUE : Sans MDS actif, le provisioning CephFS échoue avec
DeadlineExceeded.
```bash
Vérifier l'état MDS avant déploiement
ceph mds stat
Résultat initial : prd-k8s-fs:0 ← PROBLÈME, 0 MDS actif
Déployer les MDS
ceph orch apply mds prd-k8s-fs \ --placement="2 INFRA-CEPH-01 INFRA-CEPH-02 INFRA-CEPH-03"
Attendre ~30 secondes puis vérifier
watch ceph mds stat
Résultat attendu :
prd-k8s-fs:1 {prd-k8s-fs:0=prd-k8s-fs.INFRA-CEPH-02.xxx=up:active}
Vérifier le filesystem
ceph fs status prd-k8s-fs ```
✅ Résultat attendu :
RANK STATE MDS
0 active prd-k8s-fs.INFRA-CEPH-02.wdkqor
STANDBY MDS
prd-k8s-fs.INFRA-CEPH-03.prrhcl
STEP 3 — Créer le Subvolume Group 'csi'
⚠️ REQUIS : Sans ce groupe, le provisioner échoue avec
subvolume group 'csi' does not exist.
```bash
Créer le subvolume group pour ceph-csi
ceph fs subvolumegroup create prd-k8s-fs csi
Vérifier
ceph fs subvolumegroup ls prd-k8s-fs
Résultat : [{"name": "csi"}]
```
STEP 4 — Créer l'Utilisateur CephFS
```bash ceph auth get-or-create client.prd-k8s-cephfs \ mon 'allow r' \ mds 'allow rw fsname=prd-k8s-fs' \ osd 'allow rw pool=prd-k8s-cephfs-data, allow rw pool=prd-k8s-cephfs-meta' \ mgr 'allow rw'
Récupérer la clé
ceph auth get-key client.prd-k8s-cephfs
→ AQDX9K5pTNIYFhAAFg5FsWot0FEaI+kh0SAapw==
```
STEP 5 — Installer Ceph-CSI CephFS sur Kubernetes
⚠️ Important : Utiliser le port
8082pour éviter le conflit avec RBD qui occupe le8081.
```bash
Créer le namespace
kubectl create namespace ceph-csi-cephfs
Installer avec port 8082
helm install ceph-csi-cephfs ceph-csi/ceph-csi-cephfs \ --namespace ceph-csi-cephfs \ --set csiConfig[0].clusterID="d08e3e42-115e-11f0-a5ad-005056b31542" \ --set csiConfig[0].monitors[0]="192.168.1.231:6789" \ --set csiConfig[0].monitors[1]="192.168.1.232:6789" \ --set csiConfig[0].monitors[2]="192.168.1.233:6789" \ --set nodeplugin.httpMetrics.containerPort=8082
Vérifier tous les pods 3/3 Running
kubectl get pods -n ceph-csi-cephfs -w ```
✅ Résultat attendu :
NAME READY STATUS RESTARTS
ceph-csi-cephfs-nodeplugin-4jdl9 3/3 Running 0
ceph-csi-cephfs-nodeplugin-7fp2f 3/3 Running 0
ceph-csi-cephfs-nodeplugin-dk2ss 3/3 Running 0
ceph-csi-cephfs-provisioner-79d7bb699d-cnpn9 6/6 Running 0
ceph-csi-cephfs-provisioner-79d7bb699d-xbzrb 6/6 Running 0
ceph-csi-cephfs-provisioner-79d7bb699d-zwxkl 6/6 Running 0
STEP 6 — Créer le Secret Kubernetes pour CephFS
```yaml
cephfs-secret-prd.yaml
apiVersion: v1 kind: Secret metadata: name: csi-cephfs-secret-prd namespace: ceph-csi-cephfs stringData: userID: prd-k8s-cephfs userKey: AQDX9K5pTNIYFhAAFg5FsWot0FEaI+kh0SAapw== adminID: admin adminKey: AQAJ6e9nOPc0NRAAJ1fw+KheU/jSxY5s58jy4Q== ```
bash
kubectl apply -f cephfs-secret-prd.yaml
kubectl get secret -n ceph-csi-cephfs
STEP 7 — Créer la StorageClass CephFS
```yaml
storageclass-cephfs-prd.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ceph-filesystem-prd provisioner: cephfs.csi.ceph.com parameters: clusterID: "d08e3e42-115e-11f0-a5ad-005056b31542" fsName: prd-k8s-fs pool: prd-k8s-cephfs-data csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret-prd csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret-prd csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret-prd csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs reclaimPolicy: Delete allowVolumeExpansion: true ```
bash
kubectl apply -f storageclass-cephfs-prd.yaml
kubectl get storageclass
STEP 8 — Tester PVC RWO et RWX
```yaml
test-pvc-cephfs-rwo.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-cephfs-rwo namespace: default spec: accessModes: - ReadWriteOnce # RWO sur CephFS storageClassName: ceph-filesystem-prd resources: requests: storage: 2Gi ```
```yaml
test-pvc-cephfs-rwx.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-cephfs-rwx namespace: default spec: accessModes: - ReadWriteMany # RWX sur CephFS storageClassName: ceph-filesystem-prd resources: requests: storage: 2Gi ```
```bash kubectl apply -f test-pvc-cephfs-rwo.yaml kubectl apply -f test-pvc-cephfs-rwx.yaml
Vérifier les 2 → doivent être Bound
kubectl get pvc | grep cephfs ```
✅ Résultat attendu :
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS
test-cephfs-rwo Bound pvc-xxx... 2Gi RWO ceph-filesystem-prd
test-cephfs-rwx Bound pvc-yyy... 2Gi RWX ceph-filesystem-prd
PARTIE 3 — Troubleshooting & Commandes Utiles
Erreurs Rencontrées et Solutions
| Erreur | Cause | Solution |
|--------|-------|----------|
| Port 8081 already in use | RBD occupe le port 8081 | CephFS → port 8082 via helm upgrade |
| DeadlineExceeded | MDS non actif pour prd-k8s-fs | ceph orch apply mds prd-k8s-fs |
| subvolume group 'csi' does not exist | Groupe manquant dans CephFS | ceph fs subvolumegroup create prd-k8s-fs csi |
| operation already exists | PVC bloqué en cache provisioner | kubectl delete pvc + rollout restart provisioner |
Fix — Conflit Port 8081 (CrashLoopBackOff nodeplugin)
```bash
Symptôme
kubectl logs pod/ceph-csi-cephfs-nodeplugin-xxx -n ceph-csi-cephfs -c liveness-prometheus
→ failed to listen on address 10.200.5.3:8081: bind: address already in use
Solution
helm upgrade ceph-csi-cephfs ceph-csi/ceph-csi-cephfs \ --namespace ceph-csi-cephfs \ --set csiConfig[0].clusterID="d08e3e42-115e-11f0-a5ad-005056b31542" \ --set csiConfig[0].monitors[0]="192.168.1.231:6789" \ --set csiConfig[0].monitors[1]="192.168.1.232:6789" \ --set csiConfig[0].monitors[2]="192.168.1.233:6789" \ --set nodeplugin.httpMetrics.containerPort=8082 ```
Fix — Provisioner Bloqué (operation already exists)
```bash
Supprimer le PVC bloqué
kubectl delete pvc
Redémarrer les provisioners pour vider le cache
kubectl rollout restart deployment \ ceph-csi-cephfs-provisioner -n ceph-csi-cephfs
Recréer le PVC
kubectl apply -f test-pvc-fs.yaml kubectl get pvc -w ```
Commandes de Diagnostic Rapide
```bash
── CEPH ─────────────────────────────────────────────────────────
ceph status # Santé globale du cluster ceph mds stat # État de tous les MDS ceph fs ls # Liste des filesystems ceph fs status prd-k8s-fs # État du filesystem K8s ceph fs subvolumegroup ls prd-k8s-fs # Vérifier le groupe 'csi' rbd ls prd-k8S # Images RBD créées par K8s ceph osd pool ls # Liste des pools ceph orch ps | grep mds # Daemons MDS déployés
── KUBERNETES ───────────────────────────────────────────────────
kubectl get storageclass # StorageClasses disponibles kubectl get pvc -A # Tous les PVC (tous namespaces) kubectl get pv # Tous les PersistentVolumes kubectl get pods -n ceph-csi-rbd # Pods driver RBD kubectl get pods -n ceph-csi-cephfs # Pods driver CephFS helm list -A | grep ceph # Installations Helm Ceph
── LOGS ─────────────────────────────────────────────────────────
Logs provisioner RBD
kubectl logs -n ceph-csi-rbd \
Logs provisioner CephFS
kubectl logs -n ceph-csi-cephfs \
Logs nodeplugin CephFS (liveness)
kubectl logs -n ceph-csi-cephfs \
── DEBUG PVC ────────────────────────────────────────────────────
kubectl describe pvc
✅ Récapitulatif Final — StorageClasses en Production
| StorageClass | Provisioner | Modes supportés | Usage recommandé |
|---|---|---|---|
| ceph-rbd-prd | rbd.csi.ceph.com | RWO | Databases, Postgres, Redis, apps stateful |
| ceph-filesystem-prd | cephfs.csi.ceph.com | RWO + RWX | Fichiers partagés, logs, media, configs |
☑️ Checklist Connectivité
- [ ] Ports MON ouverts (
6789) des workers K8s vers192.168.1.231-233 - [ ] Ports OSD ouverts (
6800-7300) des workers K8s vers le cluster Ceph - [ ] Module kernel RBD chargé sur tous les workers :
modprobe rbd - [ ] Module kernel CephFS chargé si besoin :
modprobe ceph - [ ] MDS actif pour
prd-k8s-fs:ceph mds stat - [ ] Subvolume group
csicréé :ceph fs subvolumegroup ls prd-k8s-fs - [ ] Tous les pods CSI en
Running:kubectl get pods -n ceph-csi-rbd && kubectl get pods -n ceph-csi-cephfs