DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesKubernetes Intermédiaire : Deployments, Services et Volumes04 - Volumes : emptyDir et PersistentVolumeClaims

Détails

  • 30 minutes
  • Intermédiaire

Objectifs

  • Utiliser un volume emptyDir pour partager des données entre conteneurs
  • Créer un PersistentVolumeClaim (PVC) pour stocker des données persistantes
  • Monter un PVC dans un Deployment et vérifier la persistance des données
  • Comprendre le cycle de vie des volumes vs les pods
Module Kubernetes Intermédiaire : Deployments, Services et Volumes

Exercice 04 : Volumes - emptyDir et PersistentVolumeClaims

🎯 Objectifs

À la fin de cet exercice, vous serez capable de :

  • ✅ Créer un volume emptyDir partagé entre deux conteneurs d'un même pod
  • ✅ Créer un PVC et l'associer à un Deployment
  • ✅ Écrire des données dans un volume persistant et vérifier qu'elles survivent à un redémarrage de pod
  • ✅ Distinguer les différents types de volumes et leurs cas d'usage

Durée estimée : 30 minutes

Difficulté : ⭐⭐☆☆☆ (Intermédiaire)

Prérequis : Exercice 01 complété, namespace intermediaire existant


📖 Contexte

Par défaut, les fichiers créés dans un conteneur disparaissent avec lui. Pour une base de données, un cache Redis ou un stockage d'upload de fichiers, il faut de la persistance. Kubernetes propose deux niveaux :

  • emptyDir : stockage temporaire partagé entre les conteneurs d'un pod (disparaît avec le pod)
  • PersistentVolume (PV) + PVC : stockage persistant qui survit à la mort du pod

📋 Énoncé

Explorez les volumes emptyDir puis créez un stockage persistant avec PVC.


🧭 Déroulement de l'exercice

Tâche 1 : Volume emptyDir - partage entre conteneurs

Un emptyDir est utile pour partager des fichiers entre deux conteneurs dans le même pod (sidecar pattern) : par exemple, un conteneur qui génère des logs et un conteneur qui les traite.

bash
cat > emptydir-pod.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: shared-volume
  namespace: intermediaire
spec:
  volumes:
    - name: data-shared
      emptyDir: {}   # Volume vide créé quand le pod démarre

  containers:
    # Conteneur 1 : écrit des données dans le volume
    - name: writer
      image: busybox:latest
      command: ["/bin/sh", "-c"]
      args:
        - |
          while true; do
            echo "$(date): message from writer" >> /data/messages.log
            sleep 5
          done
      volumeMounts:
        - name: data-shared
          mountPath: /data

    # Conteneur 2 : lit les données depuis le même volume
    - name: reader
      image: busybox:latest
      command: ["/bin/sh", "-c"]
      args:
        - |
          while true; do
            echo "=== Reader sees:"
            cat /data/messages.log 2>/dev/null || echo "(vide)"
            sleep 10
          done
      volumeMounts:
        - name: data-shared
          mountPath: /data   # Même chemin de montage
EOF

kubectl apply -f emptydir-pod.yaml

# Suivre les logs du reader
kubectl logs shared-volume -c reader -n intermediaire -f
bash
# Écrire depuis le conteneur writer directement
kubectl exec shared-volume -c writer -n intermediaire -- \
  sh -c 'echo "message manuel" >> /data/messages.log'

# Vérifier que le reader le voit
kubectl exec shared-volume -c reader -n intermediaire -- \
  cat /data/messages.log

Indice : Le volume emptyDir est créé vide au démarrage du pod. Il est partagé entre TOUS les conteneurs du pod. Si le pod est supprimé, les données sont perdues. Si un conteneur redémarre (sans supprimer le pod), les données sont conservées.


Tâche 2 : Créer un PersistentVolumeClaim

bash
cat > pvc.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
  namespace: intermediaire
spec:
  accessModes:
    - ReadWriteOnce     # Montable par un seul nœud en lecture/écriture
  storageClassName: standard   # StorageClass de minikube
  resources:
    requests:
      storage: 1Gi
