Introduction
La mise à niveau et la migration des volumes Kubernetes sont des opérations à haut risque. Une seule erreur peut empêcher les applications de démarrer, rendre les données inaccessibles ou laisser des ressources de stockage orphelines. Ce guide propose une approche pratique, basée sur des commandes, pour mettre à niveau et migrer des volumes dans un cluster Kubernetes, en mettant l'accent sur la sécurité, l'observabilité et la récupération.
Vous apprendrez à :
- Inventorier la configuration actuelle des volumes et des classes de stockage.
- Planifier et exécuter une migration de volume avec un minimum d'interruption.
- Mettre à niveau les provisionneurs de stockage ou les plugins de volume.
- Valider que les données sont intactes et que les applications sont saines.
- Revenir en arrière en cas de problème.
Chaque étape comprend de vraies commandes kubectl, des extraits de manifestes et les sorties attendues. L'objectif est de vous fournir un playbook reproductible qui réduit les risques et renforce la confiance.
Ce guide s'adresse aux développeurs, ingénieurs DevOps et équipes plateforme qui ont déjà une connaissance pratique des concepts fondamentaux de Kubernetes comme les Pods, les Deployments, les PersistentVolumes (PV), les PersistentVolumeClaims (PVC) et les StorageClasses. Si vous découvrez ces concepts, consultez la documentation officielle de Kubernetes avant de continuer.
Nous utiliserons une application e-commerce fictive appelée shop-app comme exemple. Elle se compose d'une base de données PostgreSQL (avec ses données sur un PersistentVolume) et d'un frontend web sans état. Toutes les commandes supposent que vous avez configuré kubectl avec accès à un cluster de test d'abord et que vous avez déjà sauvegardé les données critiques.
Inventaire de la version et de l'environnement
Avant de toucher quoi que ce soit, vous devez savoir exactement ce que vous avez. Cette section explique comment rassembler un inventaire complet de votre configuration de stockage actuelle, y compris la version de Kubernetes, les StorageClasses, les PV et les PVC. Ces informations sont essentielles pour planifier une migration sûre et pour résoudre les problèmes éventuels.
Vérifier la version de Kubernetes et les capacités de stockage
Commencez par vérifier la version de votre plan de contrôle et de vos nœuds Kubernetes. Certaines fonctionnalités de stockage, comme la migration CSI ou l'expansion de volume, dépendent de la version.
kubectl version --short
kubectl get nodes -o wide
Exemple de sortie :
Client Version: v1.27.3
Server Version: v1.27.3
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node-1 Ready control-plane 10d v1.27.3 192.168.1.10 <none> Ubuntu 22.04.2 LTS 5.15.0-76-generic containerd://1.7.1
node-2 Ready <none> 10d v1.27.3 192.168.1.11 <none> Ubuntu 22.04.2 LTS 5.15.0-76-generic containerd://1.7.1
Notez la version du serveur. Si vous prévoyez de mettre à niveau des volumes qui dépendent d'un driver CSI spécifique, vérifiez la matrice de compatibilité de ce driver avec cette version.
Lister les StorageClasses
Les StorageClasses définissent les types de stockage disponibles dans votre cluster. Vous devez savoir lesquelles sont utilisées et leurs provisionneurs.
kubectl get storageclass
Exemple de sortie :
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) kubernetes.io/gce-pd Delete Immediate false 30d
fast kubernetes.io/aws-ebs Delete WaitForFirstConsumer true 30d
csi-example example.csi.driver.io Retain Immediate true 20d
Notez le provisionneur (in-tree vs CSI), la politique de récupération et si l'expansion de volume est autorisée. Ces propriétés influencent les options de migration.
Lister les PersistentVolumes et les Claims
Obtenez une vue détaillée de tous les PV et de leur statut de liaison.
kubectl get pv -o wide
Exemple de sortie :
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-1234abcd-56ef-7890-1234-567890abcdef 10Gi RWO Delete Bound default/shop-db-data standard 30d
pvc-5678efgh-90ij-1234-5678-901234ghijkl 5Gi RWO Delete Bound default/shop-db-backup fast 10d
Listez maintenant tous les PVC dans tous les namespaces :
kubectl get pvc --all-namespaces
Exemple de sortie :
NAMESPACE NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
default shop-db-data Bound pvc-1234abcd-56ef-7890-1234-567890abcdef 10Gi RWO standard 30d
default shop-db-backup Bound pvc-5678efgh-90ij-1234-5678-901234ghijkl 5Gi RWO fast 10d
Identifier quels Pods utilisent quels volumes
Découvrez quels Pods en cours d'exécution montent ces PVC. Cela vous indique quelles charges de travail seront affectées par une migration.
kubectl get pods -o wide --all-namespaces
Ensuite, pour un Pod spécifique, décrivez-le pour voir les montages de volume :
kubectl describe pod shop-db-0 -n default
Recherchez les sections Volumes et Mounts dans la sortie. Vous pouvez aussi interroger directement avec JSONPath :
kubectl get pods -n default -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.volumes[*].persistentVolumeClaim.claimName}{"\n"}{end}'
Exemple de sortie :
shop-db-0 shop-db-data
shop-web-xyz shop-web-uploads
Notez quels Pods utilisent chaque PVC. C'est essentiel pour planifier une fenêtre de maintenance et pour vérifier que les applications sont saines après la migration.
Prérequis et vérification de compatibilité
Avant de procéder, assurez-vous d'avoir :
- Sauvegardes : Prenez un snapshot ou une sauvegarde de chaque volume que vous prévoyez de migrer. Pour les volumes cloud, utilisez la fonction de snapshot du fournisseur. Pour les environnements sur site, utilisez les outils de sauvegarde de votre système de stockage.
- Accès
kubectlavec les permissions appropriées pour obtenir, créer et supprimer des PV, PVC et Pods. - Capacité de stockage suffisante dans la classe de stockage cible pour contenir les données plus l'espace temporaire de migration.
- Un environnement de test qui reflète la production aussi fidèlement que possible.
Si vous mettez à niveau un driver CSI, consultez les notes de version du driver pour les versions de Kubernetes supportées et les chemins de mise à niveau. Certains drivers CSI peuvent être mis à niveau sur place, tandis que d'autres nécessitent une nouvelle instance du driver et une migration progressive des volumes.
Chemin de configuration sécurisé
Une migration ou une mise à niveau sûre suit un chemin contrôlé : planifier, tester, sauvegarder, exécuter par étapes et valider à chaque étape. Cette section décrit un chemin sûr général, puis l'applique à un scénario concret de migration de volume d'un provisionneur in-tree vers un driver CSI.
Chemin général de migration sécurisée
- Sauvegarde : Prenez un instantané du volume source ou utilisez des sauvegardes au niveau applicatif.
- Test : Effectuez la migration dans un namespace ou cluster non productif avec une configuration similaire.
- Planifier la bascule : Décidez d'utiliser une approche blue/green (bleu/vert) ou canary. Pour les charges de travail avec état, un déploiement blue/green de l'application avec un nouveau volume est souvent plus simple.
- Exécuter : Créez le nouveau volume, copiez les données, basculez l'application sur le nouveau volume et vérifiez.
- Nettoyer : Supprimez l'ancien volume seulement après une période de validation réussie.
Exemple : Migration d'un provisionneur in-tree vers un driver CSI
De nombreuses distributions Kubernetes déprécient les plugins de volume in-tree au profit des drivers CSI. Une migration courante est celle du provisionneur in-tree kubernetes.io/gce-pd vers le driver CSI GCE PD. Le processus implique la création d'une nouvelle StorageClass, la migration des PV et des tests.
Étape 1 : Installer le driver CSI (s'il n'est pas déjà installé). Pour GCE PD, vous pouvez appliquer les manifestes du driver depuis le dépôt officiel. Vérifiez que les pods du driver fonctionnent :
kubectl get pods -n kube-system | grep csi
Sortie attendue (similaire) :
gce-pd-csi-driver-controller-0 4/4 Running 0 5m
gce-pd-csi-driver-node-xxxxx 2/2 Running 0 5m
Étape 2 : Créer une nouvelle StorageClass utilisant le provisionneur CSI. Enregistrez le YAML suivant sous csi-standard.yaml :
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-standard
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-standard
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Appliquez-le :
kubectl apply -f csi-standard.yaml
Vérifiez :
kubectl get storageclass csi-standard
Étape 3 : Migrer un volume existant. La méthode recommandée est de créer un nouveau PVC avec la nouvelle StorageClass et de copier les données. Nous utiliserons une méthode simple avec kubectl cp pour des volumes de taille modérée. Pour des volumes très volumineux, envisagez d'utiliser un job avec rsync ou un outil comme Velero.
D'abord, créez un nouveau PVC pour les données de la base de données :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shop-db-data-csi
spec:
accessModes:
- ReadWriteOnce
storageClassName: csi-standard
resources:
requests:
storage: 10Gi
Appliquez et attendez qu'il soit lié :
kubectl apply -f shop-db-data-csi.yaml
kubectl get pvc shop-db-data-csi
Vous verrez le STATUT devenir Bound une fois qu'un PV est provisionné.
Ensuite, vous avez besoin d'un Pod temporaire pour copier les données. Comme la base de données est en cours d'exécution, vous devez arrêter les écritures pour garantir la cohérence. Pour une migration en production, vous arrêteriez l'application ou utiliseriez une méthode de réplication de base de données. Pour cet exemple, nous supposerons que vous pouvez temporairement réduire le StatefulSet de la base de données à zéro.
Réduisez la base de données :
kubectl scale statefulset shop-db --replicas=0
Créez un Pod temporaire qui monte à la fois l'ancien et le nouveau PVC :
apiVersion: v1
kind: Pod
metadata:
name: data-migrator
spec:
containers:
- name: migrator
image: busybox
command: ["/bin/sh", "-c"]
args:
- |
echo "Copie des données..."
cp -a /source/* /destination/
echo "Copie terminée"
sleep 3600
volumeMounts:
- name: source
mountPath: /source
- name: destination
mountPath: /destination
volumes:
- name: source
persistentVolumeClaim:
claimName: shop-db-data
- name: destination
persistentVolumeClaim:
claimName: shop-db-data-csi
restartPolicy: Never
Appliquez et attendez la fin de la copie :
kubectl apply -f data-migrator.yaml
kubectl logs data-migrator
Sortie attendue :
Copie des données...
Copie terminée
Une fois la copie terminée, supprimez le Pod migrateur.
Étape 4 : Mettre à jour l'application pour utiliser le nouveau PVC. Pour un StatefulSet, vous mettriez à jour les volumeClaimTemplates. Cependant, comme les PersistentVolumeClaims créés à partir de modèles sont immuables, vous ne pouvez pas simplement changer le storageClassName. L'approche courante consiste à créer un nouveau StatefulSet avec un nom différent, ou à utiliser un outil comme kubectl patch si le PVC le permet. Pour simplifier, nous supposerons ici que la base de données est un Pod unique géré par un Deployment.
S'il s'agissait d'un Deployment, vous pourriez corriger le nom du claim de volume :
kubectl patch deployment shop-db --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/volumes/0/persistentVolumeClaim/claimName", "value": "shop-db-data-csi"}]'
Puis remontez à l'échelle :
kubectl scale deployment shop-db --replicas=1
Étape 5 : Vérifier que l'application fonctionne et que les données sont intactes. Consultez les journaux et exécutez une requête.
kubectl logs deployment/shop-db --tail=20
kubectl exec -it deployment/shop-db -- psql -U postgres -c "SELECT count(*) FROM orders;"
Sortie attendue (exemple) :
count
-------
1234
(1 row)
Si tout fonctionne, vous pouvez supprimer l'ancien PVC après une certaine période de surveillance.
Vérification et diagnostics
Après toute migration ou mise à niveau, vous devez vérifier que le système fonctionne correctement. Cette section fournit des commandes et des techniques pour diagnostiquer les problèmes de stockage et confirmer l'intégrité des données.
Vérifier la liaison des volumes et leur statut
Vérifiez que les PVC sont liés et que les PV sont dans l'état attendu.
kubectl get pvc -n default
kubectl get pv
Pour un PVC spécifique, décrivez-le pour voir les événements et les détails de liaison :
kubectl describe pvc shop-db-data-csi
Recherchez des avertissements tels que FailedBinding ou ProvisioningFailed. Ils indiquent des problèmes avec le provisionneur de stockage ou la capacité.
Vérifier la santé des Pods et les montages de volume
Assurez-vous que le Pod fonctionne et que le volume est monté correctement.
kubectl get pods
kubectl describe pod shop-db-xxxxx
Dans la sortie de description, sous Volumes, vous devriez voir le nom du PVC et le chemin de montage. Sous Conditions, Ready devrait être True. Si le Pod est bloqué dans ContainerCreating, vérifiez les événements pour des erreurs liées au volume.
Erreurs courantes :
FailedMount: Le volume n'a pas pu être monté en raison de problèmes de périphérique manquant ou d'autorisations.FailedAttachVolume: Le nœud n'a pas pu attacher le volume, souvent à cause d'une discordance de zone ou de problèmes de driver.
Utilisez kubectl logs pour voir les journaux d'application qui pourraient indiquer des problèmes de lecture/écriture de données.
Tester les performances en lecture/écriture
Pour vous assurer que le nouveau volume offre des performances adéquates, vous pouvez exécuter un test simple d'E/S à l'intérieur du Pod. Par exemple, si le Pod a un shell, écrivez et lisez un fichier de test :
kubectl exec -it deployment/shop-db -- bash
# Dans le conteneur
dd if=/dev/zero of=/var/lib/postgresql/data/testfile bs=1M count=100
dd if=/var/lib/postgresql/data/testfile of=/dev/null bs=1M count=100
rm /var/lib/postgresql/data/testfile
Cela écrit un fichier de 100 Mo et le relit. Vérifiez s'il y a des erreurs ou des performances anormalement lentes.
Valider la cohérence du système de fichiers
Pour les volumes de base de données, utilisez les contrôles de cohérence intégrés de la base de données. Pour PostgreSQL, vous pouvez exécuter pg_dump vers un fichier temporaire ou utiliser psql pour exécuter quelques requêtes. Pour d'autres applications, comparez le nombre de fichiers ou les sommes de contrôle avant et après la migration.
Si vous avez une sauvegarde, vous pouvez comparer le nombre de fichiers ou la taille totale :
kubectl exec -it deployment/shop-db -- du -sh /var/lib/postgresql/data
Comparez cela au volume source avant la suppression.
Surveiller les métriques de stockage
Si votre cluster dispose d'une surveillance (Prometheus, Grafana), examinez les métriques liées au volume telles que kubelet_volume_stats_used_bytes, kubelet_volume_stats_capacity_bytes et les erreurs d'opération de volume. Configurez des alertes en cas d'espace disque faible ou de latence élevée.
Modes de défaillance et récupération
Même avec une planification minutieuse, des défaillances peuvent survenir. Cette section décrit les scénarios de défaillance courants lors de la migration et de la mise à niveau des volumes, ainsi que les étapes de récupération.
Capacité insuffisante dans la nouvelle StorageClass
Défaillance : Le nouveau PVC reste à l'état Pending car le provisionneur de stockage ne peut pas créer un volume de la taille demandée (par exemple, la classe de stockage a une limite ou le backend est à court d'espace).
Diagnostic :
kubectl describe pvc shop-db-data-csi
Recherchez des événements comme :
Warning ProvisioningFailed 2m (x5 over 5m) persistentvolume-controller failed to provision volume with StorageClass "csi-standard": rpc error: code = ResourceExhausted desc = Insufficient capacity
Récupération :
- Vérifiez la capacité disponible dans votre backend de stockage.
- Réduisez la taille demandée si possible (mais seulement si les données y tiennent).
- Utilisez une autre StorageClass avec plus de capacité.
Copie de données incomplète ou corrompue
Défaillance : Le Pod migrateur de données se termine avec le code de sortie 0 mais l'application ne démarre pas ou des données sont manquantes.
Diagnostic :
- Comparez la taille des volumes source et destination en utilisant
du -sh. - Vérifiez les journaux du Pod migrateur pour des erreurs qui auraient pu être ignorées.
- Exécutez des contrôles d'intégrité au niveau applicatif (par exemple, cohérence de la base de données).
Récupération :
- Si une corruption est suspectée, ne supprimez pas le volume source. Relancez la copie avec une méthode plus fiable (par exemple,
rsyncavec vérification par somme de contrôle). - Pour les bases de données, envisagez d'utiliser la sauvegarde/restauration native au lieu de la copie de fichiers.
Le Pod ne parvient pas à monter le nouveau volume
Défaillance : Après avoir basculé le PVC, le Pod est bloqué dans ContainerCreating avec des événements FailedMount.
Diagnostic :
kubectl describe pod shop-db-xxxxx
Recherchez des erreurs de montage :
Warning FailedMount 2m kubelet MountVolume.MountDevice failed for volume "pvc-..." : driver name pd.csi.storage.gke.io not found in the list of registered CSI drivers
Récupération :
- Assurez-vous que le driver CSI est installé et fonctionne sur le nœud.
- Vérifiez que la StorageClass référence le bon provisionneur.
- Si le volume a été créé par un driver différent, vous devrez peut-être définir manuellement le champ
csi.driverdu PV et redémarrer le kubelet.
Stratégie de rollback
Si la migration échoue et que vous ne pouvez pas résoudre le problème rapidement, revenez au volume d'origine.
Étapes :
- Réduisez l'application à zéro.
- Revenez à l'ancien nom de PVC dans la référence du Pod ou du StatefulSet.
- Remontez l'application à l'échelle.
- Vérifiez que l'ancien volume est toujours intact et que l'application fonctionne.
- Enquêtez sur l'échec avant de réessayer.
Conservez toujours l'ancien volume jusqu'à ce que vous soyez sûr que la nouvelle configuration est stable. Fixez une période de surveillance (par exemple, une semaine) avant de supprimer l'ancien PVC.
Échec de la mise à niveau du driver CSI
Si vous mettez à niveau le driver CSI lui-même et que la nouvelle version ne démarre pas, vous pouvez revenir à la version précédente du driver en réappliquant les anciens manifestes ou en utilisant une méthode de déploiement versionnée (par exemple, Helm rollback).
helm rollback my-csi-driver 1
Vérifiez ensuite que les pods du driver sont sains :
kubectl get pods -n kube-system | grep csi
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle avant, pendant et après une migration ou une mise à niveau de volume pour vous assurer que rien n'est oublié.
Pré-migration
- [ ] Sauvegarder toutes les données critiques des volumes à migrer.
- [ ] Vérifier que les sauvegardes sont restaurables en effectuant une restauration de test.
- [ ] Enregistrer la version actuelle de Kubernetes, les StorageClasses, les PV, les PVC et les correspondances Pod-volume.
- [ ] Identifier toutes les applications utilisant les volumes et leur tolérance aux interruptions.
- [ ] Vérifier la capacité du système de stockage cible.
- [ ] Tester le processus de migration dans un environnement de staging.
- [ ] Planifier une fenêtre de maintenance et informer les parties prenantes.
Pendant la migration
- [ ] Réduire les applications qui écrivent sur les volumes sources (ou arrêter les écritures).
- [ ] Créer de nouveaux PVC avec la StorageClass cible.
- [ ] Démarrer le job de copie des données et surveiller la progression.
- [ ] Vérifier que la copie des données s'est terminée avec succès (taille, sommes de contrôle si possible).
- [ ] Mettre à jour les manifestes des applications pour utiliser les nouveaux PVC.
- [ ] Remonter les applications à l'échelle.
- [ ] Exécuter des tests de fumée et des vérifications au niveau applicatif.
Post-migration
- [ ] Vérifier la santé des Pods et les montages de volume (
kubectl get pods,kubectl describe pod). - [ ] Consulter les journaux d'application pour détecter des erreurs.
- [ ] Exécuter des contrôles d'intégrité de la base de données ou équivalent.
- [ ] Surveiller les métriques de performance pendant une période définie.
- [ ] Conserver les anciens volumes pour le rollback jusqu'à la fin de la période de validation.
- [ ] Supprimer les anciens volumes et nettoyer les ressources temporaires.
- [ ] Documenter la nouvelle configuration et mettre à jour les procédures.
Liste de contrôle de rollback d'urgence
- [ ] Réduire les applications affectées à zéro.
- [ ] Revenir aux anciennes références de PVC.
- [ ] Remonter les applications à l'échelle.
- [ ] Vérifier que les anciens volumes sont intacts et que les applications fonctionnent.
- [ ] Enquêter sur la cause racine avant de réessayer.
Conclusion
La mise à niveau et la migration des volumes Kubernetes exigent une planification et une exécution minutieuses. En suivant l'approche structurée de ce guide, vous pouvez minimiser les risques de temps d'arrêt et de perte de données. Les principes clés sont :
- Inventorier d'abord : Connaître la disposition actuelle du stockage et les dépendances.
- Tout sauvegarder : Ne jamais migrer sans une sauvegarde vérifiée.
- Tester en staging : Répéter la migration avant la production.
- Aller étape par étape : Utiliser un chemin sûr avec des points de rollback.
- Vérifier rigoureusement : Utiliser des commandes et des contrôles pour confirmer l'intégrité des données et la santé des applications.
- Garder le rollback prêt : Conserver les anciens volumes jusqu'à ce que le nouveau système se révèle stable.
Avec ces pratiques, vous pouvez traiter les migrations et mises à niveau de volumes comme des opérations de routine plutôt que comme des événements à haut risque. Commencez par un volume à faible risque, documentez votre processus et affinez-le au fil du temps. Les exemples de commandes et les listes de contrôle de cet article fournissent une base solide pour construire votre propre playbook adapté à votre environnement.