Un guide pratique pour construire un laboratoire de volumes Kubernetes sûr sur votre machine locale afin de tester les PersistentVolumes, PersistentVolumeClaims, StorageClasses et les configurations de stockage des pods.

## Introduction

Les volumes Kubernetes sont un élément fondamental des applications avec état, mais ils sont souvent mal compris. Un laboratoire local vous offre un environnement sûr et isolé pour expérimenter avec les PersistentVolumes (PV), les PersistentVolumeClaims (PVC) et les StorageClasses sans risquer les données de production. Ce guide vous accompagne dans la mise en place d'un tel laboratoire en utilisant des outils courants comme Minikube ou kind, la création de stockage local et l'exécution de tests pratiques. À la fin, vous disposerez d'un flux de travail reproductible pour apprendre et déboguer le comportement des volumes.

Nous commencerons par la configuration de l'environnement, puis nous créerons une StorageClass et un PVC, attacherons le volume à un pod, vérifierons la persistance, explorerons les modes de défaillance et la récupération, et terminerons par une liste de contrôle opérationnelle. Chaque étape comprend des commandes concrètes, des extraits YAML et les résultats attendus pour que vous puissiez suivre.

## Inventaire des versions et de l'environnement

Avant de commencer, assurez-vous d'avoir installé et compatible les éléments suivants :

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Composant</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Version recommandée</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Remarques</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Kubernetes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">v1.24 ou ultérieure</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Minikube ou kind fonctionnent tous deux</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">kubectl</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">v1.24 ou ultérieure</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Faites correspondre la version mineure au cluster</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Minikube</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">v1.26 ou ultérieure</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ou kind v0.14 ou ultérieure</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Moteur de conteneurs</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Docker ou containerd</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Minikube peut utiliser sa propre VM</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Système d&#39;exploitation hôte</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Linux, macOS ou Windows</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Linux est le plus simple pour les volumes locaux</td></tr></tbody>
</table>
</div>
Ce laboratoire utilise Minikube avec le pilote Docker par défaut. Vérifiez votre environnement avec :

kubectl version --client
# Exemple de sortie : Client Version: v1.26.3
minikube version
# Exemple de sortie : minikube version: v1.29.0 
 Démarrez votre cluster :

minikube start --driver=docker --kubernetes-version=v1.26.3
# Exemple de sortie : Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default. 
 Vérifiez que le cluster est opérationnel :

kubectl get nodes
# Sortie attendue :
# NAME STATUS ROLES AGE VERSION
# minikube Ready control-plane 1m v1.26.3 
 Si votre environnement utilise kind, les étapes sont similaires, mais les volumes hostPath seront sur le conteneur du nœud kind plutôt que sur une VM. Les commandes pour créer des PVC et des pods restent les mêmes.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 1 sur 2

Quelle est l'approche recommandée pour la sécurité et l'isolation des données selon la documentation Kubernetes ?

- Utilisation de volumes hostPath
- Utilisation de l'approvisionnement dynamique de volumes
- Utilisation de volumes locaux
- Utilisation de l'approvisionnement statique

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">La référence indique que pour la sécurité et l&#39;isolation des données, l&#39;approvisionnement dynamique de volumes est recommandé et que les types de volumes utilisant les ressources du nœud doivent être évités.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Chemin de configuration sûr

Pour un laboratoire sûr, utilisez une StorageClass avec volumeBindingMode: Immediate et un provisionneur de chemin local. Minikube fournit une StorageClass standard intégrée qui provisionne dynamiquement des volumes hostPath. Vous pouvez également créer votre propre StorageClass pour plus de contrôle.

Tout d'abord, inspectez les StorageClasses existantes :

kubectl get storageclass
# Sortie attendue :
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# standard (default) k8s.io/minikube-hostpath Delete Immediate false 1m 
 La sortie montre une StorageClass par défaut nommée standard avec le provisionneur k8s.io/minikube-hostpath . Ce provisionneur crée un répertoire sous /tmp/hostpath-provisioner/ sur le nœud Minikube pour chaque volume. Comme la politique de récupération est Delete , la suppression du PVC supprimera le répertoire associé.

Si vous avez besoin d'une StorageClass personnalisée, créez un fichier YAML custom-sc.yaml :

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: local-hp
provisioner: k8s.io/minikube-hostpath
reclaimPolicy: Retain
volumeBindingMode: Immediate 
 Appliquez-le :

kubectl apply -f custom-sc.yaml
# Sortie attendue : storageclass.storage.k8s.io/local-hp created 
 Pour ce laboratoire, nous utiliserons la classe standard par défaut pour plus de simplicité.

