infra / kubernetes
Volumes persistants : PV, PVC et StorageClass
Explication
Ce que vous allez apprendre
- Expliquer pourquoi le stockage d'un conteneur est éphémère par défaut, et quelles applications en ont besoin autrement
- Distinguer les trois responsabilités séparées : PersistentVolume (disque réel), PersistentVolumeClaim (demande), StorageClass (règle de provisionnement)
- Écrire un PVC qui demande une capacité de stockage sans connaître le disque physique sous-jacent
- Choisir le bon
accessMode(ReadWriteOnce, ReadOnlyMany, ReadWriteMany) selon le besoin de partage entre nodes - Diagnostiquer un Pod bloqué en
Pendingà cause d'un PVC mal configuré ou d'un accessMode incompatible
Dans quel contexte ?
Une équipe déploie une base de données PostgreSQL dans Kubernetes et découvre, après un premier test, que toutes les données disparaissent à chaque redéploiement du Pod. En ajoutant un PersistentVolumeClaim de 20 Go avec le mode ReadWriteOnce, monté sur le répertoire de données de PostgreSQL, les données survivent désormais aux redémarrages, aux mises à jour et même au déplacement du Pod vers un autre node du cluster — exactement le comportement attendu d'une base de données en production.
Le problème du stockage éphémère
D'abord, un fait déjà entrevu : tout ce qu'un conteneur écrit sur son disque disparaît quand le Pod est recréé. C'est voulu : cela garantit que les Pods restent interchangeables.
Prérequis
Cette leçon suppose comprise la distinction Deployment/Pod (leçon 4) : un PVC est généralement référencé dans le template de Pod d'un Deployment ou, mieux, d'un StatefulSet (leçon 16) pour les bases de données.
Ce que ce comportement casse pour certaines applications
Mais certaines applications, typiquement les bases de données, ont besoin que leurs données survivent aux redémarrages, aux mises à jour, voire au déplacement du Pod vers un autre node.
Trois objets pour trois responsabilités séparées
Kubernetes sépare volontairement trois notions. Le PersistentVolume (PV) représente un espace de stockage réellement provisionné, comme un disque cloud ou un NFS.
| Objet | Rôle | Qui l'écrit habituellement |
|---|---|---|
| StorageClass | Définit comment provisionner automatiquement un disque | Administrateur du cluster |
| PersistentVolume (PV) | Représente un espace de stockage réellement provisionné | Généré automatiquement (ou par un admin) |
| PersistentVolumeClaim (PVC) | Demande de stockage faite par l'application | Développeur |
Ce qu'une application demande, sans connaître le disque réel
Le PersistentVolumeClaim (PVC) est une "demande" faite par l'application : "j'ai besoin de 20 Go", sans se soucier du disque physique exact derrière. La StorageClass, elle, définit comment ce provisionnement se fait automatiquement, avec quel type de disque, dans quelle zone.
Pourquoi cette séparation est utile en pratique
Un développeur écrit simplement un PVC, pendant qu'un administrateur configure les StorageClass disponibles, sans que l'un ait besoin de connaître les détails de l'autre.
Un piège fréquent : le mode d'accès
Une fois le PVC créé, il reste un détail à ne pas négliger : le accessMode, qui détermine comment le volume peut être monté. ReadWriteOnce autorise un seul node à la fois, le cas le plus courant pour une base de données.
Piège fréquent
Vouloir monter un PVC en écriture sur plusieurs nodes simultanément sans le bon accessMode (ReadWriteMany, qui nécessite un système de fichiers réseau comme NFS) bloque simplement le démarrage des Pods concernés, qui restent en Pending sans message d'erreur évident. Vérifiez toujours que l'accessMode correspond au nombre réel de Pods qui doivent écrire simultanément.
Les modes qui autorisent plusieurs nodes
ReadOnlyMany et ReadWriteMany autorisent plusieurs nodes en même temps, mais nécessitent un système de fichiers réseau comme NFS. Vouloir monter un PVC en écriture sur plusieurs nodes sans le bon mode bloque simplement le démarrage des Pods concernés.
Ne pas perdre les données par erreur
Enfin, la reclaimPolicy détermine ce qui arrive au volume physique quand le PVC est supprimé. Retain conserve les données même après suppression accidentelle du PVC, un filet de sécurité précieux pour toute donnée importante en production.
Maintenant que les données peuvent survivre à un Pod, la leçon suivante s'intéresse à un besoin différent : organiser un cluster partagé entre plusieurs équipes ou environnements, avec les Namespaces.
Commandes & code
PersistentVolume, PersistentVolumeClaim, StorageClass
# storageclass.yaml - définit COMMENT le stockage est provisionné dynamiquement
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs # dépend du cloud provider (ex: ebs.csi.aws.com)
parameters:
type: gp3
reclaimPolicy: Retain # garde les données même après suppression du PVC
volumeBindingMode: WaitForFirstConsumer # provisionne au moment où un Pod l'utilise réellement# pvc.yaml - une "demande" de stockage faite par une application
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-data-pvc
spec:
accessModes:
- ReadWriteOnce # RWO = un seul node en lecture/écriture (typique pour une base)
storageClassName: fast-ssd
resources:
requests:
storage: 20Gi# statefulset-like usage dans un Deployment (voir aussi la leçon StatefulSets)
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumes:
- name: data
persistentVolumeClaim:
claimName: db-data-pvckubectl apply -f storageclass.yaml -f pvc.yaml
kubectl get pv,pvc
kubectl describe pvc db-data-pvc # "Pending" = souvent un StorageClass introuvable ou quota atteint| AccessMode | Signification |
|---|---|
ReadWriteOnce (RWO) | Monté en lecture/écriture par un seul node |
ReadOnlyMany (ROX) | Monté en lecture seule par plusieurs nodes |
ReadWriteMany (RWX) | Monté en lecture/écriture par plusieurs nodes (NFS, EFS...) |
ReadWriteOncePod | Monté en lecture/écriture par un seul Pod (le plus strict) |
Résumé
- PV = ressource de stockage réelle, PVC = demande faite par une app, StorageClass = comment provisionner.
WaitForFirstConsumerévite de provisionner un volume dans la mauvaise zone de disponibilité.reclaimPolicy: Retainprotège les données même si le PVC est supprimé par erreur.ReadWriteOnceest le mode le plus courant pour les bases de données.
Exercices pratiques
Mission : sauver les données de PostgreSQL
Objectif : Ajouter un stockage persistant à une base de données, et choisir le bon accessMode selon le besoin réel de partage entre nodes.
Contexte
L'équipe vient de découvrir que toutes les données de son PostgreSQL disparaissent à chaque redéploiement du Pod, car aucun stockage persistant n'a été configuré. Ils veulent aussi préparer un second scénario : un futur outil d'analyse qui devra lire les mêmes fichiers exportés depuis DEUX Pods différents, sur deux nodes différents, en même temps.