Dans un environnement Kubernetes, la gestion du stockage est un élément crucial pour garantir la stabilité et la performance de vos applications. Le choix entre stockage éphémère et stockage persistant n’est pas à négliger.
Par défaut, les conteneurs dans K8s sont éphémères. Cela signifie que toute les données stocké à l’interieur, disparaissent à la suppression ou au redémarrage. Pour éviter cela, Kubernetes a introduit le concept de Volumes, qui permet de dissocier le cycle de vie des données de celui des conteneurs.
Stockage par défaut: éphémère
Les volumes éphémères (comme emptyDir) sont crée au lancement du Pod et détruit lors de sa suppression ou redémarrage. Ces volumes sont utile pour:
- Le stockage temporaire comme le cache
- Le traitement de données intermédiaires
Stockage persistant
Pour les services nécessitant une conservation de données, on utilise le Stockage Persistant (PV) et des Persistant Volume Claims (PVC)
Un PV est une ressource de stockage disponible dans le cluster, tandis qu’un PVC est une requête de la par d’un Pod pour l’obtenir un volume avec une certaine caractéristique defini dans le fichier YAML de la demande. (taille, accès…)
Ces stockages peuvent être locale ou distante (NFS, EBS…) Ils permettent de préserver les données même après la suppression du Pod.
exemple de PV
# Définition du PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-exemple
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/pv-exemple
persistentVolumeReclaimPolicy: Retain
accessModes: – ReadWriteOnce : Cette ligne indique qu’un seul pod peut avoir accès au PV à la fois en mode lecture/écriture
persistentVolumeReclaimPolicy: Retain – Cette politique de volume permet de retenir les données même après la suppression du PVC
Exemple de PVC
# Définition du PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-exemple
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Exemple de fichier YAML – Pod utilisant un PVC
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc
spec:
containers:
- name: mon-container
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: volume-html
volumes:
- name: volume-html
persistentVolumeClaim:
claimName: pvc-exemple
Ce pod utilise l’image nginx
Il monte le PVC pvc-exemple dans le répertoire /usr/share/nginx/html du conteneur
Tout fichiers placé dans ce dossier restera persistant dans ce volume
+-------------+ +-------------+ +----------------+
| Pod | <---> | PVC | <---> | PV |
| (utilise) | | (réclame) | | (fourni par le |
| | | | | cluster/admin) |
+-------------+ +-------------+ +----------------+
Résumé PV PVC
Le PersistentVolume (PV) pv-exemple
est créé à l’avance par un administrateur ou une configuration.
- Il expose un volume de 1Gi avec un mode d’accès
ReadWriteOnce
. - Il pointe vers un dossier réel sur le nœud :
/data/pv-exemple
.
Le PersistentVolumeClaim (PVC) pvc-exemple
est une demande de volume de 1Gi avec les mêmes caractéristiques.
- Kubernetes va automatiquement chercher un PV disponible et compatible.
- Comme
pv-exemple
correspond parfaitement (taille, mode d’accès), il est « bindé » (lié) au PVC.
Le Pod pod-pvc
demande à utiliser pvc-exemple
via la section volumes
.
- Kubernetes sait déjà que
pvc-exemple
pointe verspv-exemple
. - Donc, le volume est monté dans le conteneur du Pod, à l’endroit défini (
/usr/share/nginx/html
).
Analogie : Le volume persistant, est comme une clé USB
Imagine que ton Pod est un ordinateur et que tu veux sauvegarder des fichiers, mais que cet ordi peut être redémarré ou remplacé à tout moment.
Tu pourrais :
- Écrire les fichiers sur le disque interne → ils disparaîtront si l’ordi redémarre (stockage éphémère).
- Brancher une clé USB → les fichiers restent, même si tu redémarres ou changes d’ordinateur (stockage persistant).
Dans Kubernetes, le PersistentVolume (PV) joue le rôle de cette clé USB.
Le Pod ne sait pas où elle est branchée physiquement (le PV peut être local ou distant), mais grâce au PVC, Kubernetes s’assure de la brancher au bon endroit dans le conteneur, ici par exemple dans /usr/share/nginx/html
.
Storage Controller
Le storage controller est le service qui va gérer les volumes. Il à plusieurs roles:
Surveiller les PVC
Trouver ou créer les PV qui correspond à la demande
Lier les PVC au PV
Gérer la création dynamique des volumes si nécessaire ( via un StorageClass)
Si le service est sur un service cloud (AWS par exemple) Le storage Controller va demander au provisioner (ici le EBS de AWS) de crée run volume automatiquement
StorageClass
La ressource StorageClass permet à Kubernetes de créer automatiquement des volumes persistants(PV) en fonction des besoins des applications, sans à avoit à définir manuellement.
Le StorageClass apporte de nombreux avantages:
- Gain de temps: La création des PV se fait automatiquement
- Flexibilité: Nous pouvons définir différentes classses selon les besoins (rapide, standard, crypté…)
- Automatisation complète ! Un simple PVC peut déclencher la création d’un volume réel dans l’infrastructure !
exemple de Storageclass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
provisioner: le plugin CSI (container storage interface) ou intégré utilisé pour créer le volume
parameters: dépendent du backend (type de disque, IOPS, encryption…)
reclaimPolicy: Que faire du volume après suppression du PVC: (Retain, Delete)
volumeBindingMode: contrôle quand le volume est alloué
Tableau récapitulatif
PVC | Demande de stockage faite par une application (le Pod) |
PV | Volume concret qui fournit l’espace demandé |
Storage Controller | Logique interne de Kubernetes qui gère l’attribution et le suivi des volumes |
Provisioner (plugin) | Plugin ou service externe qui exécute la création réelle des volumes (ex : AWS EBS, NFS, etc.) |
Sauvegarde des données: VolumeSnapshots
Les VolumeSnapshots permettent de sauvegarder l’état d’un volume à un instant T. Cela fonctionne avec les drivers CSI (container storage interface) compatibles avec la fonctionnalité snapshot (EBS, Ceph…)
Pourquoi utiliser les Snapshot ? Pour plusieurs raisons:
- Sauvegarder l’état d’une base de données ou service critique
- Créer un point de restauration avant une mise à jour risqué ou en cas de sinistre
- Dupliquer un environnement de test à partir d’un volume existants
Afin de pouvoir sauvegarder nos Snapshot, nous devons avant, créer un SnapShotClass:
Les VolumeSnapshotClass
sont à la création de snapshots ce que les StorageClass
sont à la création de volumes : elles définissent comment et où Kubernetes doit créer des snapshots pour tes volumes persistants.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-aws-vsc
driver: ebs.csi.aws.com
deletionPolicy: Retain
le driver correspondre exactement au nom du driver CSI utilisé par le PV
exemple de VolumeSnapshot:
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: snapshot-exemple
spec:
volumeSnapshotClassName: csi-aws-vsc
source:
persistentVolumeClaimName: pvc-exemple
Cette fonctionnalité nécessite que le CSI supporte les snapshots !
Restauration d’un Snapshot
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-from-snapshot
spec:
dataSource:
name: snapshot-exemple
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
Bonne pratiques
✅ Bonnes pratiques pour gérer le stockage dans Kubernetes
1. 🧼 Utiliser des StorageClass
pour le provisionnement dynamique
Plutôt que de créer manuellement les PersistentVolume
, configure des StorageClass
adaptées à ton environnement cloud (EBS, GCE, Ceph, etc.).
➡️ Ça permet à Kubernetes de créer automatiquement les volumes à la demande, à partir des PVC
.
2. 🔒 Bien choisir les accessModes
ReadWriteOnce
: un seul Pod peut lire/écrireReadOnlyMany
: plusieurs Pods peuvent lire (lecture seule)ReadWriteMany
: plusieurs Pods peuvent lire/écrire en même temps
➡️ Choisis en fonction de ton cas d’usage (base de données, fichiers partagés, etc.).
3. 🧠 Savoir où tu montes ton volume
Vérifie le mountPath
dans le conteneur :
- Il doit correspondre au dossier attendu par l’application
- Sinon, rien ne sera lu/écrit ou ça plantera
➡️ Par exemple, Nginx lit par défaut dans /usr/share/nginx/html
.
4. 🔁 Évite les hostPath
en production
Même si pratique en local, le hostPath
(volume local d’un nœud) n’est pas recommandé en prod, car :
- Ce nœud peut disparaître
- Il n’est pas portable sur d’autres nœuds
➡️ Préfère un backend de stockage réseau (EBS, NFS, Ceph, etc.)
5. 🗑️ Attention à la politique de réclamation (reclaimPolicy
)
Retain
: les données restent même après suppression du PVC (tu dois les nettoyer manuellement)Delete
: supprime automatiquement le volume quand le PVC est supprimé
➡️ Choisis la bonne stratégie selon tes besoins de rétention de données.