Créez maintenant un PVC pour demander du stockage à cette StorageClass. Enregistrez le contenu suivant sous pvc.yaml :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: lab-pvc
spec:
 accessModes:
 - ReadWriteOnce
 resources:
 requests:
 storage: 1Gi 
 Appliquez-le :

kubectl apply -f pvc.yaml
# Sortie attendue : persistentvolumeclaim/lab-pvc created 
 Vérifiez l'état du PVC :

kubectl get pvc lab-pvc
# Sortie attendue :
# NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# lab-pvc Bound pvc-1234abcd-56ef-7890-ghij-klmnopqrstuv 1Gi RWO standard 5s 
 Un PV a été automatiquement créé. Affichez-le :

kubectl get pv
# Sortie attendue :
# NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
# pvc-1234abcd-56ef-7890-ghij-klmnopqrstuv 1Gi RWO Delete Bound default/lab-pvc standard 10s 
 Le PV est lié au PVC. Notez que la politique de récupération est Delete , ce qui signifie que lorsque le PVC est supprimé, le PV et les données sous-jacentes seront supprimés.

Déployez maintenant un pod qui utilise ce PVC. Enregistrez le contenu suivant sous pod.yaml :

apiVersion: v1
kind: Pod
metadata:
 name: volume-test
spec:
 containers:
 - name: app
 image: nginx:latest
 volumeMounts:
 - mountPath: /usr/share/nginx/html
 name: data
 volumes:
 - name: data
 persistentVolumeClaim:
 claimName: lab-pvc 
 Appliquez le pod :

kubectl apply -f pod.yaml
# Sortie attendue : pod/volume-test created 
 Vérifiez que le pod est en cours d'exécution :

kubectl get pod volume-test
# Sortie attendue :
# NAME READY STATUS RESTARTS AGE
# volume-test 1/1 Running 0 10s 

## Vérification et diagnostics

 Pour vérifier que le volume fonctionne, écrivez un fichier depuis l'intérieur du pod, puis vérifiez-le depuis l'hôte ou un autre pod.

Tout d'abord, exécutez une commande dans le pod pour créer un fichier :

kubectl exec -it volume-test -- sh -c 'echo Hello from volume > /usr/share/nginx/html/test.txt'
# Aucune sortie en cas de succès 
 Lisez le fichier depuis le pod :

kubectl exec volume-test -- cat /usr/share/nginx/html/test.txt
# Sortie attendue : Hello from volume 
 Maintenant, inspectez le chemin hôte où le volume est monté. Pour Minikube, vous pouvez utiliser minikube ssh :

minikube ssh
# À l'intérieur de la VM Minikube
sudo ls /tmp/hostpath-provisioner/default/lab-pvc
# Sortie attendue : test.txt
sudo cat /tmp/hostpath-provisioner/default/lab-pvc/test.txt
# Sortie attendue : Hello from volume 
 Cela confirme que le volume persiste sur l'hôte. Quittez la session SSH avec exit .

Pour tester la persistance lors des redémarrages de pod, supprimez le pod et recréez-le :

kubectl delete pod volume-test
# Sortie attendue : pod "volume-test" deleted
kubectl apply -f pod.yaml
# Sortie attendue : pod/volume-test created 
 Après le démarrage du pod, vérifiez que le fichier existe toujours :

kubectl exec volume-test -- cat /usr/share/nginx/html/test.txt
# Sortie attendue : Hello from volume 
 Pour voir des informations détaillées sur le volume, décrivez le PVC et le PV :

kubectl describe pvc lab-pvc
# Recherchez les Events :
# Normal ProvisioningSucceeded 10s k8s.io/minikube-hostpath_minikube Successfully provisioned volume pvc-1234abcd-56ef-7890-ghij-klmnopqrstuv 
 kubectl describe pv pvc-1234abcd-56ef-7890-ghij-klmnopqrstuv
# Recherchez Source :
# Type: HostPath (path: /tmp/hostpath-provisioner/default/lab-pvc) 
 Vérifiez la capacité et l'utilisation du stockage depuis l'intérieur du pod :

kubectl exec volume-test -- df -h /usr/share/nginx/html
# Exemple de sortie :
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 9.7G 1.2G 8.5G 12% /usr/share/nginx/html 

 Question rapide 2 sur 2

Quel est le but d'une PersistentVolumeClaim ?

- Pour définir une classe de stockage
- Pour demander du stockage par un utilisateur
- Pour provisionner du stockage dynamiquement
- Pour gérer le stockage sur un nœud

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">Une PersistentVolumeClaim est une demande de stockage par un utilisateur, de la même manière que les Pods consomment les ressources du nœud.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Modes de défaillance et récupération

Les défaillances courantes dans un laboratoire local incluent un PVC bloqué en Pending , un pod qui ne parvient pas à monter le volume ou une perte de données due à la politique de récupération.

