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

ModulesCKAD - Volumes et Persistance

Module

Maîtrise les Volumes Kubernetes, PersistentVolumes et PersistentVolumeClaims pour stocker et persister les données.

  • 1 heure 30
  • Avancé

Formation 100 % Linux

Tous les modules nécessitent un environnement Linux. Si vous êtes sur Windows, installez d'abord WSL (Windows Subsystem for Linux) avant de continuer.

CKAD - Volumes et Persistance

🎯 Objectifs

Dans ce module, tu vas :

  • ✅ Comprendre les différents types de Volumes
  • ✅ Utiliser les Volumes avec tes Pods
  • ✅ Maîtriser PersistentVolumes et PersistentVolumeClaims
  • ✅ Gérer le cycle de vie des données
  • ✅ Déboguer les problèmes de stockage
  • ✅ Utiliser les StorageClasses

📋 Prérequis

  • Module Kubernetes - Intermédiaire complété
  • Module CKAD - Préparation lu
  • Module CKAD - Applications complété

📖 Pourquoi ce module ?

Les Volumes et Stockage c'est 15% de la CKAD, mais c'est crucial pour les applications avec données (bases de données, caches, uploads de fichiers).

Tu dois maîtriser :

  • Les Volumes simples (emptyDir, hostPath)
  • Les Volumes persistants (PV, PVC)
  • Comment connecter une app à du stockage

🔧 Types de Volumes

Problème

Les Pods sont éphémères. Quand un Pod supprime, ses données disparaissent. Comment on persiste les données ?

Solution : Volumes

Kubernetes offre plusieurs types de volumes selon tes besoins.

emptyDir : Volume temporaire (défaut)

Un volume vide qui existe pendant la vie du Pod. Parfait pour les fichiers temporaires.

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: temp-data
      mountPath: /tmp/data
  - name: log-cleaner  # Sidecar
    image: busybox
    volumeMounts:
    - name: temp-data
      mountPath: /tmp/data
  volumes:
  - name: temp-data
    emptyDir: {}

Cas d'usage :

  • Fichiers temporaires
  • Cache entre conteneurs d'un même Pod
  • Logs avant d'être envoyés ailleurs

hostPath : Accès à la machine

Montage un répertoire du Node dans le Pod. Dangereux en production (lie le Pod à un Node spécifique).

yaml
apiVersion: v1
kind: Pod
metadata:
  name: debug-pod
spec:
  containers:
  - name: debug
    image: busybox
    volumeMounts:
    - name: host-logs
      mountPath: /host/logs
  volumes:
  - name: host-logs
    hostPath:
      path: /var/log
      type: Directory

Cas d'usage :

  • Débugage (accéder aux logs du Node)
  • Apps avec accès hardware
  • Jamais en production normale

Volumes cloud

Montage du stockage du cloud provider.

yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-storage
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    awsElasticBlockStore:
      volumeID: vol-1234567890abcdef0
      fsType: ext4

Types :

  • awsElasticBlockStore (AWS EBS)
  • gcePersistentDisk (Google Cloud)
  • azureDisk (Azure)
  • cephfs (Ceph)

💾 PersistentVolume & PersistentVolumeClaim

Problème

Demander directement un volume spécifique (EBS, GCE) couple ton Deployment au cloud provider. Tu veux de l'abstraction.

Solution : PV & PVC

  • PersistentVolume (PV) : Ressource de stockage (créée par admin)
  • PersistentVolumeClaim (PVC) : Requête pour du stockage (utilisée par développeur)

Workflow

Développeur crée PVC → Kubernetes cherche un PV libre et compatible → Match → Pod utilise la PVC

Créer un PersistentVolume

L'admin cluster crée les PV (avec un cloud provider) :

yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-1
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce      # Accès : un seul Pod en lecture/écriture
  persistentVolumeReclaimPolicy: Delete  # Supprimer quand la PVC est supprimée
  storageClassName: standard
  awsElasticBlockStore:
    volumeID: vol-1234567890abcdef0
    fsType: ext4

Créer une PersistentVolumeClaim

Le développeur demande du stockage :

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

Utiliser la PVC dans un Pod

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: app
    image: myapp:1.0
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: app-data

