Table des matières :
- Pourquoi le stockage distribué Kubernetes finit toujours par devenir votre vrai sujet (pas vos microservices)
- PV, PVC, StorageClass : le contrat légal entre vos pods et votre stockage
- CSI : l’interface standard qui a remplacé la collection de plugins ésotériques
- RWO, RWX, RWOP : les modes d’accès, ou l’art de créer des corruptions élégantes
- Ceph dans Kubernetes : RBD, CephFS, et une masterclass de systèmes distribués (volontaire ou non)
- Longhorn : du stockage distribué Kubernetes “batteries included”, mais pas une baguette magique
- Comment choisir entre Ceph, Longhorn, et le classique “on verra plus tard” (spoiler : non)
- Ce que je mettrais en production en 2026 (et ce que j’éviterais poliment)
Quand on vend Kubernetes comme « plateforme cloud-native », on oublie souvent de préciser un détail amusant : vos conteneurs sont éphémères… mais vos données, elles, ont la mauvaise habitude de vouloir survivre. Et là, magie noire : stockage distribué Kubernetes, PVC/CSI, modes d’accès RWO/RWX, et les grands classiques Ceph et Longhorn.
Si votre stratégie actuelle ressemble à « on monte un hostPath et on croise les doigts », rassurez-vous : vous n’êtes pas seuls. Mais c’est aussi une excellente manière de transformer un incident mineur en post-mortem de 40 pages. Passons au sérieux.
Pourquoi le stockage distribué Kubernetes finit toujours par devenir votre vrai sujet (pas vos microservices)
Kubernetes sait très bien orchestrer du compute. Pour le stockage, il orchestre surtout des décisions d’architecture : où sont les données, comment elles se déplacent, qui a le droit de les monter, et comment on restaure quand un nœud meurt (spoiler : il meurt). Le stockage distribué Kubernetes n’est pas « un plugin », c’est une partie de votre design de résilience et de performance.
En e-commerce, les workloads stateful sont rarement optionnels : PostgreSQL/MySQL, Elasticsearch/OpenSearch, queues, cache persistant, backoffice qui écrit des médias, ETL… Même quand vous utilisez des services managés, vous gardez des besoins de volumes persistants (logs locaux, artefacts, caches build, fichiers temporaires). Et évidemment, l’équipe sécurité vous rappellera que « perdre des données » est un incident, mais « fuir des données » est un cauchemar.
Mini-scénario (très réaliste) : vendredi soir, déploiement d’un patch sur un nœud → drain → vos pods redémarrent ailleurs. Avec du hostPath, le pod “revient”, mais ses fichiers, eux, sont restés sur le nœud drainé. Résultat : une appli qui démarre “correctement” mais avec un répertoire vide, un cache incohérent, ou une base locale qui a disparu. Le problème n’est pas Kubernetes : c’est votre contrat de persistance qui n’existait pas.
Le piège classique : confondre persistant et distribué. Un disque attaché à une VM (ou un volume cloud de type bloc) peut être persistant, sans être distribué. Un stockage distribué Kubernetes (Ceph, Longhorn, etc.) ajoute réplication, tolérance aux pannes, et souvent des primitives (snapshots, clones, chiffrement) qu’on veut vraiment en production. Mais il ajoute aussi de l’overhead réseau, de la complexité opératoire, et un nouveau domaine de panne. Bref : vous échangez un risque contre un autre, donc il faut le faire consciemment.
Deux notions qui clarifient les débats dès le départ :
- RPO (Recovery Point Objective) : combien de données vous acceptez de perdre (0 ? 5 minutes ? 1 heure ?).
- RTO (Recovery Time Objective) : combien de temps vous acceptez d’être indisponible.
Sans RPO/RTO, on choisit “au feeling”, et le stockage finit toujours par devenir le sujet… au pire moment.
PV, PVC, StorageClass : le contrat légal entre vos pods et votre stockage
Kubernetes a séparé le besoin applicatif (une demande de stockage) de l’implémentation (le backend). Le trio PV/PVC/StorageClass sert exactement à ça (référence : https://kubernetes.io/docs/concepts/storage/persistent-volumes/).
Une PVC (PersistentVolumeClaim), c’est la requête : taille, mode d’accès (RWO/RWX…), volumeMode (Filesystem/Block), classe de stockage. Un PV, c’est la ressource concrète. Et une StorageClass, c’est la politique de provisionnement dynamique : type de disque, paramètres (réplication, pool, fsType), reclaimPolicy (Delete/Retain), allowVolumeExpansion, etc. Les équipes Dev adorent parce qu’elles n’ont pas à supplier l’ops pour un disque ; les ops aiment un peu moins parce que ça peut partir en sprawl de volumes si on ne met pas de quotas.
Quelques options qui font une vraie différence “prod” (et qui évitent les surprises) :
volumeBindingMode: WaitForFirstConsumer: retarde l’allocation du volume jusqu’à ce qu’un pod soit schedulé. Très utile quand la topologie (zones, nœuds dédiés) compte, pour éviter de créer un volume dans une zone où le pod ne pourra pas tourner.reclaimPolicy: Retainpour les données critiques : réduit le risque de suppression accidentelle de volumes lors d’une suppression de namespace (le PV passe en état “Released”, à traiter explicitement).allowVolumeExpansion: true: indispensable… mais à tester (online/offline resize, support du CSI, comportement du filesystem).
Concrètement, si vous avez déjà eu une base qui refuse de redémarrer après un resize “au pif”, retenez ceci : l’expansion de volume est un sujet stateful (filesystem resize, online vs offline, support du driver), et elle doit être testée comme un scénario de prod. Même chose pour reclaimPolicy: Delete : c’est super jusqu’au jour où quelqu’un supprime le namespace “staging” et efface aussi les volumes… parce que “staging” contient toujours des données critiques, évidemment.
Exemple minimal (très simplifié) de PVC, pour illustrer la couche d’abstraction :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pg-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
storageClassName: fast-rwo
Et un exemple de StorageClass (toujours générique) montrant les champs qui reviennent en audit :
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-rwo
provisioner: csi.example.com
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
parameters:
type: ssd
Point gouvernance : si vous avez plusieurs équipes/projets, pensez très tôt à des ResourceQuotas (nombre de PVC, capacité totale) et à un naming clair des StorageClasses (“fast-rwo”, “capacity-rwo”, “shared-rwx”), sinon vous allez hériter d’un cimetière de volumes “temporairement permanents”.
CSI : l’interface standard qui a remplacé la collection de plugins ésotériques
Avant CSI, Kubernetes trimballait des drivers “in-tree”. C’était pratique… jusqu’à ce qu’il faille les maintenir dans le core, gérer les cycles de release, et déployer des features stockage sans upgrader tout le cluster. CSI a remis de l’ordre : les vendors livrent des drivers out-of-tree avec un contrat stable (spécification : https://github.com/container-storage-interface/spec).
Techniquement, un déploiement CSI se découpe en Controller (provisioning, attach/detach, snapshots) et Node (mount/format sur le nœud). Autour, des sidecars “classiques” (external-provisioner, external-attacher, external-resizer, external-snapshotter). Résultat : vous obtenez des features comme le provisionnement dynamique, les VolumeSnapshots, le clonage, et la topology awareness (zone/region) sans bricolage maison. Oui, ça fait beaucoup de composants ; non, ce n’est pas optionnel si vous voulez du stockage sérieux.
Deux détails pratiques souvent oubliés lors des incidents :
- Les snapshots Kubernetes ne sont pas “magiques” : ils dépendent d’un driver qui les implémente et du contrôleur snapshot. La référence à garder sous la main : https://kubernetes.io/docs/concepts/storage/volume-snapshots/
- Un snapshot n’est pas un backup tant que vous n’avez pas testé la restauration (et idéalement l’export hors-cluster / hors-zone, selon votre modèle de risques).
Exemple minimal d’un VolumeSnapshot (si votre CSI le supporte) :
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: pg-data-snap-2026-03-01
spec:
volumeSnapshotClassName: fast-snap
source:
persistentVolumeClaimName: pg-data
Point 2026 à ne pas zapper : l’accès ReadWriteOncePod (RWOP) (selon version/driver) permet de verrouiller un volume à un seul pod (pas juste un nœud). C’est utile pour éviter les “double-mount” involontaires lors de déploiements agressifs ou d’un scheduler qui pense bien faire. Si votre DB se retrouve montée deux fois, elle ne va pas “discuter” : elle va se corrompre. Et elle aura raison.
RWO, RWX, RWOP : les modes d’accès, ou l’art de créer des corruptions élégantes
Les modes d’accès Kubernetes sont souvent mal compris parce qu’ils expriment une capacité du backend, pas une promesse abstraite. RWO signifie “montable en lecture/écriture par un seul nœud à la fois” (mais potentiellement par plusieurs pods sur ce nœud). RWX signifie “montable en lecture/écriture par plusieurs nœuds”. ROX (moins courant) : lecture seule multi-nœud. Et RWOP (quand supporté) : un seul pod.
En pratique, RWX implique presque toujours un filesystem partagé (NFS, CephFS) ou un mécanisme équivalent. Les volumes block “purs” (iSCSI, RBD) sont généralement RWO, car le multi-attach block est une zone de guerre (verrous SCSI, fencing, cluster FS). Si vous avez une appli qui “a besoin de RWX” pour partager un répertoire, demandez-vous si elle ne devrait pas plutôt écrire dans de l’object storage (S3-compatible) ou dans une base. Les fichiers partagés, c’est la nostalgie des années 2000, pas une stratégie cloud-native.
Table de lecture rapide (utile en atelier d’archi) :
| Mode | Ce que ça autorise (réellement) | Backends typiques | Erreur classique |
|---|---|---|---|
| RWO | 1 nœud en écriture (plusieurs pods possibles sur ce nœud) | Block (cloud disks, Ceph RBD, Longhorn) | Penser “multi-pods = multi-nœuds” |
| RWX | Plusieurs nœuds en écriture | FS partagé (CephFS, NFS) | Mettre une DB dessus “parce que c’est simple” |
| RWOP | 1 seul pod | Selon support CSI | Croire que ça remplace une stratégie HA |
| ROX | Plusieurs nœuds en lecture | Cas spécifiques | Croire que ça protège contre les écritures applicatives |
Cas d’école e-commerce : base de données en RWO sur un volume block performant, uploads en RWX si vous tenez à un FS partagé (ou mieux : stockage objet + CDN), et jobs qui consomment des snapshots/clones pour tests.
Et si vous voulez mesurer l’impact réel, instrumentez : latence p99 des requêtes DB, iowait, taux de fsync, saturation réseau, et surtout erreurs côté CSI (timeouts, multi-attach). Un cluster qui “marche” sans observabilité est juste un cluster qui n’a pas encore planté. Pour le monitoring, un socle Prometheus bien fait reste la base (voir https://www.les-vikings.fr/article/prometheus-monitoring-quickstart-en-5-minutes-et-mise-en-production/), et l’unification via OpenTelemetry est devenue difficile à ignorer ( https://www.les-vikings.fr/article/opentelemetry-unifier-metriques-traces-et-logs-pour-lobservabilite/ ).
Ceph dans Kubernetes : RBD, CephFS, et une masterclass de systèmes distribués (volontaire ou non)
Ceph est souvent choisi parce qu’il fait “tout” : objet, block, file (documentation : https://docs.ceph.com/).
Dans Kubernetes, les deux profils courants sont Ceph RBD (block, typiquement RWO) et CephFS (file, typiquement RWX). Avec l’opérateur Rook (https://rook.io/), vous déployez Ceph “dans” le cluster, avec CRDs, daemons OSD/MON/MGR, pools, et intégration CSI. Sur le papier, c’est magnifique : auto-healing, réplication (souvent 3x), snapshots (selon config), et surtout une indépendance vis-à-vis d’un SAN externe.
Dans la vraie vie, Ceph demande une hygiène d’infra (et c’est là que tout se joue) :
- Réseau : Ceph parle beaucoup. Une latence réseau instable se transforme vite en latence disque “mystérieuse”. En pratique, séparer logiquement (voire physiquement) les flux “client” et “cluster” aide à stabiliser le comportement sur des plateformes chargées.
- Disques : Ceph sait utiliser HDD/SSD/NVMe, mais il faut aligner le matériel avec les workloads. Mettre une base OLTP sur des HDD “capacity” est un exercice de patience.
- Capacity planning : avec une réplication 3×, 100 To bruts ne font pas 100 To utiles. Calcul simple (hors overheads) :
capacité utile ≈ capacité brute / facteur de réplication.
Et il reste encore la marge opérationnelle (rebuild, scrubbing, croissance).
Les performances dépendent énormément du profil I/O : une base OLTP qui fsync beaucoup va faire ressortir la latence ; des workloads séquentiels (backup, médias) passeront mieux. Plutôt que de discuter “au ressenti”, définissez vos SLO : par exemple p95/p99 sur les écritures sync, débit minimal sur les exports, temps de restauration maximal.
Le vrai coût, c’est l’ops : upgrades Ceph, rebalancing CRUSH, dégradations, scrubbing, et surtout les incidents “lents” (un OSD flappe, un switch congestionne, et tout le monde accuse Kubernetes). Ceph est excellent… pour les équipes qui acceptent d’exploiter un système distribué. Si vous n’avez pas ce niveau de MCO/MCS, vous allez apprendre. Rapidement. Et avec des astreintes.
Checklist “prod” (courte, mais non négociable) si vous partez sur Rook/Ceph :
- anti-affinité / spread des MON/OSD pour éviter les pannes corrélées ;
- supervision des états degraded/backfilling/recovering et alerting actionnable ;
- politique de snapshots + tests de restauration (pas juste “on sait en faire”) ;
- stratégie de mise à jour (fenêtres, PDB, capacité libre pour rebuild) ;
- chiffrement et gestion des secrets cohérents avec vos contraintes (RGPD, exigences client), idéalement intégrés à votre démarche DevSecOps ( https://www.les-vikings.fr/article/devsecops-as-a-service-integrer-la-securite-au-pipeline-ci-cd/ ).
Longhorn : du stockage distribué Kubernetes “batteries included”, mais pas une baguette magique
Longhorn (https://longhorn.io/) se positionne comme stockage block distribué, simple à déployer sur Kubernetes (documentation : https://longhorn.io/docs/).
Le modèle est différent de Ceph : Longhorn réplique par volume sur plusieurs nœuds, expose un device block au nœud qui attache le volume, et gère snapshots/backup (souvent vers S3). C’est souvent plus simple à prendre en main, surtout sur des clusters modestes, du bare-metal hétérogène, ou des contextes edge où vous voulez une solution intégrée sans bâtir une “storage team”.
Là où Longhorn est agréable en exploitation :
- réglage “par volume” (nombre de replicas, localité des données, politique de rebuild) ;
- snapshots et “recurring jobs” (selon votre stratégie) pour automatiser une hygiène minimale ;
- backups vers un stockage objet (utile si votre objectif est de sortir une copie hors cluster).
Mais il faut rester lucide : la réplication au niveau volume, les reconstructions, et le chemin I/O ont un coût. Pour des bases très exigeantes en latence, vous devez benchmarker sur votre matériel (CPU, réseau, MTU, débit est/ouest). Et pour le RWX, Longhorn passe généralement par un composant de partage (type NFS via share-manager) : pratique, mais ce n’est pas le même niveau de performance/semantique qu’un vrai FS distribué. Longhorn est parfait quand vous cherchez une solution opérationnellement légère ; il est moins pertinent si vous cherchez un stockage universel à très grande échelle.
Un piège classique (observé en production) : activer la réplication “forte” partout par réflexe, puis découvrir que certains workloads sont surtout limités par le réseau est/ouest et la saturation CPU liée aux chemins d’I/O. La bonne pratique est d’avoir au moins deux profils (par exemple “fast-rwo” pour les workloads sensibles, “capacity-rwo” pour le reste) et d’accepter que tout ne mérite pas le même niveau de résilience.
Comment choisir entre Ceph, Longhorn, et le classique “on verra plus tard” (spoiler : non)
Le choix Ceph vs Longhorn (ou stockage cloud managé) doit se faire sur des critères concrets : SLO de latence, profils I/O (random write vs séquentiel), RPO/RTO, contraintes d’isolement (multi-tenant), compétences internes, et budget. Si vous gérez un gros e-commerce, la question n’est pas “quel est le meilleur”, c’est “quel risque je préfère : complexité Ceph ou limites Longhorn, et quel plan de secours j’ai”. Le stockage distribué Kubernetes, c’est du trade-off industrialisé.
Une matrice simple aide à cadrer sans religion :
| Besoin | Solution souvent pertinente | Pourquoi |
|---|---|---|
| DB OLTP (PostgreSQL/MySQL) | Block RWO (Ceph RBD ou Longhorn selon contexte) | Semantique block + contrôle fin + perf prévisible si bien dimensionné |
| Partage fichiers intensif multi-nœuds | CephFS (RWX) | FS distribué conçu pour RWX |
| Partage “fonctionnel” (exports, imports) | RWX via composant NFS / share-manager | Suffisant si la concurrence I/O est modérée |
| Artefacts, médias, archives | Stockage objet (S3 compatible) | Scalabilité et coûts souvent meilleurs, découplage applicatif |
| Multi-zone / topo stricte | Driver CSI avec topologie + WaitForFirstConsumer |
Évite les volumes créés au mauvais endroit |
Méthode rationnelle (donc impopulaire) : 1) classer les données (tiering), 2) définir des SLO mesurables (p95/p99, débit, IOPS), 3) prototyper sur un environnement proche prod, 4) tester des scénarios de panne (kill node, partition réseau, disque lent), 5) valider restore (snapshot → nouveau PVC → app). Et vous mettez les métriques sous Prometheus, avec alerting sur latence volume, erreurs CSI, reconstructions, saturation réseau.
Si vous n’avez pas de pipeline de durcissement, vous allez aussi vouloir intégrer la sécurité au delivery ( https://www.les-vikings.fr/article/devsecops-as-a-service-integrer-la-securite-au-pipeline-ci-cd/ ) et formaliser le maintien en conditions ( https://www.les-vikings.fr/groupe-vikings-technologies-tous-nos-domaines-intervention/entreprise-maintenance-preventive-wordpress-prestashop-magento-tma-e-commerce/mco-mcs-maintien-en-conditions-operationnelles-maintien-en-conditions-de-securite/ ).
Côté “transactionnel” (parce qu’à un moment, il faut aussi livrer) : si votre objectif est une plateforme robuste, ce n’est pas juste un choix de driver CSI, c’est un choix d’hébergement, de réseau, et d’exploitation 24/7. Un stockage distribué performant réclame une infra THD et des pratiques d’exploitation propres (voir l’approche hébergement très haute disponibilité : https://www.les-vikings.fr/groupe-vikings-technologies-tous-nos-domaines-intervention/societe-hebergement-e-commerce-web-hebergeur-vert/hebergement-infrastructure-thd-tres-haute-disponibilite/ et l’accompagnement DevOps : https://www.les-vikings.fr/groupe-vikings-technologies-tous-nos-domaines-intervention/societe-hebergement-e-commerce-web-hebergeur-vert/devops-creation-et-optimisation-dinfrastructures-dhebergement/ ). Et si vous manipulez des données sensibles, ce serait dommage d’oublier la base ( https://www.les-vikings.fr/article/hebergement-informatique-securise-meilleures-pratiques-pour-les-professionnels/ ).
Ce que je mettrais en production en 2026 (et ce que j’éviterais poliment)
Pour une base de données (PostgreSQL/MySQL) dans Kubernetes : je privilégie un volume block RWO avec un CSI mature, des snapshots testés, et un opérateur DB qui gère correctement le failover (sinon, vous réinventez Patroni à la main, et c’est rarement un hobby sain). Ceph RBD est une option solide si l’équipe sait l’exploiter ; Longhorn peut convenir si le cluster et les exigences de perf restent raisonnables et si vous acceptez de benchmarker et d’ajuster les replicas/anti-affinités.
Pour du partage RWX (uploads, médias, exports) : si c’est critique et intensif, je préfère un FS distribué fait pour ça (CephFS) ou un service managé équivalent. Si c’est “fonctionnel mais pas critique”, Longhorn RWX peut dépanner, mais j’évite d’y mettre des workloads à forte concurrence I/O en faisant semblant que c’est un NAS enterprise. Alternative souvent supérieure : sortir du paradigme FS et passer sur stockage objet + cache/CDN, ce qui simplifie la scalabilité applicative.
Un garde-fou simple avant mise en prod (checklist express) :
- au moins une procédure de restauration testée (snapshot → nouveau PVC → redéploiement) ;
- une règle claire sur
reclaimPolicy(et qui peut supprimer quoi) ; WaitForFirstConsumersi la topologie compte ;- alerting sur erreurs CSI, latence I/O, volumes en rebuild/Degraded ;
- politique de mise à jour (drivers CSI + stockage) documentée et répétée en préprod ;
- capacité libre suffisante (les rebuilds et migrations “mangent” de la marge) ;
- chiffrement/gestion des secrets alignés avec votre cadre (RGPD, exigences contractuelles).
Enfin, j’éviterais deux choses : 1) le stockage “à la débrouille” (hostPath, local PV sans stratégie) pour tout ce qui a une valeur business, 2) les migrations de stockage sans plan de rollback. Les données n’ont pas de bouton “undo”. Et si vous voulez objectiver l’état actuel (performances, risques, dette), un audit technique bien mené vous fera gagner des mois ( https://www.les-vikings.fr/article/audit-de-site-web-technique-seo-ux-et-securite-pour-une-roadmap/ ), même si oui, c’est moins glamour que de rajouter un énième microservice.