Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Gestion du stockage

Vue d'ensemble

Le stockage dans Kubernetes est géré via un système de ressources découplant les Pods de l'infrastructure de stockage sous-jacente. Ce document décrit les options de stockage disponibles sur le cluster Kubernetes SdV, leurs cas d'usage, leurs limites et les bonnes pratiques associées.

Concepts clés

ConceptDescriptionRôle
PersistentVolume (PV)Ressource de stockage physique dans le clusterReprésente un espace de stockage disponible
PersistentVolumeClaim (PVC)Demande de stockage par un utilisateurConsomme un PV et l'attache à un Pod
StorageClassDéfinit les classes de stockage disponiblesPermet le provisionnement dynamique des PV
VolumeSnapshotPoint de sauvegarde d'un volumePermet la restauration et la duplication

Stockage Persistant

SdV propose dans son catalogue une classe de stockage NFS pour le stockage persistant des données des workloads Kubernetes. Cette solution est adaptée au stockage de fichiers nécessitant un accès concurrent depuis plusieurs Pods.

StorageClasses disponibles

StorageClassTypePolitique de rétentionProvisionnementCas d'usage recommandé
managed-nfs-storagefichierDeleteDynamiqueDéveloppement, staging, données temporaires
managed-nfs-storage-retainfichierRetainDynamiqueProduction, données critiques nécessitant une conservation manuelle

Politique de rétention

  • Delete : Le PersistentVolume et les données associées sont automatiquement supprimés lorsque le PVC est détruit. ⚠️ Risque de perte de données.
  • Retain : Le PersistentVolume est conservé même après la suppression du PVC. Les données restent disponibles et doivent être supprimées manuellement par un administrateur.

Stockage en mode fichier (NFS)

Cette StorageClass est basée sur le protocole NFS (Network File System). Elle permet de partager un système de fichiers entre plusieurs Pods simultanément.

Caractéristiques

CritèreValeurCommentaire
ProtocoleNFSv3/NFSv4Protocole réseau pour partage de fichiers
PerformanceMoyenne (réseau)Latence dépendante du réseau (~1-5ms)
IOPSFaibles à moyennesNon adapté aux charges intensives en I/O
Débit~100-500 MB/sDépendant du réseau et de la charge
Accès concurrentOui (ReadWriteMany)Plusieurs Pods peuvent lire/écrire simultanément

Cas d'usage recommandés

Adapté pour :

  • Applications web stateless (assets, uploads utilisateurs)
  • Partage de fichiers de configuration entre Pods
  • Stockage de fichiers médias (images, vidéos, documents)
  • Logs d'applications à centraliser
  • Dossiers partagés pour traitement batch
  • CMS (WordPress, Drupal, etc.)
  • Applications nécessitant ReadWriteMany

Déconseillé pour :

  • Bases de données relationnelles (PostgreSQL, MySQL, MariaDB)
  • Bases de données NoSQL nécessitant des IOPS élevées (Cassandra, MongoDB)
  • Applications nécessitant des performances disque élevées
  • Stockage de données nécessitant une forte cohérence transactionnelle
  • Workloads avec des milliers d'opérations I/O par seconde

Modes d'accès supportés

ModeAbréviationDescriptionSupport NFS
ReadWriteOnceRWOLecture-écriture par un seul nœudOui
ReadOnlyManyROXLecture seule par plusieurs nœudsOui
ReadWriteManyRWXLecture-écriture par plusieurs nœudsOui (principal avantage NFS)

Exemple de PersistentVolumeClaim

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: webapp-storage
  namespace: production
  labels:
    app: webapp
    environment: production
  annotations:
    description: "Stockage partagé pour les uploads utilisateurs"
spec:
  storageClassName: managed-nfs-storage-retain
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

Utilisation dans un Pod

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webapp-pod
  namespace: production
  labels:
    app: webapp
spec:
  containers:
  - name: webapp
    image: myapp:1.0.0
    volumeMounts:
    - name: persistent-storage
      mountPath: /var/www/html/uploads
      subPath: uploads  # Utilise un sous-répertoire du PVC
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: webapp-storage

Exemple avec Deployment

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: myapp:1.0.0
        volumeMounts:
        - name: shared-data
          mountPath: /data/shared
          readOnly: false
      volumes:
      - name: shared-data
        persistentVolumeClaim:
          claimName: webapp-storage

Autres types de stockage

Kubernetes propose par défaut plusieurs types de volumes pour le stockage. Tous ne sont pas persistants et présentent des caractéristiques différentes. Voir la documentation officielle pour une liste exhaustive.

Stockage objet S3

