Gestion dynamique du stockage avec les StorageClass
Mise à jour :
Dans un guide précédent, nous avons exploré comment Kubernetes gère le stockage, notamment à travers les solutions intégrées et l’utilisation de CSI (Container Storage Interface). Nous avons abordé les concepts de stockage éphémère et persistant, ainsi que les différents types de volumes disponibles. Pour approfondir cette thématique, il est essentiel de comprendre le rôle de la ressource StorageClasses.
Dans ce guide, nous allons détailler leur fonctionnement, leur création et leur gestion pour optimiser l’utilisation du stockage dans vos déploiements Kubernetes.
Prérequis pour tester les exemples
Avant de manipuler les StorageClasses dans Kubernetes, il est essentiel de disposer d’un environnement fonctionnel et des outils adéquats. Voici ce dont vous aurez besoin :
L’outil kubectl
pour interagir avec le cluster
kubectl
est l’outil en
ligne de commande indispensable pour gérer un cluster Kubernetes. Il permet
de :
- Appliquer des fichiers de configuration YAML
- Lister et vérifier l’état des StorageClasses, PV et PVC
- Debugger les éventuels problèmes liés au stockage
L’outil helm
pour installer des provisionneurs
Helm
est un gestionnaire de
paquets pour Kubernetes, qui facilite l’installation et la gestion des
applications complèxes. Il est souvent utilisé pour déployer des provisionneurs
de stockage CSI (Container Storage Interface) dans un cluster.
Un cluster Kubernetes opérationnel
Pour tester les StorageClasses et le provisionnement dynamique de volumes, vous devez disposer d’un cluster Kubernetes fonctionnel. Deux options s’offrent à vous :
- Un cluster en production ou hébergé sur le cloud (AWS EKS, Azure AKS, Google GKE, OpenShift, etc.)
- Un cluster local pour les tests et l’apprentissage Minikube est une solution simple à mettre en place sur une machine locale.
Vérifiez que votre cluster est bien opérationnel avec la commande :
kubectl cluster-infoKubernetes control plane is running at https://192.168.50.141:8443CoreDNS is running at https://192.168.50.141:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Si votre cluster est en place, vous devriez voir une sortie indiquant l’adresse de l’API Kubernetes.
Un éditeur de code pour manipuler les fichiers YAML
Pour éditer et appliquer vos fichiers de configuration Kubernetes, il est recommandé d’utiliser un éditeur de code adapté comme :
- VS Code avec l’extension Kubernetes
- Vim ou Nano si vous préférez un éditeur en ligne de commande
- IntelliJ IDEA avec le plugin Kubernetes
Pourquoi utiliser une StorageClass ?
Sans StorageClass, le processus de stockage est statique : un administrateur doit d’abord créer un PersistentVolume (PV), puis un PersistentVolumeClaim (PVC) doit le réclamer. Mais cette méthode pose plusieurs problèmes :
- Complexité : il faut créer et gérer chaque volume manuellement.
- Manque de flexibilité : si plusieurs applications ont besoin de stockage, il faut anticiper et créer les volumes à l’avance.
- Moins d’automatisation : Kubernetes ne peut pas provisionner de nouveaux volumes automatiquement.
Avec une StorageClass, Kubernetes peut créer des volumes à la demande, en fonction des besoins de l’application. L’administrateur définit une fois les règles, et Kubernetes gère le reste !
Installation du serveur NFS pour les exemples
Pour les exemples de ce guide, nous allons utiliser un serveur NFS pour le stockage persistant. Voici comment installer un serveur NFS sur une machine Ubuntu :
-
Installer le serveur NFS :
Terminal window sudo apt updatesudo apt install nfs-server -
Créer un répertoire partagé :
Terminal window sudo mkdir -p /data -
Configurer le partage NFS :
Terminal window sudo echo "/data *(rw,sync,no_subtree_check)" >> /etc/exports -
Redémarrer le serveur NFS :
Terminal window sudo systemctl restart nfs-kernel-server -
Vérifier que le partage est bien configuré :
Terminal window sudo exportfs/data <world>
Votre serveur NFS est maintenant prêt à être utilisé pour les exemples de StorageClasses.
Installer des provisionneurs de stockage
De nombreux provisionneurs CSI sont disponibles pour Kubernetes, chacun permettant l’intégration avec différents systèmes de stockage. Voici quelques exemples notables :
- AWS Elastic Block Store (EBS) : Permet l’utilisation des volumes EBS d’AWS comme stockage persistant dans Kubernetes.
- Azure Disk Storage : Intègre les disques managés d’Azure pour une utilisation avec Kubernetes.
- Google Persistent Disk : Offre une intégration avec les disques persistants de Google Cloud.
- NFS (Network File System) : Permet l’utilisation de serveurs NFS existants pour le stockage persistant.
Pour une liste complète et à jour des provisionneurs CSI disponibles, vous pouvez consulter la documentation officielle de Kubernetes CSI ↗.
Installation d’un provisionneur CSI
L’installation d’un provisionneur NFS CSI permet à Kubernetes d’interagir avec un serveur NFS pour la gestion dynamique des volumes persistants. Voici comment procéder :
-
Pré-requis :
- Disposer d’un serveur NFS fonctionnel et accessible depuis le cluster Kubernetes.
-
Déploiement du driver CSI NFS :
-
Utiliser le chart Helm fourni par le projet
csi-driver-nfs
:Terminal window helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/chartshelm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.10.0
-
-
Vérifier que le provisionneur est bien en place :
Terminal window kubectl get pods -n kube-system -o wide | grep nfscsi-driver-nfs-controller-0 5/5 Running 0 2mcsi-driver-nfs-node-0-0 3/3 Running 0 2m
Au bout de quelques instants, le provisionneur CSI NFS devrait être déployé et opérationnel dans votre cluster.
Création d’une StorageClass
Avant de créer une StorageClass, il est essentiel de comprendre les paramètres clés qui la composent et leur rôle dans le provisionnement des volumes persistants.
Comprendre les paramètres d’une StorageClass
Une StorageClass est une ressource Kubernetes qui définit les règles pour provisionner automatiquement des volumes persistants. Voici les paramètres clés d’une StorageClass et leur rôle :
-
provisioner
: Définit le provisionneur de stockage utilisé.- Exemple :
nfs.csi.k8s.io
pour le driver NFS CSI. Vous povuez trouver le nom du provisionneur dans la documentation du driver CSI.
- Exemple :
-
parameters
: Contient les configurations spécifiques au stockage.server
: Adresse du serveur NFS.share
: Chemin du partage NFS sur le serveur.
-
reclaimPolicy
: Définit ce qu’il advient du volume une fois que le PersistentVolumeClaim (PVC) est supprimé.Delete
: Kubernetes supprime automatiquement le volume.Retain
: Le volume reste présent et doit être supprimé manuellement.
-
allowVolumeExpansion
: Permet ou non l’agrandissement d’un volume après sa création (true
oufalse
). -
volumeBindingMode
: Définit quand Kubernetes lie un PersistentVolume à un PersistentVolumeClaim.Immediate
(par défaut) : Le volume est créé dès la demande.WaitForFirstConsumer
: Kubernetes attend qu’un Pod utilise le volume avant de le créer.
Création d’une StorageClass avec NFS CSI
Maintenant que nous avons installé le provisionneur NFS CSI, nous allons créer une StorageClass qui utilisera ce driver pour provisionner des volumes dynamiquement.
-
Créer un fichier
storageclass-nfs.yaml
:apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:name: nfs-csiprovisioner: nfs.csi.k8s.ioparameters:server: 192.168.20.121 # Remplacer par l'adresse IP du serveur NFSshare: /datareclaimPolicy: DeletevolumeBindingMode: ImmediateallowVolumeExpansion: truemountOptions:- nfsvers=4.1 -
Appliquer la StorageClass dans Kubernetes :
Terminal window kubectl apply -f storageclass-nfs.yaml -
Vérifier que la StorageClass a été créée :
Terminal window kubectl get storageclassNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGEnfs-csi nfs.csi.k8s.io Delete Immediate true 2m
Utilisation de la StorageClass
Une fois la StorageClass créée, elle peut être utilisée pour provisionner des volumes persistants dynamiquement à l’aide d’un PersistentVolumeClaim (PVC).
-
Créer un fichier
pvc-nfs.yaml
:---apiVersion: v1kind: PersistentVolumeClaimmetadata:name: pvc-deployment-nfsnamespace: defaultspec:accessModes:- ReadWriteMany # Accès en lecture/écriture pour plusieurs Podsresources:requests:storage: 10GistorageClassName: nfs-csi # Utilisation de la StorageClass NFS définie précédemmentCe PVC demande 5 Go de stockage en ReadWriteMany, ce qui signifie qu’il peut être monté sur plusieurs Pods en même temps.
-
Appliquer le PVC :
Terminal window kubectl apply -f pvc-nfs.yaml -
Vérifier que le PVC est bien lié à un volume :
Terminal window kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGEpvc-deployment-nfs Bound pvc-a7b9101f-644d-4bbd-8b7b-eaa8ced6f74a 10Gi RWX nfs-csi <unset> 8sLe statut
Bound
signifie que le volume a été créé et est prêt à être utilisé.
Avec cette StorageClass basée sur NFS CSI, Kubernetes peut provisionner dynamiquement des volumes persistants dès qu’une application en fait la demande, sans intervention manuelle.
Création d’un deployment consommant le PVC
-
Créer un fichier
deployment.yaml
:---apiVersion: apps/v1kind: Deploymentmetadata:name: deployment-nfsnamespace: defaultspec:replicas: 1selector:matchLabels:name: deployment-nfstemplate:metadata:name: deployment-nfslabels:name: deployment-nfsspec:nodeSelector:"kubernetes.io/os": linuxcontainers:- name: deployment-nfsimage: mcr.microsoft.com/oss/nginx/nginx:1.19.5command:- "/bin/bash"- "-c"- set -euo pipefail; while true; do echo $(hostname) $(date) >> /mnt/nfs/outfile; sleep 1; donevolumeMounts:- name: nfsmountPath: "/mnt/nfs"readOnly: falsevolumes:- name: nfspersistentVolumeClaim:claimName: pvc-deployment-nfs -
Appliquer le déploiement :
Terminal window kubectl apply -f deployment.yaml -
Vérifier que le déploiement est en cours :
Terminal window kubectl get podsdeployment-nfs-7fbbf89668-md8gc 1/1 Running 0 1s
Le déploiement est en cours et le pod est en train de consommer le volume provisionné par la StorageClass NFS.
Vérifiez le contenu du dossier /data
sur le serveur NFS pour voir les fichiers
générés par le pod.
ls -al /data
drwxrwxrwx 3 nobody nogroup 4096 mars 4 18:38 .drwxr-xr-x 24 root root 4096 janv. 27 13:06 ..drwxr-xr-x 2 root root 4096 mars 4 18:38 pvc-8b6dcfbb-5556-41f3-9434-025784808f22
On retroue le dossier créé par le PVC, qui contient les fichiers générés par le pod.
cat /data/pvc-8b6dcfbb-5556-41f3-9434-025784808f22/outfiledeployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:38:54 UTC 2025deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:38:55 UTC 2025deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:38:56 UTC 2025
Le pod écrit bien dans le fichier outfile
du volume NFS.
Passons le replica à 2 pour voir que les deux pods peuvent écrire dans le même fichier.
kubectl scale deployment deployment-nfs --replicas=2
Vérifiez que les deux pods écrivent bien dans le même fichier.
cat /data/pvc-8b6dcfbb-5556-41f3-9434-025784808f22/outfiledeployment-nfs-7fbbf89668-xktb6 Tue Mar 4 18:42:08 UTC 2025deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:42:09 UTC 2025deployment-nfs-7fbbf89668-xktb6 Tue Mar 4 18:42:09 UTC 2025deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:42:10 UTC 2025deployment-nfs-7fbbf89668-xktb6 Tue Mar 4 18:42:10 UTC 2025
Les deux pods écrivent bien dans le même fichier, ce qui prouve que le volume est bien partagé entre les deux pods.
Debug et troubleshooting des StorageClasses
L’utilisation des StorageClasses dans Kubernetes peut parfois poser des problèmes : volumes qui ne se créent pas, erreurs de provisionnement, ou encore PVC en attente (Pending). Ce chapitre présente les méthodes de diagnostic et les solutions aux erreurs courantes.
Vérifier la liste des StorageClasses disponibles
Avant toute chose, il faut s’assurer que la StorageClass utilisée existe bien dans le cluster :
kubectl get storageclass
Exemple de sortie :
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGEnfs-storage nfs.csi.k8s.io Retain Immediate true 2h
➡ Si votre StorageClass n’apparaît pas, assurez-vous qu’elle a bien été créée :
kubectl describe storageclass <nom-de-la-storageclass>
Si la StorageClass est introuvable, appliquez à nouveau son fichier YAML :
kubectl apply -f storageclass.yaml
Vérifier les PVC associés
Si un PersistentVolumeClaim (PVC) reste bloqué en Pending, vérifiez son état :
kubectl get pvc
Exemple de sortie avec un problème :
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEpvc-nfs Pending nfs-storage 3m
➡ Si le PVC reste en Pending, exécutez :
kubectl describe pvc pvc-nfs
Vous devriez voir des événements indiquant la raison du blocage.
Exemple d’erreur :
Warning ProvisioningFailed 2m csi-nfs-controller failed to provision volume with StorageClass "nfs-storage":provisioner nfs.csi.k8s.io failed to create volume: connection refused
Vérifier les événements Kubernetes
Les erreurs liées aux volumes sont souvent enregistrées dans les événements Kubernetes. Pour afficher les événements récents :
kubectl get events --sort-by=.metadata.creationTimestamp
Vous pouvez aussi vérifier les erreurs liées au driver CSI :
kubectl logs -l app=csi-nfs-controller -n kube-system
Si vous utilisez un autre provisionneur (AWS, Azure, Google Cloud), remplacez
csi-nfs-controller
par le nom du provisionneur concerné.
Vérifier les PV associés
Si un PVC est bien créé mais que le pod ne parvient pas à l’utiliser, vérifiez l’état du PersistentVolume (PV) :
kubectl get pv
Si le PV existe mais est en état Released ou Failed, il ne pourra plus être réutilisé.
➡ Solution : Supprimez le PV et laissez Kubernetes en créer un nouveau :
kubectl delete pv <nom-du-pv>
Tester le montage manuel d’un volume
Si un pod ne parvient pas à monter un volume, vous pouvez tester manuellement si le stockage fonctionne. Par exemple, pour un volume NFS :
-
Connectez-vous à un pod en cours d’exécution :
Terminal window kubectl run -it --rm --image=busybox test-pod -- /bin/sh -
Essayez de monter le partage NFS :
Terminal window mount -t nfs <NFS_SERVER_ADDRESS>:<NFS_SHARE_PATH> /mnt
Si cette commande échoue, le problème vient du serveur NFS.
Redémarrer les composants CSI
Si le provisionneur CSI semble bloqué, vous pouvez redémarrer ses pods :
kubectl delete pod -l app=csi-nfs-controller -n kube-system
Cela forcera Kubernetes à recréer les composants liés au provisionneur.
Conclusion
Dans ce guide, nous avons exploré comment utiliser une StorageClass pour gérer dynamiquement le stockage persistant dans Kubernetes. Nous avons mis en place un serveur NFS, configuré un PVC et intégré le volume dans un Déployment. Enfin, nous avons testé la persistance des données après la suppression d’un Pod.
Cette approche avec NFS est idéale pour un environnement de développement ou des charges de travail légères, mais en production, d’autres solutions plus performantes et résilientes peuvent être utilisées, comme :
- GlusterFS : un système de fichiers distribué offrant de la haute disponibilité et du scaling horizontal.
- Ceph : une solution de stockage objet, bloc et fichier, bien adaptée aux environnements Cloud et aux infrastructures nécessitant une forte résilience.
- Longhorn : un stockage distribué pour Kubernetes, offrant des fonctionnalités avancées de snapshot, backup et restauration.
Ces technologies, intégrables avec Kubernetes via CSI (Container Storage Interface), permettent d’aller plus loin dans l’automatisation et la gestion avancée du stockage.
À vous de jouer ! Expérimentez avec GlusterFS, Ceph ou d’autres solutions pour optimiser le stockage de vos applications Kubernetes !