EOF

kubectl apply -f pvc.yaml

# Voir l'état du PVC : STATUS doit passer de Pending à Bound
kubectl get pvc -n intermediaire -w

Indice : Sur minikube, la StorageClass standard provisionne automatiquement un volume (provisionnement dynamique). Sur un vrai cluster AWS, on utiliserait gp2 ou gp3; sur GKE standard-rwo. Le PVC passe de Pending à Bound une fois qu'un PersistentVolume lui est associé.


Tâche 3 : Utiliser le PVC dans un Deployment

bash
cat > postgres-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-demo
  namespace: intermediaire
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres-demo
  template:
    metadata:
      labels:
        app: postgres-demo
    spec:
      volumes:
        - name: postgres-data
          persistentVolumeClaim:
            claimName: data-pvc     # Référencer le PVC créé

      containers:
        - name: postgres
          image: postgres:16-alpine
          env:
            - name: POSTGRES_PASSWORD
              value: "testpassword"
            - name: POSTGRES_DB
              value: "demo"
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data  # Les données sont persistées ici
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 512Mi
EOF

kubectl apply -f postgres-deployment.yaml

# Attendre que le pod soit Running
kubectl get pods -n intermediaire -l app=postgres-demo -w

Tâche 4 : Tester la persistance

bash
# Obtenir le nom du pod
POD=$(kubectl get pods -n intermediaire -l app=postgres-demo -o jsonpath='{.items[0].metadata.name}')

# Créer des données dans la base
kubectl exec "$POD" -n intermediaire -- \
  psql -U postgres -d demo -c "CREATE TABLE test (id serial PRIMARY KEY, message TEXT);"

kubectl exec "$POD" -n intermediaire -- \
  psql -U postgres -d demo -c "INSERT INTO test (message) VALUES ('Données persistées !');"

kubectl exec "$POD" -n intermediaire -- \
  psql -U postgres -d demo -c "SELECT * FROM test;"

# Supprimer le pod (le Deployment en crée un nouveau)
kubectl delete pod "$POD" -n intermediaire

# Attendre le nouveau pod
kubectl get pods -n intermediaire -l app=postgres-demo -w

# Vérifier que les données sont toujours là !
NEW_POD=$(kubectl get pods -n intermediaire -l app=postgres-demo -o jsonpath='{.items[0].metadata.name}')
kubectl exec "$NEW_POD" -n intermediaire -- \
  psql -U postgres -d demo -c "SELECT * FROM test;"

Vérification : La table et les données sont présentes dans le nouveau pod. Le volume (PVC) survit à la mort du pod.


✅ Vérification du résultat

  • Le volume emptyDir est bien partagé entre les deux conteneurs du pod
  • kubectl get pvc -n intermediaire affiche le PVC en état Bound
  • Les données PostgreSQL survivent à la suppression et recréation du pod
  • kubectl get pv liste le PersistentVolume auto-créé par minikube

💡 À retenir

TypeSurvit à la mort du pod ?Cas d'usage
emptyDir❌ NonSidecar, fichiers temporaires, cache
hostPath✅ Oui (si même nœud)Dev seulement (déconseillé en prod)
PVC✅ OuiBases de données, fichiers utilisateurs

Relation PVC / PV :

PVC (demande de stockage) ← lie → PV (stockage réel)
                ↑ provisionné automatiquement par StorageClass

✨ Solution Complète

yaml
# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mon-pvc
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

# Dans le Deployment
volumes:
  - name: mon-volume
    persistentVolumeClaim:
      claimName: mon-pvc
containers:
  - volumeMounts:
      - name: mon-volume
        mountPath: /data
Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement de l'exercice
  • Tâche 1 : Volume emptyDir - partage entre conteneurs
  • Tâche 2 : Créer un PersistentVolumeClaim
  • Tâche 3 : Utiliser le PVC dans un Deployment
  • Tâche 4 : Tester la persistance
  • ✅ Vérification du résultat
  • 💡 À retenir
  • ✨ Solution Complète