Aller au contenu

Gestion dynamique du stockage avec les StorageClass

Mise à jour :

logo kubernetes

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 :

Terminal window
kubectl cluster-info
Kubernetes control plane is running at https://192.168.50.141:8443
CoreDNS 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 :

  1. Installer le serveur NFS :

    Terminal window
    sudo apt update
    sudo apt install nfs-server
  2. Créer un répertoire partagé :

    Terminal window
    sudo mkdir -p /data
  3. Configurer le partage NFS :

    Terminal window
    sudo echo "/data *(rw,sync,no_subtree_check)" >> /etc/exports
  4. Redémarrer le serveur NFS :

    Terminal window
    sudo systemctl restart nfs-kernel-server
  5. 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 :

  1. Pré-requis :

    • Disposer d’un serveur NFS fonctionnel et accessible depuis le cluster Kubernetes.
  2. 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/charts
      helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace kube-system --version v4.10.0
  3. Vérifier que le provisionneur est bien en place :

    Terminal window
    kubectl get pods -n kube-system -o wide | grep nfs
    csi-driver-nfs-controller-0 5/5 Running 0 2m
    csi-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.
  • 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 ou false).

  • 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.

  1. Créer un fichier storageclass-nfs.yaml :

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: nfs-csi
    provisioner: nfs.csi.k8s.io
    parameters:
    server: 192.168.20.121 # Remplacer par l'adresse IP du serveur NFS
    share: /data
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
    mountOptions:
    - nfsvers=4.1
  2. Appliquer la StorageClass dans Kubernetes :

    Terminal window
    kubectl apply -f storageclass-nfs.yaml
  3. Vérifier que la StorageClass a été créée :

    Terminal window
    kubectl get storageclass
    NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    nfs-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).

  1. Créer un fichier pvc-nfs.yaml :

    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: pvc-deployment-nfs
    namespace: default
    spec:
    accessModes:
    - ReadWriteMany # Accès en lecture/écriture pour plusieurs Pods
    resources:
    requests:
    storage: 10Gi
    storageClassName: nfs-csi # Utilisation de la StorageClass NFS définie précédemment

    Ce PVC demande 5 Go de stockage en ReadWriteMany, ce qui signifie qu’il peut être monté sur plusieurs Pods en même temps.

  2. Appliquer le PVC :

    Terminal window
    kubectl apply -f pvc-nfs.yaml
  3. Vérifier que le PVC est bien lié à un volume :

    Terminal window
    kubectl get pvc
    NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
    pvc-deployment-nfs Bound pvc-a7b9101f-644d-4bbd-8b7b-eaa8ced6f74a 10Gi RWX nfs-csi <unset> 8s

    Le 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

  1. Créer un fichier deployment.yaml :

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: deployment-nfs
    namespace: default
    spec:
    replicas: 1
    selector:
    matchLabels:
    name: deployment-nfs
    template:
    metadata:
    name: deployment-nfs
    labels:
    name: deployment-nfs
    spec:
    nodeSelector:
    "kubernetes.io/os": linux
    containers:
    - name: deployment-nfs
    image: mcr.microsoft.com/oss/nginx/nginx:1.19.5
    command:
    - "/bin/bash"
    - "-c"
    - set -euo pipefail; while true; do echo $(hostname) $(date) >> /mnt/nfs/outfile; sleep 1; done
    volumeMounts:
    - name: nfs
    mountPath: "/mnt/nfs"
    readOnly: false
    volumes:
    - name: nfs
    persistentVolumeClaim:
    claimName: pvc-deployment-nfs
  2. Appliquer le déploiement :

    Terminal window
    kubectl apply -f deployment.yaml
  3. Vérifier que le déploiement est en cours :

    Terminal window
    kubectl get pods
    deployment-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.

Terminal window
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.

Terminal window
cat /data/pvc-8b6dcfbb-5556-41f3-9434-025784808f22/outfile
deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:38:54 UTC 2025
deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:38:55 UTC 2025
deployment-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.

Terminal window
kubectl scale deployment deployment-nfs --replicas=2

Vérifiez que les deux pods écrivent bien dans le même fichier.

Terminal window
cat /data/pvc-8b6dcfbb-5556-41f3-9434-025784808f22/outfile
deployment-nfs-7fbbf89668-xktb6 Tue Mar 4 18:42:08 UTC 2025
deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:42:09 UTC 2025
deployment-nfs-7fbbf89668-xktb6 Tue Mar 4 18:42:09 UTC 2025
deployment-nfs-7fbbf89668-md8gc Tue Mar 4 18:42:10 UTC 2025
deployment-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 :

Terminal window
kubectl get storageclass

Exemple de sortie :

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-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 :

Terminal window
kubectl describe storageclass <nom-de-la-storageclass>

Si la StorageClass est introuvable, appliquez à nouveau son fichier YAML :

Terminal window
kubectl apply -f storageclass.yaml

Vérifier les PVC associés

Si un PersistentVolumeClaim (PVC) reste bloqué en Pending, vérifiez son état :

Terminal window
kubectl get pvc

Exemple de sortie avec un problème :

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Pending nfs-storage 3m

Si le PVC reste en Pending, exécutez :

Terminal window
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 :

Terminal window
kubectl get events --sort-by=.metadata.creationTimestamp

Vous pouvez aussi vérifier les erreurs liées au driver CSI :

Terminal window
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) :

Terminal window
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 :

Terminal window
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 :

  1. Connectez-vous à un pod en cours d’exécution :

    Terminal window
    kubectl run -it --rm --image=busybox test-pod -- /bin/sh
  2. 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 :

Terminal window
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 !