SdV propose offres de stockage objet compatible S3 pour les besoins de stockage massif, d'archivage ou de distribution de contenu statique.

Caractéristiques

CritèreValeur
TypeStockage objet (Object Storage)
ProtocoleAPI REST S3 (compatible AWS S3)
DurabilitéTrès élevée (réplication multi-zones)
ScalabilitéIllimitée
PerformanceOptimisé pour le throughput, pas pour la latence

Cas d'usage

Adapté pour :

  • Stockage de backups et archives
  • Distribution de contenu statique (CDN)
  • Data lakes et analytics
  • Stockage d'images et vidéos à grande échelle
  • Logs applicatifs (via Fluentd, Loki, etc.)
  • Artefacts de build (images Docker, binaires)

Intégration avec Kubernetes

Le stockage S3 n'est pas directement monté comme un volume Kubernetes. L'accès se fait via :

  1. SDK applicatif : Boto3 (Python), AWS SDK (Java, Node.js, Go...)
  2. S3 FUSE : Monte un bucket S3 comme système de fichiers (performances limitées)

Exemple d'utilisation avec des secrets

secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: s3-credentials
  namespace: production
type: Opaque
stringData:
  access-key: "AKIAIOSFODNN7EXAMPLE"
  secret-key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

emptyDir

Un volume emptyDir est créé lorsqu'un Pod est assigné à un nœud et existe aussi longtemps que le Pod s'exécute sur ce nœud. Comme son nom l'indique, le volume est initialement vide. Tous les conteneurs du Pod peuvent lire et écrire dans ce volume.

Caractéristiques

CritèreValeur
PersistanceNon persistant (supprimé avec le Pod)
LocalisationDisque local du nœud ou RAM
PartageEntre conteneurs d'un même Pod uniquement
TailleLimitée par l'espace disque/RAM du nœud

Cas d'usage

Adapté pour :

  • Cache temporaire d'une application
  • Échange de données entre conteneurs d'un même Pod (sidecars)
  • Espace de travail pour traitements temporaires
  • Stockage de fichiers de session éphémères

Déconseillé pour :

  • Données devant survivre au redémarrage du Pod
  • Volumétries importantes (>100 Mo)
  • Données critiques nécessitant une persistance

Exemple avec stockage disque

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webapp-cache
  namespace: production
  labels:
    app: webapp
spec:
  containers:
  - name: webapp
    image: nginx:1.25
    volumeMounts:
    - name: cache-volume
      mountPath: /var/cache/nginx
  - name: cache-warmer
    image: busybox:1.36
    command: ['sh', '-c', 'while true; do date > /cache/timestamp; sleep 60; done']
    volumeMounts:
    - name: cache-volume
      mountPath: /cache
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 100Mi  # Limite la taille du volume

Exemple avec stockage en RAM (tmpfs)

Pour optimiser les temps d'accès, il est possible d'utiliser un stockage en RAM (tmpfs) en définissant le champ emptyDir.medium à Memory.

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: high-speed-cache
  namespace: production
spec:
  containers:
  - name: app
    image: myapp:1.0.0
    resources:
      requests:
        memory: "256Mi"  # Inclut l'emptyDir en mémoire
      limits:
        memory: "512Mi"
    volumeMounts:
    - name: tmp-cache
      mountPath: /tmp/cache
  volumes:
  - name: tmp-cache
    emptyDir:
      medium: Memory
      sizeLimit: 128Mi  # Taille max en RAM

ConfigMap et Secret (volumes projetés)

Les ConfigMap et Secret peuvent être montés comme volumes dans les Pods pour injecter des fichiers de configuration ou des informations sensibles.

Exemple avec ConfigMap

configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  app.conf: |
    server {
      listen 80;
      server_name example.com;
    }
  settings.json: |
    {
      "debug": false,
      "max_connections": 100
    }

Exemple avec Secret

secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: production
type: Opaque
stringData:
  username: admin
  password: "P@ssw0rd!Secure"

Commandes utiles

Gestion des PersistentVolumeClaims

Terminal
# Lister les PVC dans le namespace courant
kubectl get pvc
 
# Lister les PVC dans tous les namespaces
kubectl get pvc --all-namespaces
 
# Détails d'un PVC
kubectl describe pvc <nom-pvc> -n <namespace>
 
# Voir les événements liés à un PVC
kubectl get events --field-selector involvedObject.name=<nom-pvc> -n <namespace>
 
# Supprimer un PVC
kubectl delete pvc <nom-pvc> -n <namespace>

Gestion des PersistentVolumes

Terminal
# Lister tous les PV du cluster
kubectl get pv
 
# Détails d'un PV
kubectl describe pv <nom-pv>
 
