Volumes persistants
Nous avons vu précédemment la notion de volumes. C’est ce qui permet d’apporter des données aux Pods, par exemple de la configuration via des ConfigMap ou des identifiants via des Secrets. Mais les volumes que nous avons vu jusqu’ici étaient temporaires. C’est-à-dire tout ce qui est écrit dessus disparaît quand le Pod disparaît. Or il y a des applications qui ont besoin de persistance de données. Par exemple, on ne peut pas perdre les données d’une base de données SQL dès qu’il arrive un souci au Pod.
Dans ces cas, nous avons besoin de nouveaux objets Kubernetes qui nous apportent des volumes persistants : les PV, les PVC et les StorageClass.
Un PV (Persistent Volume) représente le stockage (par exemple un disque SSD) disponible à utiliser par des Pods sur un cluster. Chaque PV décrit ses capacités : type de stockage, taille, mode d’accès, et emplacement. Mais un Pod ne demande pas directement un PV, il passe d’abord par un PVC.
Un PVC (Persistent Volume Claim) est l’objet qui représente ce que demande un utilisateur comme stockage. Et c’est un algorithme de contrôle k8s qui se charge de désigner quel PV va correspondre à ce PVC. Si un utilisateur demande un PVC de 1Gi et qu’il n’y a qu’un PV de 10Gi de disponible, k8s va associer le PV de 10Gi au PVC demandant 1Gi. La plupart du temps, pour éviter ce genre de problèmes, les PV ne sont pas créés de manière statique au préalable de la demande de PVC. On attend qu’un utilisateur demande un PVC d’une certaine taille et avec certaines caractéristiques pour que k8s puisse satisfaire cette demande avec un PV qu’il va créer dynamiquement. Pour le faire, l’administrateur doit spécifier des StorageClass. Une StorageClass permet de décrire comment on peut demander des volumes persistants sur le cluster k8s. Par exemple, on peut avoir une StorageClass qui crée des disques SSD normaux, une qui crée des disques SSD très performants, une autre qui crée des partages de fichiers NFS ou SMB. Lorsqu’un utilisateur veut avoir un volume SSD de 1Gi par exemple, il doit créer un PVC qui fait référence à la StorageClass qui correspond à ses besoins, et un contrôleur k8s va créer le PV qui va correspondre à ce PVC, et lier les deux.
Création statique d’un Persistent Volume
Nous allons d’abord commencer par créer un volume persistant de manière statique pour comprendre comment marche la mécanique d’association des PV et PVC, ainsi que pour voir concrètement la persistance des volumes.
Créons d’abord le PV :
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-data
spec:
storageClassName: "local"
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/opt/data"Le PV que nous voulons créer est d’une capacité de 1Gi, avec un accessModes de ReadWriteOnce (RWO), ce qui signifie que le volume peut être monté en lecture/écriture par un seul nœud à la fois., et pour le fournir, nous demandons à k8s d’utiliser hostPath, c’est-à-dire qu’il sera créé sur le noeud sur lequel il sera utilisé, sur le chemin /opt/data.
La StorageClass “local” n’existe pas, mais elle nous sert afin de permettre la correspondance entre ce PV et le PVC que nous allons créer plus tard.
Quand nous créons le PV :
kubectl apply -f pv-data.yaml
kubectl get pv pv-data
NAME CAPACITY STATUS STORAGECLASS
pv-data 1Gi Available local Il est bien dans l’état Available.
Maintenant nous pouvons créer le PVC :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-data
spec:
storageClassName: "local"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gikubectl apply -f pvc-data.yamlTout ce que nous avons demandé ici, c’est de créer un PVC d’une taille de 1Gi.
Quand on regarde le PVC :
kubectl get pvc pvc-data
NAME STATUS VOLUME CAPACITY STORAGECLASS
pvc-data Bound pv-data 1Gi localOn voit bien que le PVC est lié au PV pv-data qui correspond à la taille de 1Gi demandée par le PVC. Si on avait demandé une taille plus grande, k8s n’aurait pas assigné ce PV à notre PVC. Le PVC resterait alors dans l’état Pending.
Et pour confirmer la liaison dans l’autre sens aussi, on peut revoir l’état du PV :
kubectl get pv pv-data
NAME CAPACITY STATUS CLAIM STORAGECLASS
pv-data 1Gi RWO Bound test/pvc-data local On voit bien que le PV a été attaché au PVC pvc-data qui se trouve dans le namespace test. Et que le PV est passé au statut Bound.
Nous allons maintenant créer un Pod qui va utiliser ce PV/PVC :
apiVersion: v1
kind: Pod
metadata:
labels:
run: pvc-pod
name: pvc-pod
spec:
containers:
- image: busybox:latest
name: pvc-pod
args:
- sleep
- "3600"
volumeMounts:
- name: data
mountPath: "/data"
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-dataNous avons déclaré le volume qui s’appelle data et qui fait référence au PVC pvc-data. Puis nous l’avons monté sur le container pvc-pod sur le chemin /data.
On le lance et on voit que le dossier /data est bien là :
kubectl apply -f pvc-pod.yaml
kubectl exec pvc-pod -- ls -l /
drwxr-xr-x 2 root root 4096 Jan 2 10:50 dataPour vérifier que le volume est bien persistent, on va créer un fichier dans le volume data :
kubectl exec pvc-pod -- touch /data/file
kubectl exec pvc-pod-2 -- ls /data/
fileOn supprime le Pod :
kubectl delete -f pvc-pod.yamlPuis on créé un nouveau Pod qui va s’appeler pvc-pod-2 et qui monte le volume data de la même manière que pvc-pod
apiVersion: v1
kind: Pod
metadata:
labels:
run: pvc-pod
name: pvc-pod-2
spec:
containers:
- image: busybox:latest
name: pvc-pod
args:
- sleep
- "3600"
volumeMounts:
- name: data
mountPath: "/data"
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-datakubectl apply -f pvc-pod-2.yamlOn regarde dans le dossier /data, et on voit que le fichier qu’on a créé dans le premier Pod existe toujours, donc que la donnée est bien persistée :
kubectl exec pvc-pod-2 -- ls /data/
fileConclusion
Dans cet article, nous avons introduit les concepts de PersistentVolume (PV), PersistentVolumeClaim (PVC) et StorageClass, ainsi que leur rôle dans la gestion du stockage persistant dans Kubernetes.
Nous avons vu comment créer un PV de manière statique, l’associer à un PVC, puis l’utiliser dans un Pod afin de garantir la persistance des données, même après la suppression du Pod.
En pratique, le provisionnement dynamique via les StorageClasses est privilégié, car il permet de créer automatiquement les volumes persistants en fonction des besoins exprimés par les utilisateurs à travers leurs PVC.