Access Modes (modes d'accès)

ModeComportement
ReadWriteOnce (RWO)Un seul Pod, lecture/écriture
ReadOnlyMany (ROX)Plusieurs Pods, lecture seule
ReadWriteMany (RWX)Plusieurs Pods, lecture/écriture (NFS, EFS)
ReadWriteOncePod (RWOP)Un seul Pod, lecture/écriture (Kubernetes 1.22+)

Reclaim Policy

PolicyComportement
DeleteSupprimer le volume quand la PVC est supprimée
RetainGarder le volume (manuel cleanup)
RecycleVider le volume (deprecated)

🏭 StorageClass : Provisionner automatiquement

Problème

L'admin doit créer manuellement les PV. Si tu as besoin de 100 volumes, c'est fastidieux.

Solution : StorageClass

Une StorageClass automatise la création de PV.

Créer une StorageClass

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: ebs.csi.aws.com  # Provisionneur (AWS, GCP, Azure, etc.)
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true

Utiliser une StorageClass dans une PVC

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: fast-ssd  # Référence à la StorageClass
  resources:
    requests:
      storage: 20Gi

Quand tu créis cette PVC, Kubernetes appelle le provisionneur EBS, qui crée automatiquement un volume EBS et un PV.

StorageClass par défaut

La plupart des clusters ont une StorageClass par défaut. Si tu omets storageClassName, c'est celle-ci qui est utilisée.

bash
# Voir les StorageClasses
k get storageclass

# Voir la default
k get storageclass default -o yaml

🗂️ Volumes dans un Deployment

Problème

Comment partager du stockage entre les replicas d'un Deployment ?

Si tu utilises ReadWriteOnce, seul un Pod peut avoir le volume. Les autres répliques ne peuvent pas l'utiliser.

Solution :

  • Soit chaque replica a son propre PVC (possible)
  • Soit tu utilises un volume ReadWriteMany (NFS, EFS, AzureFiles)
  • Soit tu utilises un StatefulSet avec volumeClaimTemplates

Exemple : Deployment avec ReadWriteOnce

Chaque replica a son propre PVC :

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data-1
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data-2
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      # Note : ça ne marche pas vraiment, chaque replica irait sur la même PVC
      # Solution : StatefulSet ou volumes cloud ReadWriteMany
      containers:
      - name: app
        image: app:1.0
        volumeMounts:
        - name: data
          mountPath: /data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: app-data-1

Meilleure solution : StatefulSet avec volumeClaimTemplates

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: app
spec:
  serviceName: app
  replicas: 3
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: app
        image: app:1.0
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: standard
      resources:
        requests:
          storage: 5Gi

Kubernetes crée automatiquement :

  • data-app-0
  • data-app-1
  • data-app-2

Chaque replica a sa propre PVC et son propre stockage.


🔧 Déboguer les problèmes de stockage

PVC en "Pending"

bash
# Voir l'état
k get pvc
k describe pvc app-data

# Output possible :
# Status: Pending
# Events:
#   Type    Reason                Age   Message
#   ----    ------                ----  -------
#   Normal  ExternalProvisioning  5s    waiting for a volume to be created
#   Normal  Provisioning          2s    Provisioning succeeded

Solutions :

  • Attendre que le provisionneur crée le volume (peut prendre quelques secondes)
  • Vérifier que la StorageClass existe
  • Vérifier les logs du provisionneur

Pod ne peut pas monter le volume

bash
# Voir l'erreur
k describe pod myapp

# Output possible :
# Volumes:
#   data:
#     Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim)
#     ClaimName:  app-data
#     ReadOnly:   false
# Events:
#   Type     Reason       Message
#   ----     ------       -------
#   Warning  FailedMount  MountVolume.MountDevice failed for volume "pv-1"

Solutions :

  • Vérifier que la PVC existe
  • Vérifier les access modes (RWO vs RWX)
  • Vérifier que le PV et le Pod sont sur le même Node (si hostPath)
  • Vérifier les logs du kubelet du Node

Données perdues après restart

Si tu utilises emptyDir, les données disparaissent. Utilise une PVC à la place.

bash
# Mauvais
volumes:
- name: data
  emptyDir: {}

# Bon
volumes:
- name: data
  persistentVolumeClaim:
    claimName: app-data

🔧 Exemple complet : App avec persistance

yaml
---
# StorageClass (peut être fourni par le cloud)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: app-storage
provisioner: ebs.csi.aws.com

---
# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes: ["ReadWriteOnce"]
  storageClassName: app-storage
  resources:
    requests:
      storage: 20Gi

---
# Deployment avec volume
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 1  # Avec RWO, max 1 replica par PVC
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: app
        image: app:1.0
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: data
          mountPath: /app/data
        - name: cache
          mountPath: /tmp/cache
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: app-data
      - name: cache
        emptyDir: {}

---
# Service
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  type: ClusterIP
  selector:
    app: app
  ports:
  - port: 80
    targetPort: 8080

📊 Résumé

TypePersistancePartageCas d'usage
emptyDir❌ NonEntre conteneursFichiers temp
hostPath✅ OuiNonDébugage
PVC/RWO✅ Oui❌ NonMonolithes
PVC/RWX✅ Oui✅ OuiPartage fichiers
StatefulSet + PVC✅ OuiChacun sonBases de données

🚀 Prochaines Étapes

Tu as maintenant couvert tous les domaines de la CKAD !

  • Revois les modules précédents
  • Fais des exercices pratiques
  • Pratique sur des clusters réels
  • Passe l'examen CKAD officiel 🎓
Retour aux modules

Sur cette page

  • 🎯 Objectifs
  • 📋 Prérequis
  • 📖 Pourquoi ce module ?
  • 🔧 Types de Volumes
  • Problème
  • emptyDir : Volume temporaire (défaut)
  • hostPath : Accès à la machine
  • Volumes cloud
  • 💾 PersistentVolume & PersistentVolumeClaim
  • Problème
  • Workflow
  • Créer un PersistentVolume
  • Créer une PersistentVolumeClaim
  • Utiliser la PVC dans un Pod
  • Access Modes (modes d'accès)
  • Reclaim Policy
  • 🏭 StorageClass : Provisionner automatiquement
  • Problème
  • Créer une StorageClass
  • Utiliser une StorageClass dans une PVC
  • StorageClass par défaut
  • 🗂️ Volumes dans un Deployment
  • Problème
  • Exemple : Deployment avec ReadWriteOnce
  • Meilleure solution : StatefulSet avec volumeClaimTemplates
  • 🔧 Déboguer les problèmes de stockage
  • PVC en "Pending"
  • Pod ne peut pas monter le volume
  • Données perdues après restart
  • 🔧 Exemple complet : App avec persistance
  • 📊 Résumé
  • 🚀 Prochaines Étapes