# Voir les PV avec leur statut et leur claim
kubectl get pv -o wide
 
# Filtrer les PV disponibles
kubectl get pv --field-selector status.phase=Available

Gestion des StorageClasses

Terminal
# Lister les StorageClasses disponibles
kubectl get storageclass
kubectl get sc  # Alias
 
# Détails d'une StorageClass
kubectl describe sc managed-nfs-storage

Vérification de l'utilisation du stockage

Terminal
# Voir l'utilisation disque dans un Pod
kubectl exec -it <nom-pod> -n <namespace> -- df -h
 
# Taille d'un répertoire monté
kubectl exec -it <nom-pod> -n <namespace> -- du -sh /path/to/mount
 
# Lister les fichiers d'un volume
kubectl exec -it <nom-pod> -n <namespace> -- ls -lah /path/to/mount

Bonnes pratiques

Choix de la politique de rétention

EnvironnementStorageClass recommandéeJustification
Productionmanaged-nfs-storage-retainÉvite la suppression accidentelle des données
Stagingmanaged-nfs-storage-retainFacilite les tests de restauration
Développementmanaged-nfs-storageSimplifie le nettoyage automatique
CI/CDmanaged-nfs-storageVolumes éphémères pour les tests

Dimensionnement des volumes

  • Anticiper la croissance : Prévoir 30-50% de marge par rapport aux besoins initiaux
  • Surveiller l'utilisation : Mettre en place des alertes sur l'espace disque (ex: >80%)
  • Tester l'extension : Vérifier si la StorageClass supporte l'expansion de volume (allowVolumeExpansion)

Sécurité

pod.yaml
# Utiliser des permissions restrictives
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  containers:
  - name: app
    image: myapp:1.0.0
    volumeMounts:
    - name: data
      mountPath: /data
      readOnly: false  # false pour écriture, true pour lecture seule
    securityContext:
      runAsNonRoot: true
      runAsUser: 1000
      fsGroup: 2000  # Group ID pour les permissions des fichiers
      allowPrivilegeEscalation: false
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: app-data

Nommage et labels

Adopter une convention de nommage claire :

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: <app>-<type>-<env>  # Ex: webapp-uploads-prod
  namespace: production
  labels:
    app: webapp
    component: storage
    environment: production
    storage-type: nfs
  annotations:
    owner: "team-platform@example.com"
    description: "Stockage des uploads utilisateurs"
    backup: "enabled"

Gestion du cycle de vie

  1. Création : Toujours définir storageClassName explicitement
  2. Utilisation : Monitorer l'espace disque et les performances
  3. Mise à jour : Tester l'extension de volume en pré-production
  4. Suppression :
    • Pour Retain : Supprimer manuellement le PV après vérification
    • Documenter les PV orphelins et leur contenu
    • Archiver les données avant suppression définitive

Monitoring et alerting

Métriques à surveiller :

  • Utilisation de l'espace disque : Pourcentage d'utilisation du PVC
  • Latence I/O : Temps de réponse des opérations disque
  • Erreurs de montage : Échecs de binding PVC/PV
  • PV orphelins : PV en statut Released après suppression du PVC

Exemple d'alerte Prometheus :

alertmanager.yaml
# Alerte si un PVC est rempli à plus de 85%
- alert: PVCAlmostFull
  expr: |
    kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes > 0.85
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "PVC {{ $labels.persistentvolumeclaim }} presque plein"
    description: "Le PVC est rempli à {{ $value | humanizePercentage }}"

Dépannage

Problèmes courants

PVC en état Pending

Causes possibles :
  • Aucun PV disponible correspondant aux critères
  • StorageClass inexistante ou mal configurée
  • Quota de stockage dépassé
  • Provisioner NFS indisponible
Diagnostic :
Terminal
# Vérifier l'état du PVC
kubectl describe pvc <nom-pvc> -n <namespace>
 
# Vérifier les événements
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
 
# Vérifier les PV disponibles
kubectl get pv --field-selector status.phase=Available

Erreur de montage dans le Pod

Causes possibles :
  • Serveur NFS inaccessible
  • Permissions insuffisantes
  • Volume déjà monté en exclusif (RWO) sur un autre nœud
Diagnostic :
Terminal
# Voir les événements du Pod
kubectl describe pod <nom-pod> -n <namespace>
 
# Vérifier les logs du CSI driver (si applicable)
kubectl logs -n kube-system -l app=nfs-provisioner

Performance dégradée

Actions :
  • Vérifier la charge réseau vers le serveur NFS
  • Analyser les I/O du Pod : kubectl exec <pod> -- iostat -x 5
  • Contacter le support SdV pour vérifier l'état de la baie de stockage

Références