Introduction
La planification de la capacité des volumes persistants (PV) Kubernetes est souvent traitée comme une estimation unique : choisir un nombre, créer une revendication de volume persistant (PersistentVolumeClaim, PVC) et espérer que l'application ne remplira jamais le disque. Cette approche mène à des pannes, des pods bloqués et des tentatives d'extension d'urgence. Ce guide vous fait passer de ce problème observé à un résultat vérifié grâce à des étapes pratiques et reproductibles.
L'article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui exécutent des charges de travail avec état sur Kubernetes. Il relie le dimensionnement des PV, les demandes de PVC, les politiques d'extension des StorageClasses et la surveillance des ressources à des commandes, des sorties attendues, des signaux de défaillance et des décisions de récupération. Vous apprendrez à inspecter l'utilisation actuelle, à choisir une stratégie de dimensionnement, à étendre les volumes en toute sécurité et à gérer les modes de défaillance courants.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des valeurs fictives plutôt que des secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Inventaire des versions et de l'environnement
Avant de planifier la capacité, vous devez savoir exactement avec quoi vous travaillez. Exécutez ces commandes dans votre cluster cible et enregistrez la sortie. Remplacez les espaces réservés comme <namespace> et <pvc-name> par vos valeurs réelles.
1. Vérifier la version de Kubernetes et les capacités de stockage
kubectl version --short
kubectl get storageclass
La sortie attendue pour kubectl version --short inclut une version de serveur telle que Server Version: v1.28.5. La liste des StorageClasses montre des noms comme standard, gp2 ou managed-premium, avec le fournisseur et la politique de récupération. Faites attention à la colonne ALLOWVOLUMEEXPANSION (visible avec kubectl get storageclass -o wide). Si elle est true, la StorageClass prend en charge l'extension en ligne. Si false, vous devez gérer l'extension manuellement ou utiliser une autre classe.
kubectl get storageclass -o wide
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) kubernetes.io/gce-pd Delete Immediate true 12d
2. Lister les PV et PVC existants
kubectl get pv
kubectl get pvc -n <namespace>
Recherchez les PV avec le statut Released ou Failed. Un PV Released signifie que le PVC a été supprimé mais que le PV n'a pas été récupéré (politique de récupération Retain). Un tel PV ne peut pas être lié à un nouveau PVC sans nettoyage manuel. C'est une source courante de capacité gaspillée et de pannes inattendues.
Exemple :
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-abc123 10Gi RWO Delete Bound default/my-app-data standard 7d
pvc-def456 5Gi RWO Retain Released default/old-claim standard 14d
Le PV pvc-def456 occupe 5Gi mais n'est pas utilisable. Vous devrez peut-être le supprimer après vous être assuré qu'il n'est pas nécessaire.
3. Inspecter la demande et la capacité actuelles d'un PVC
kubectl get pvc <pvc-name> -n <namespace> -o yaml
Cela montre spec.resources.requests.storage et status.capacity.storage. Dans de nombreux cas, ils sont égaux, mais ils diffèrent après une extension (la capacité rattrape) ou avec certains pilotes.
4. Vérifier le pod utilisant le PVC et l'utilisation de son système de fichiers
kubectl get pod -n <namespace> -l app=<app-label>
kubectl exec -it <pod-name> -n <namespace> -- df -h /data
Exemple de sortie :
Filesystem Size Used Avail Use% Mounted on
/dev/sdb 9.8G 7.2G 2.4G 76% /data
Cela indique la consommation réelle, pas seulement la taille demandée. Un pod peut utiliser bien moins que la demande du PVC, indiquant une surallocation. Inversement, si l'utilisation est supérieure à 80 %, vous devez planifier une extension ou un nettoyage.
Prérequis pour la planification de capacité
- Accès au cluster avec
kubectlconfiguré. - Permission de lire et décrire les ressources de stockage (
kubectl auth can-i get pvc --namespace <ns>). - Connaissance du fournisseur de la StorageClass (cloud ou sur site) et de son support d'extension.
- Pour les StatefulSets, compréhension de la façon dont les
volumeClaimTemplatescréent des PVC par pod.
Séparez toujours l'observation de l'intervention. Capturez l'état actuel et les horodatages avant tout changement. Par exemple, sauvegardez un instantané :
date -u +%Y%m%dT%H%M%SZ > /tmp/ts
kubectl get pvc -n <namespace> -o yaml > /tmp/pvc-before-$(cat /tmp/ts).yaml
Chemin de configuration sûr
Cette section décrit une méthode à risque minimal pour modifier la capacité des PV ou les paramètres associés. Le principe central : faire un changement ciblé, vérifier et connaître le retour en arrière.
Étape 1 : Identifier le plus petit changement justifié
La planification de capacité implique généralement :
- Augmenter le stockage demandé d'un PVC.
- Ajuster les limites de ressources d'une application pour éviter le débordement du disque (par exemple, la rotation des journaux).
- Modifier la StorageClass par défaut ou en ajouter une nouvelle pour les charges futures.
Ne modifiez pas la StorageClass d'un PVC lié existant ; elle est immuable. Créez plutôt un nouveau PVC avec la classe souhaitée et migrez les données si nécessaire.
Étape 2 : Valider la capacité d'extension
Avant de tenter une extension, vérifiez la StorageClass :
kubectl get storageclass <class-name> -o yaml | grep allowVolumeExpansion
Si vide ou false, l'extension via Kubernetes n'est pas prise en charge. Vous devrez peut-être provisionner un nouveau volume plus grand et copier les données.
Étape 3 : Tester avec un PVC non critique
Si possible, effectuez un essai sur un PVC de test dans le même namespace ou un environnement de développement. Étendez un PVC de 1Gi à 2Gi et observez :
kubectl patch pvc test-pvc -n dev -p '{"spec":{"resources":{"requests":{"storage":"2Gi"}}}}'
kubectl get pvc test-pvc -n dev -w
Surveillez le statut Bound et la capacité mise à jour. Si l'extension reste bloquée en Resizing, examinez les événements :
kubectl describe pvc test-pvc -n dev
Étape 4 : Étendre le PVC de production
Une fois validé, appliquez le même patch au PVC de production :
kubectl patch pvc my-app-data -n prod -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
Surveillez l'extension :
kubectl get pvc my-app-data -n prod -w
La plupart des fournisseurs cloud terminent l'extension en quelques minutes. Le pod utilisant le volume devrait voir automatiquement la nouvelle taille sans redémarrage (si le pilote prend en charge l'extension en ligne). Pour le redimensionnement du système de fichiers, le kubelet le redimensionne automatiquement après l'extension du volume. Vous pouvez vérifier à l'intérieur du pod :
kubectl exec -it <pod> -n prod -- df -h /data
La sortie attendue montre la nouvelle taille et l'espace disponible accru.
Étape 5 : Documenter le changement et le retour en arrière
Enregistrez l'état avant/après :
kubectl get pvc my-app-data -n prod -o yaml > /tmp/pvc-after-$(date -u +%Y%m%dT%H%M%SZ).yaml
L'extension est généralement à sens unique ; vous ne pouvez pas réduire un PVC. Si vous devez revenir en arrière, vous devez créer un PVC plus petit et restaurer les données depuis une sauvegarde. Par conséquent, vérifiez toujours le besoin et le stockage sous-jacent disponible avant d'étendre.
Exemple d'extrait de configuration : PVC avec taille explicite et StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
namespace: prod
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 10Gi
Appliquez-le :
kubectl apply -f pvc.yaml
Gardez le test local petit
Appliquez un seul manifeste, inspectez les ressources générées et vérifiez l'accès avec un pod temporaire avant de passer à une charge de production. Par exemple :
kubectl run -it --rm test-pod --image=busybox --restart=Never -- sh
# Dans le pod : df -h /mnt
Vérification et diagnostic
Après tout changement ou régulièrement, vérifiez l'état réel des PV et PVC. Cette section fournit des commandes concrètes et des sorties attendues.
Vérifier le statut et les conditions des PVC
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>
Recherchez :
- Statut
Bound(attendu). - Événements montrant
ProvisioningSucceeded,Resizingou des avertissements. - Condition
FileSystemResizePending(vrai signifie que le PVC a été étendu au niveau du volume mais que le redimensionnement du système de fichiers n'est pas terminé, souvent parce que le pod n'a pas redémarré ou que le pilote ne prend pas en charge le redimensionnement en ligne). - Condition
Resizing(vrai pendant l'extension en cours).
Surveiller l'utilisation réelle au fil du temps
Pour un pod avec PVC monté sur /data, exécutez :
kubectl exec -it <pod> -n <namespace> -- sh -c 'df -h /data; du -sh /data/* | sort -rh | head -n 10'
Cela donne le pourcentage d'utilisation et les principaux répertoires. Cela aide à identifier si les journaux de données ou les fichiers d'application croissent de manière inattendue.
Pour une approche plus systématique, utilisez une requête Prometheus si les métriques du node exporter ou du kubelet sont disponibles :
kubelet_volume_stats_used_bytes{namespace="<ns>",persistentvolumeclaim="<pvc>"} / kubelet_volume_stats_capacity_bytes{namespace="<ns>",persistentvolumeclaim="<pvc>"}
Définissez une alerte lorsque l'utilisation dépasse 80 %.
Vérifier les événements pour les problèmes de stockage
kubectl get events -n <namespace> --sort-by=.lastTimestamp | grep -i volume
La sortie attendue inclut ProvisioningSucceeded, VolumeResizeSuccessful ou des messages d'échec comme Failed to resize volume ou Insufficient capacity.
Vérifier les PVC de StatefulSet
Pour les StatefulSets, chaque pod a son propre PVC nommé <volumeClaimTemplate-name>-<statefulset-name>-<ordinal>. Listez-les :
kubectl get pvc -n <namespace> -l app=<statefulset-label>
Utilisez les mêmes techniques de surveillance par pod.
Exemple de diagnostic : PVC bloqué en Pending
Si un PVC reste Pending, exécutez :
kubectl describe pvc <pvc-name> -n <namespace>
Raisons courantes :
- Aucune StorageClass ou fournisseur correspondant.
- Capacité insuffisante dans le système de stockage sous-jacent.
- Mode d'accès non pris en charge (par exemple, demander ReadWriteMany sur une classe de stockage en blocs).
- Quota de ressources dépassé.
Corrigez la cause racine, pas le symptôme. Par exemple, si le nom de la StorageClass a une faute de frappe, créez un nouveau PVC avec le bon nom, ou mettez à jour le déploiement pour utiliser la bonne revendication.
Modes de défaillance et récupération
Cette section détaille les pannes courantes liées à la capacité des PV et comment récupérer.
Panne 1 : L'extension du PVC se bloque
Symptôme : kubectl get pvc montre Resizing pendant longtemps, ou kubectl describe pvc montre un événement comme Waiting for user to (re-)start a pod to finish file system resize of volume on node.
Pourquoi cela arrive : Pour certains types de volumes (par exemple, certains pilotes CSI ou anciennes versions de Kubernetes), le redimensionnement du système de fichiers ne se produit que lorsque le pod utilisant le volume est redémarré. L'extension en ligne sans redémarrage n'est pas universellement prise en charge.
Récupération : Redémarrez le pod qui utilise le PVC. Pour un déploiement :
kubectl rollout restart deployment <deployment-name> -n <namespace>
Après le redémarrage, vérifiez que la condition FileSystemResizePending du PVC devient false et que la nouvelle taille est reflétée dans le pod.
Panne 2 : Disque plein et pod évincé ou en crash
Symptôme : Les journaux du pod montrent no space left on device, le pod entre en CrashLoopBackOff, ou le nœud signale une pression. L'utilisation du PVC est à 100 %.
Pourquoi cela arrive : Les journaux ou données de l'application ont dépassé la taille demandée, et aucun nettoyage ou extension n'a été fait à temps.
Récupération :
- Augmentez immédiatement la taille du PVC si la StorageClass le permet (voir Chemin de configuration sûr).
- Si l'extension est impossible, libérez de l'espace dans le pod :
kubectl exec -it <pod> -n <namespace> -- sh -c 'du -sh /data/* | sort -rh | head'
Supprimez les journaux ou fichiers temporaires inutiles, puis redémarrez le pod. C'est une solution temporaire ; mettez en place une rotation des journaux ou un archivage des données.
- À long terme, configurez la rétention au niveau de l'application (par exemple, logrotate) ou déplacez les données non critiques vers un stockage objet.
Panne 3 : PVC supprimé accidentellement, données perdues
Symptôme : Le PVC est manquant, le pod ne peut pas monter le volume. Le PV peut exister avec le statut Released si la politique de récupération était Retain.
Pourquoi cela arrive : Erreur humaine ou un script supprimant la mauvaise ressource.
Récupération :
- Si le PV existe toujours avec
Retain, vous pouvez potentiellement le relier manuellement. Cependant, il est plus sûr de restaurer depuis une sauvegarde. - Si la politique de récupération était
Delete, le PV et le stockage sous-jacent ont disparu. Restaurez depuis une sauvegarde. Cela souligne la nécessité de sauvegardes régulières des données avec état. Utilisez des outils comme Velero ou des instantanés cloud.
Vérifiez la politique de récupération avant la suppression :
kubectl get pv <pv-name> -o yaml | grep reclaimPolicy
Panne 4 : Impossible d'étendre car la StorageClass ne le permet pas
Symptôme : kubectl patch pvc renvoie une erreur comme only dynamically provisioned pvc can be resized and the storageclass that provisions the pvc must support resize.
Pourquoi cela arrive : La StorageClass a allowVolumeExpansion: false ou est absente, ou le volume est provisionné statiquement.
Récupération :
- Créez un nouveau PVC plus grand avec une StorageClass qui prend en charge l'extension, puis copiez les données à l'aide d'un pod temporaire ou de
kubectl cp. - Alternativement, provisionnez un nouveau PV manuellement et migrez.
Étapes pour migrer :
- Créez un nouveau PVC avec la taille souhaitée.
- Lancez un pod auxiliaire avec les deux PVC montés.
- Copiez les données :
kubectl cp -n <namespace> <old-pvc>:/data /tmp/datapuiskubectl cp -n <namespace> /tmp/data <new-pvc>:/data(ajustez les chemins). - Mettez à jour le déploiement pour utiliser le nouveau PVC.
- Supprimez l'ancien PVC.
Testez toujours la migration dans un environnement non productif d'abord.
Panne 5 : Inadéquation de capacité entre la demande et l'utilisation réelle
Symptôme : Le PVC demande 100Gi mais le pod n'utilise que 10Gi. Ou les coûts de stockage augmentent.
Pourquoi cela arrive : Dimensionnement initial basé sur des suppositions plutôt que des métriques.
Récupération :
- La taille d'un PVC ne peut pas être réduite sur place. Pour redimensionner correctement, vous devez créer un nouveau PVC plus petit et migrer les données (comme ci-dessus).
- Planifiez la croissance future en définissant une taille initiale raisonnable et en surveillant les tendances. Utilisez une politique de commencer avec 1,5 fois l'utilisation de pointe attendue, avec un minimum de 5Gi pour les petites charges.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle pour la gestion récurrente de la capacité des PV. Attribuez un responsable unique pour chaque décision majeure et révisez à une cadence définie (par exemple, hebdomadaire pour les charges à forte croissance, mensuelle pour les stables).
| Tâche | Commande ou méthode | Résultat attendu | Responsable | Fréquence de révision |
|---|---|---|---|---|
| Vérifier tous les statuts des PVC | kubectl get pvc --all-namespaces | Tous Bound, aucun Pending ou Resizing | Administrateur stockage (par ex., Jordan Lee, Ingénierie de plateforme) | Hebdomadaire |
| Surveiller le pourcentage d'utilisation des 10 principaux PVC | kubectl get --raw /api/v1/nodes/<node>/proxy/stats/summary ou requête Prometheus | Utilisation inférieure à 80 % | Ingénieur DevOps (par ex., Priya Shah, Responsable DevOps) | Hebdomadaire |
| Vérifier les paramètres d'extension des StorageClasses | kubectl get storageclass -o wide | Les classes souhaitées ont true sous ALLOWVOLUMEEXPANSION | Ingénieur plateforme (par ex., Alex Kim, Responsable plateforme) | Mensuelle |
Vérifier les PV Released nécessitant un nettoyage | kubectl get pv --field-selector=status.phase=Released | Liste vide ou nettoyage planifié | Administrateur stockage | Mensuelle |
| Vérifier le test de restauration de sauvegarde | Effectuer un exercice de restauration sur un PVC non critique | La sauvegarde restaure avec succès dans le RTO | Ingénieur fiabilité des sites (SRE) | Trimestrielle |
| Examiner les prévisions de capacité par rapport à la croissance réelle | Comparer les tendances df -h sur 3 mois, ajuster les quotas | Erreur de prévision < 10 % | Responsable ingénierie (par ex., Sam Rivera, VP Ingénierie) | Trimestrielle |
Pour chaque élément de la liste, le responsable enregistre le résultat dans un système de suivi (par exemple, un ticket GitHub ou Jira) et note tout écart. Le responsable de l'ingénierie examine les éléments suivis lors de la revue mensuelle de l'infrastructure.
Pièges courants et comment les éviter
Piège 1 : Utiliser la StorageClass par défaut sans vérifier le support d'extension
De nombreux clusters définissent une StorageClass par défaut (par exemple, standard) qui peut avoir allowVolumeExpansion: false. Les développeurs supposent qu'ils pourront étendre les PVC plus tard, pour découvrir que c'est impossible.
Pourquoi cela arrive : Le cluster a été configuré avec une configuration minimale, et personne n'a vérifié les capacités d'extension avant de déployer des applications avec état.
Comment éviter : Avant de déployer une charge, exécutez :
kubectl get storageclass <class> -o yaml | grep allowVolumeExpansion
Si false ou absent, utilisez une autre classe prenant en charge l'extension ou ajustez les attentes et planifiez une migration.
Piège 2 : Ignorer la surcharge du système de fichiers et l'épuisement des inodes
Bien qu'un PVC soit de 10Gi, le système de fichiers (ext4, XFS) réserve de l'espace pour les métadonnées. De plus, si l'application crée des millions de petits fichiers, vous pouvez manquer d'inodes (par exemple, ext4 a par défaut un inode par 16KiB d'espace). Le disque peut sembler peu utilisé par df mais de nouveaux fichiers ne peuvent pas être créés.
Pourquoi cela arrive : La planification initiale de capacité n'a considéré que les octets, pas les besoins en inodes.
Comment éviter : Vérifiez l'utilisation des inodes :
kubectl exec -it <pod> -n <namespace> -- df -i /data
Si l'utilisation des inodes est élevée (>80 %), envisagez un système de fichiers avec plus d'inodes ou ajustez l'application pour utiliser des fichiers moins nombreux et plus grands.
Piège 3 : Ne pas définir de quotas de ressources sur les namespaces
Sans quotas, les développeurs peuvent créer de nombreux grands PVC, épuisant le stockage du cluster et les coûts. Par exemple, un namespace avec un quota de 100Gi peut demander 10 PVC de 20Gi chacun.
Pourquoi cela arrive : Les quotas ne sont pas configurés par défaut, et l'organisation manque d'une politique de gouvernance du stockage.
Comment éviter : Définissez un ResourceQuota pour le stockage :
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-quota
namespace: team-a
spec:
hard:
requests.storage: 200Gi
persistentvolumeclaims: "10"
Appliquez-le et éduquez les équipes sur les limites.
Piège 4 : Supposer que la suppression d'un PVC supprime les données
Selon la politique de récupération (Delete vs Retain), la suppression d'un PVC peut ou non supprimer le stockage sous-jacent. Avec Retain, le PV reste et doit être nettoyé manuellement ; sinon, il fuit de la capacité.
Pourquoi cela arrive : Les développeurs s'attendent à la politique Delete par défaut mais la StorageClass utilise Retain.
Comment éviter : Vérifiez la politique de récupération de la StorageClass avant la suppression :
kubectl get storageclass <class> -o yaml | grep reclaimPolicy
Si Retain, supprimez explicitement le PV après avoir vérifié que les données ne sont plus nécessaires ou sauvegardées.
Piège 5 : Ne pas planifier la réduction d'échelle d'un StatefulSet
Lors de la réduction d'échelle d'un StatefulSet, les PVC des pods terminés ne sont pas supprimés automatiquement (sauf si vous utilisez volumeClaimTemplates avec une politique de suppression, mais c'est risqué). Ces PVC orphelins consomment du stockage.
Pourquoi cela arrive : Kubernetes préserve les données pour la sécurité, et les opérateurs oublient de nettoyer.
Comment éviter : Définissez une politique pour les PVC orphelins. Après une réduction d'échelle, examinez et supprimez les PVC inutilisés si les données sont sauvegardées ou inutiles :
kubectl get pvc -n <namespace> -l app=<statefulset> | grep -v Bound
Alternativement, définissez persistentVolumeClaimRetentionPolicy.whenDeleted: Delete sur le StatefulSet si approprié.
Conclusion
La planification de la capacité des volumes persistants Kubernetes ne réussit que si chaque recommandation est liée à une version, observable et réversible là où la technologie le permet. Copier une commande sans vérifier les prérequis et la sortie attendue n'est pas une procédure d'exploitation. Utilisez les commandes et vérifications de ce guide pour établir une base de référence pour votre cluster.
Comme prochaine étape, choisissez une vérification à faible risque pour un PVC : enregistrez l'état actuel, exécutez une commande de surveillance comme kubectl exec ... -- df -h, comparez le résultat avec la taille demandée et planifiez une révision avec votre équipe. Faites attention aux composants dépendants tels que les PVC, les StatefulSets et les StorageClasses ; leur configuration affecte votre capacité à étendre et récupérer.
Un flux de travail technique fiable rend la défaillance visible, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. Revisitez votre plan de capacité mensuellement et ajustez en fonction des tendances d'utilisation réelles. Le bénéfice est une charge avec état stable et moins d'alertes à 3 heures du matin.