### PVC en attente (Pending)

Si le PVC n'est pas lié, vérifiez la StorageClass et le provisionneur :

kubectl describe pvc lab-pvc
# Recherchez les Events :
# Warning ProvisioningFailed 10s k8s.io/minikube-hostpath_minikube failed to provision volume with StorageClass "standard": ... 
 Si vous utilisez une StorageClass personnalisée, assurez-vous que le provisionneur est correct et disponible. Pour Minikube, la classe standard fonctionne immédiatement.

### Erreurs de montage du pod

Si le pod ne démarre pas avec une erreur de montage, vérifiez l'état du PVC et les événements du pod :

kubectl get pvc
kubectl describe pod volume-test
# Recherchez les Events :
# Warning FailedMount 30s kubelet MountVolume.SetUp failed for volume "pvc-..." : ... 
 Parfois, le problème est que le volume est déjà monté par un autre pod avec ReadWriteOnce sur un nœud différent. Dans un Minikube à nœud unique, cela est rare.

### Perte de données lors de la suppression du PVC

La politique de récupération par défaut pour la StorageClass standard est Delete . Si vous supprimez le PVC, le PV et les données hostPath sont supprimés.

kubectl delete pvc lab-pvc
# Sortie attendue : persistentvolumeclaim "lab-pvc" deleted 
 Si vous devez conserver les données, changez la politique de récupération en Retain sur le PV avant de supprimer le PVC. Cependant, pour un laboratoire, vous pouvez recréer le PVC et le pod à partir de zéro.

### Étapes de récupération

- Vérifiez les événements du cluster : kubectl get events --sort-by=.metadata.creationTimestamp

- Vérifiez la StorageClass : kubectl get sc

- Inspectez le hostPath sur le nœud si vous utilisez hostPath : minikube ssh et parcourez /tmp/hostpath-provisioner/...

- Recréez les ressources si nécessaire.

Pour réinitialiser complètement le laboratoire, supprimez toutes les ressources créées :

kubectl delete pod volume-test
kubectl delete pvc lab-pvc
# Aucune sortie, mais les ressources sont supprimées 
 Puis réappliquez vos fichiers YAML.

## Liste de contrôle opérationnelle

Utilisez cette liste de contrôle pour des opérations de laboratoire reproductibles :

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Étape</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Commande / Action</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Résultat attendu</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Démarrer le cluster</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">minikube start</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Cluster prêt</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier la StorageClass</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get sc</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">standard</code> listée</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Appliquer le PVC</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl apply -f pvc.yaml</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">PVC créé</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier que le PVC est lié</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get pvc</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">STATUS Bound</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Appliquer le pod</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl apply -f pod.yaml</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Pod en cours d&#39;exécution</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Écrire un fichier de test</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl exec ... -- sh -c &#39;echo test &gt; /mnt/test.txt&#39;</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Aucune erreur</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Lire le fichier de test</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl exec ... -- cat /mnt/test.txt</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Sortie <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">test</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Supprimer le pod et le recréer</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl delete pod ... &amp;&amp; kubectl apply -f pod.yaml</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Les données persistent</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Nettoyer</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl delete pod, pvc</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ressources supprimées</td></tr></tbody>
</table>
</div>
Pour une inspection plus approfondie :

- kubectl describe pvc affiche les événements de provisionnement.

- kubectl describe pv affiche les détails de la source du volume.

- minikube ssh permet des vérifications de fichiers au niveau de l'hôte.

Conservez les fichiers YAML sous contrôle de version pour des laboratoires reproductibles.

## Conclusion

Vous disposez maintenant d'un laboratoire de volumes Kubernetes fonctionnel sur votre machine locale. Vous avez appris à configurer un cluster, créer une StorageClass, provisionner un PVC, l'attacher à un pod, vérifier la persistance des données et récupérer des défaillances courantes. Ce laboratoire sert de base pour explorer des sujets plus avancés comme les StatefulSets, le provisionnement dynamique avec différents backends de stockage et les pilotes CSI. N'oubliez pas de commencer avec un scénario étroit et de l'élargir progressivement, comme le suggèrent les preuves de recherche pour un développement local efficace. Gardez votre environnement propre et vos fichiers YAML organisés pour un apprentissage reproductible.

Pour étendre ce laboratoire, expérimentez avec différents modes d'accès, politiques de récupération et StorageClasses personnalisées. Essayez de déployer plusieurs pods partageant un volume ReadWriteMany, ou utilisez un StatefulSet pour gérer le stockage persistant de chaque réplica. Ces exercices approfondiront votre compréhension du stockage Kubernetes et vous prépareront aux scénarios de production.