E-NO
Kubernetes 7 min de lecture

Mise à niveau et migration d'un service Kubernetes : guide pratique de mise en œuvre

calendar_today Publié : 2026-08-26
update Dernière mise à jour : 2026-08-26
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Mise à niveau et migration d'un service Kubernetes : guide pratique de mise en œuvre ».

Introduction

La mise à niveau ou la migration d'un service Kubernetes est rarement une simple commande kubectl. C'est une séquence d'observations, de changements ciblés, de vérifications et de décisions de récupération qui doit rester sûre dans un cluster en production. Ce guide fournit un parcours pratique, axé sur les commandes, pour les développeurs, les consultants DevOps et les équipes techniques de startups qui doivent faire évoluer un service d'une version ou d'une forme à une autre sans interrompre le trafic.

L'accent est mis sur la sécurité opérationnelle : capturez l'état actuel avant de modifier quoi que ce soit, limitez le rayon d'impact, évitez d'exposer des secrets dans les manifests ou les commandes, vérifiez chaque étape avec un signal observable et documentez la récupération avant d'en avoir besoin. Que vous passiez d'un mode kube-proxy basé sur iptables à IPVS, que vous migriez un service du fournisseur cloud intégré vers un contrôleur externe, ou que vous modifiiez simplement les sélecteurs et les ports, les principes ci-dessous s'appliquent.

Tout au long de cet article, vous trouverez des commandes concrètes, des sorties attendues et des seuils de décision. Aucune étape ne repose uniquement sur du texte. Pour chaque opération majeure, il existe une vérification concrète que vous pouvez exécuter d'abord dans un espace de noms de test. À la fin, vous disposerez d'un flux de travail réutilisable pour la mise à niveau, la migration, la restauration et la validation des services Kubernetes.

Inventaire des versions et de l'environnement

Avant de mettre à niveau ou de migrer un service, vous devez savoir exactement ce qui s'exécute dans votre cluster et ce que la version cible prend en charge. Un changement contrôlé commence par un inventaire complet et en lecture seule. Cela signifie capturer la version de Kubernetes, le mode kube-proxy, le plugin CNI, le contrôleur de service et la définition actuelle du service.

Commandes pour l'inventaire de l'environnement

Exécutez ces commandes et enregistrez leur sortie avec un horodatage. Elles sont sûres et en lecture seule.

# Versions du cluster et des nœuds
kubectl version --short
kubectl get nodes -o wide

# Mode kube-proxy (iptables, ipvs, userspace) et image du proxy
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o jsonpath='{.items[0].spec.containers[0].args}' | tr ' ' '\n' | grep -E "proxy-mode|cluster-cidr"
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o jsonpath='{.items[0].spec.containers[0].image}'

# Plugin CNI et version (exemple : Calico)
kubectl get pods -n kube-system | grep -E "calico|cni"
kubectl get daemonset -n kube-system -o wide | grep -E "calico|cni"

# Contrôleur de service (fournisseur cloud ou externe)
kubectl get pods -n kube-system | grep -E "cloud-controller|service-controller"

La sortie attendue comprend la version du serveur Kubernetes (par exemple, v1.28.5), les images des nœuds, les versions du noyau et la liste exacte des arguments de kube-proxy. Si vous voyez --proxy-mode=iptables et prévoyez de passer à IPVS, c'est un déclencheur de migration. Si vous voyez que le fournisseur cloud intégré est toujours actif, vous devrez peut-être migrer vers le gestionnaire de contrôleur cloud externe avant la mise à niveau.

Capturer le manifeste actuel du service

Exportez l'objet Service tel qu'il existe réellement, pas tel que vous pensez qu'il existe. Ce manifeste est votre base de référence pour les comparaisons et la restauration.

kubectl get service <nom-du-service> -n <namespace> -o yaml > service-actuel.yaml

Ouvrez le fichier et inspectez ces champs :

  • spec.type : ClusterIP, NodePort, LoadBalancer ou ExternalName.
  • spec.selector : étiquettes qui sélectionnent les pods backend.
  • spec.ports : mappage des ports et targetPort.
  • spec.clusterIP : l'IP allouée, le cas échéant.
  • metadata.annotations : annotations du fournisseur cloud, external-dns, etc.
  • status.loadBalancer : l'ingress externe, si assigné.

Pour un service LoadBalancer, vérifiez également les objets EndpointSlice associés :

kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<nom-du-service> -o yaml

Cela devient critique lors de la migration vers un nouveau contrôleur de service, car le contrôleur doit adopter les endpoints existants sinon vous perdrez du trafic.

Délimiter le plus petit changement justifié

Exemple : si votre objectif est uniquement de mettre à niveau un service pour utiliser une nouvelle annotation pour l'équilibreur de charge cloud, ne modifiez pas simultanément le sélecteur ou les ports. Séquencer les changements. Pour une mise à niveau de version du contrôleur de service, vérifiez d'abord que le nouveau contrôleur peut réconcilier le service existant sans modification. Appliquez ensuite la mise à niveau, puis modifiez les annotations ou d'autres champs.

Documentez la plage de versions prises en charge pour chaque composant. Par exemple :

  • Plan de contrôle Kubernetes : v1.26 à v1.29 (votre cible).
  • kube-proxy : doit correspondre au plan de contrôle avec un écart d'une version mineure.
  • Gestionnaire de contrôleur cloud : v1.28+ pour AWS, v1.27+ pour GCP.
  • CNI : Calico v3.25+ pour Kubernetes v1.28.

Si votre cluster actuel est en v1.25 et que vous voulez passer à v1.29, vous devez effectuer des mises à niveau séquentielles : 1.25 à 1.26, puis 1.26 à 1.27, etc. Sauter des versions mineures n'est pas pris en charge et peut casser les services.

Stratégie de test local

Ne testez pas d'abord sur un LoadBalancer en production. Créez un test local en appliquant un service minimal de type ClusterIP dans un espace de noms dédié, ou utilisez kubectl port-forward pour tester la connectivité vers un seul pod. Ce n'est qu'après une vérification locale que vous devez procéder aux changements d'équilibreur de charge cloud ou de contrôleur d'ingress.

Question rapide 1 sur 2

Selon le passage, quelle commande pouvez-vous utiliser pour récupérer les journaux de Pod d'un Deployment dans le cas d'un seul conteneur ?

Le passage indique : « kubectl logs deploy/my-deployment # récupération des journaux de Pod pour un Deployment (cas d'un seul conteneur) ».

Chemin de configuration sûr

Le chemin de configuration sûr consiste à apporter des modifications réversibles et observables. Vous devez appliquer un manifeste à la fois, vérifier, puis passer au changement suivant.

Avant tout changement : protégez les informations d'identification et le matériel privé

Ne mettez jamais de secrets directement dans un manifeste de service. Si vous devez configurer une annotation de fournisseur cloud ou d'external-dns qui nécessite des informations d'identification, utilisez un secret référencé. Par exemple :

apiVersion: v1
kind: Service
metadata:
  name: my-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/uuid
    external-dns.alpha.kubernetes.io/hostname: app.example.com
spec:
  type: LoadBalancer
  ports:
  - port: 443
    targetPort: 8443
  selector:
    app: my-app

L'ARN du certificat n'est pas secret, mais toute clé privée ou tout jeton doit être dans un secret et référencé via une annotation comme service.beta.kubernetes.io/aws-load-balancer-ssl-cert pointant vers un certificat stocké dans AWS Certificate Manager. Pour les contrôleurs sur site, utilisez des secrets Kubernetes montés dans le pod du contrôleur, pas dans l'objet Service.

Utiliser le versionnage et la comparaison

Stockez tous les manifests dans Git. Avant d'appliquer, effectuez toujours une comparaison avec l'objet en direct :

kubectl diff -f service-nouveau.yaml

Cela montre exactement ce qui changerait. Si vous voyez des modifications non intentionnelles, arrêtez-vous. Utilisez un outil comme kubectl apply --server-side avec un nom de gestionnaire pour suivre la propriété et éviter les conflits.

Le plus petit changement justifié en pratique

Supposons que vous deviez migrer un service du fournisseur cloud AWS intégré vers le gestionnaire de contrôleur cloud externe AWS. Le fournisseur intégré peut être déprécié dans votre version de Kubernetes. Le chemin sûr est :

  1. Assurez-vous que le gestionnaire de contrôleur cloud externe est en cours d'exécution et sain.
  2. Testez qu'il peut réconcilier un nouveau service LoadBalancer dans un espace de noms de test.
  3. Pour chaque service existant, ajoutez l'annotation service.kubernetes.io/load-balancer-cleanup avec la valeur true au service actuel avant de supprimer le fournisseur intégré. Cela indique au nouveau contrôleur d'adopter l'équilibreur de charge existant.
  4. Changez le contrôleur de service. Pour de nombreux services Kubernetes gérés, cela se produit automatiquement pendant la mise à niveau. Pour les clusters autogérés, vous devez désactiver le fournisseur intégré et démarrer le contrôleur externe.
  5. Vérifiez que l'IP externe existante reste inchangée et que l'équilibreur de charge route toujours.

Exemple de commande d'adoption d'annotation :

kubectl annotate service my-service -n production \
  service.kubernetes.io/load-balancer-cleanup=true --overwrite

Ensuite, mettez à niveau le gestionnaire de contrôleur cloud. Le nouveau contrôleur voit l'annotation et prend possession sans recréer l'équilibreur de charge.

Restauration avant d'en avoir besoin

Pour chaque modification de manifeste, enregistrez la version précédente. Utilisez kubectl get service my-service -o yaml > service-sauvegarde-$(date +%s).yaml. Pour restaurer, appliquez la sauvegarde :

kubectl apply -f service-sauvegarde-1717000000.yaml

Vérifiez que la spécification du service revient à son état antérieur et que les endpoints sont inchangés. Si vous migrez vers un nouveau contrôleur, la restauration peut nécessiter de réactiver l'ancien contrôleur. Documentez ce processus dans votre runbook opérationnel.

Vérification et diagnostics

La vérification ne consiste pas seulement à vérifier que kubectl apply a réussi. Vous devez vérifier que le service se comporte comme prévu du point de vue d'un client réel. Cette section vous donne des vérifications concrètes pour la connectivité, les endpoints, le DNS et l'état du contrôleur.

Vérifier les endpoints du service

Un service n'est utile que s'il a des endpoints sains. Utilisez :

kubectl get endpoints my-service -n production

La sortie attendue montre une liste d'IP de pods et de ports :

NAME         ENDPOINTS                                           AGE
my-service   10.244.1.5:8080,10.244.2.3:8080,10.244.3.7:8080   5m

Si les endpoints sont vides, le sélecteur ne correspond à aucun pod, ou les pods ne sont pas prêts. Vérifiez immédiatement les pods :

kubectl get pods -n production -l app=my-app -o wide
kubectl describe pod <nom-du-pod> -n production

Recherchez des événements comme FailedScheduling, CrashLoopBackOff ou Readiness probe failed.

Pour une vue plus moderne, vérifiez les EndpointSlices :

kubectl get endpointslice -n production -l kubernetes.io/service-name=my-service -o yaml

Chaque slice doit lister les mêmes adresses d'endpoints. Si vous avez récemment migré le contrôleur de service, confirmez que le contrôleur a mis à jour les EndpointSlices et pas seulement l'objet Endpoints hérité.

Tester la connectivité depuis un pod client

Créez un pod temporaire dans le même espace de noms :

kubectl run client-test --rm -it --image=busybox --restart=Never -- /bin/sh

À l'intérieur du pod, exécutez :

nslookup my-service.production.svc.cluster.local
wget -qO- http://my-service.production.svc.cluster.local:8080/health

La sortie attendue comprend le ClusterIP renvoyé par le DNS et la réponse HTTP 200 de l'endpoint de santé. Si le DNS échoue, vérifiez les pods CoreDNS. Si la connexion expire, vérifiez la politique réseau et kube-proxy.

Pour un service LoadBalancer, testez depuis l'extérieur du cluster :

curl -v https://app.example.com

Confirmez que le certificat TLS est valide et que la réponse provient de votre service. Vérifiez la cible du health check de l'équilibreur de charge et le seuil de bon état. Dans AWS, utilisez :

aws elbv2 describe-target-health --target-group-arn <arn>

Vérifier kube-proxy et les règles de service

Si vous mettez à niveau ou migrez les modes de kube-proxy (iptables vers IPVS), vous devez vérifier que le nouveau mode est correctement installé et que les règles iptables sont cohérentes.

Vérifiez le mode sur chaque nœud :

kubectl get pods -n kube-system -l k8s-app=kube-proxy -o jsonpath='{.items[*].spec.containers[0].args}' | tr ' ' '\n' | grep proxy-mode

Sur un nœud, inspectez les règles. Pour le mode iptables :

sudo iptables-save | grep -A5 "KUBE-SERVICES"

Vous devriez voir une chaîne pour chaque service. Pour le mode IPVS :

sudo ipvsadm -Ln

La sortie doit lister le ClusterIP du service, le planificateur (rr, wrr, etc.) et les IP des pods backend.

État du contrôleur et événements

Pour une mise à niveau ou une migration du contrôleur de service, surveillez ses journaux et événements :

kubectl logs -n kube-system -l app=aws-cloud-controller-manager --tail=50
kubectl get events -n production --field-selector involvedObject.name=my-service

Recherchez des messages concernant l'échec de la réconciliation de l'équilibreur de charge, les conflits de groupes de sécurité ou les erreurs d'annotation. Si le contrôleur ne peut pas trouver l'équilibreur de charge en raison de permissions manquantes, le service restera à l'état Pending pour l'IP du LoadBalancer. Dans ce cas, vérifiez les rôles IAM ou les informations d'identification du fournisseur.

Question rapide 2 sur 2

Quelle commande est utilisée pour exécuter une commande dans le premier Pod et le premier conteneur d'un Deployment ?

Le passage mentionne « kubectl exec deploy/my-deployment -- ls » comme la commande pour exécuter une commande dans le premier Pod et le premier conteneur d'un Deployment.

Modes d'échec et récupération

Malgré une planification minutieuse, des échecs surviennent. Cette section décrit les modes d'échec courants lors de la mise à niveau et de la migration des services, leurs symptômes et les étapes de récupération.

Mode d'échec 1 : Endpoints vides après un changement de sélecteur

Symptôme : vous modifiez le sélecteur pour pointer vers un nouvel ensemble de pods, mais kubectl get endpoints ne montre aucun endpoint.

Récupération :

  1. Annulez le changement de sélecteur en appliquant le manifeste de sauvegarde.
  2. Vérifiez que les nouveaux pods existent et ont des étiquettes correspondantes :
kubectl get pods -n production --show-labels | grep <nouvelle-étiquette>
  1. Si les étiquettes ne correspondent pas, corrigez-les avant de réappliquer le changement de sélecteur. Utilisez kubectl label pods <nom-du-pod> app=nouvelle-app --overwrite si nécessaire.
  1. Vérifiez que les endpoints réapparaissent.

Mode d'échec 2 : L'IP du LoadBalancer change après la migration

Symptôme : après la migration vers le gestionnaire de contrôleur cloud externe, le service obtient une nouvelle IP externe, ce qui fait pointer le DNS vers un nouvel équilibreur de charge et coupe tout le trafic.

Récupération :

  1. Supprimez immédiatement le nouveau service ou annulez la migration en réactivant l'ancien contrôleur.
  2. Vérifiez si l'ancien équilibreur de charge existe toujours et si son nom DNS est valide.
  3. Si possible, réaffectez l'ancien nom DNS à l'ancien équilibreur de charge en mettant à jour les enregistrements DNS manuellement.
  4. Recherchez pourquoi le nouveau contrôleur n'a pas adopté l'équilibreur de charge existant. L'annotation service.kubernetes.io/load-balancer-cleanup doit être présente sur l'ancien service avant la migration. Si absente, le nouveau contrôleur a créé un nouvel équilibreur de charge.

Exemple d'annotation correcte avant la migration :

kubectl annotate service my-service -n production \
  service.kubernetes.io/load-balancer-cleanup=true --overwrite

Confirmez ensuite que l'annotation est en place :

kubectl get service my-service -n production -o jsonpath='{.metadata.annotations}'

Mode d'échec 3 : La mise à niveau de kube-proxy casse le routage du service

Symptôme : après la mise à niveau de kube-proxy vers une nouvelle version ou un changement de mode proxy, certains services deviennent inaccessibles ou subissent des délais d'attente intermittents.

Récupération :

  1. Revenez à la version précédente de kube-proxy en utilisant votre méthode de déploiement (par exemple, kubectl rollout undo daemonset kube-proxy -n kube-system).
  2. Si vous changez du mode iptables à IPVS, assurez-vous que les modules du noyau sont chargés sur tous les nœuds. Sur chaque nœud, exécutez :
sudo modprobe ip_vs
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe ip_vs_sh
  1. Vérifiez également que --proxy-mode=ipvs est défini dans la configuration de kube-proxy. Sinon, mettez à jour la configmap et redémarrez kube-proxy.
  1. Après la restauration ou la correction, vérifiez la connectivité à l'aide du pod client de test décrit précédemment.

Mode d'échec 4 : Le contrôleur de service perd ses permissions

Symptôme : le service reste à l'état Pending pour l'IP du LoadBalancer, et les journaux du contrôleur affichent AccessDenied ou Forbidden.

Récupération :

  1. Vérifiez le rôle IAM du fournisseur cloud attaché au contrôleur. Assurez-vous qu'il dispose des permissions pour les opérations d'équilibreur de charge (par exemple, elasticloadbalancing:* pour AWS).
  2. Si vous utilisez un ServiceAccount avec IRSA, vérifiez l'annotation sur le ServiceAccount :
kubectl get serviceaccount aws-load-balancer-controller -n kube-system -o yaml
  1. Corrigez la politique IAM ou la liaison de rôle, puis redémarrez le pod du contrôleur. Surveillez l'état du service :
kubectl describe service my-service -n production

Attendez-vous à ce que le champ LoadBalancer Ingress soit renseigné en quelques minutes.

Principes généraux de récupération

  • Ayez toujours une sauvegarde du manifeste du service avant tout changement.
  • Utilisez kubectl apply --dry-run=server pour prévisualiser les changements sans les appliquer.
  • Pour les migrations complexes, utilisez une approche canari : migrez d'abord un service non critique, vérifiez, puis continuez.
  • Documentez les étapes de restauration pour chaque changement dans votre runbook avant d'exécuter le changement.
  • Si un changement provoque une panne, rétablissez d'abord le service, puis recherchez la cause profonde. Ne laissez pas un service cassé pendant que vous déboguez.

Checklist opérationnelle

La checklist suivante consolide le flux de travail sûr pour toute mise à niveau ou migration de service Kubernetes. Utilisez-la à chaque fois. Remplacez les valeurs d'exemple par les vôtres.

  • [ ] Inventaire capturé : exécutez kubectl version --short, kubectl get nodes -o wide et capturez le mode kube-proxy et les images des contrôleurs. Enregistrez la sortie avec un horodatage.
  • [ ] Service actuel exporté : kubectl get service my-service -n production -o yaml > service-actuel.yaml et enregistré dans Git.
  • [ ] Prérequis vérifiés : confirmez que la version du cluster est dans la plage prise en charge pour le contrôleur ou le proxy cible. Exemple : Kubernetes v1.27.3 et AWS Cloud Controller Manager v1.27.1.
  • [ ] Test dans un espace de noms local : appliquez un service modifié dans l'espace de noms test-ns et vérifiez la connectivité des endpoints à l'aide d'un client de test busybox.
  • [ ] Manifeste de sauvegarde créé : kubectl get service my-service -n production -o yaml > service-sauvegarde-1717000000.yaml et validé.
  • [ ] Plus petit changement appliqué : utilisez kubectl diff -f service-nouveau.yaml pour confirmer uniquement les modifications prévues. Appliquez avec kubectl apply -f service-nouveau.yaml.
  • [ ] Endpoints vérifiés : kubectl get endpoints my-service -n production montre les IP et ports des pods attendus. Exemple : 10.244.1.5:8080,10.244.2.3:8080.
  • [ ] Connectivité testée : depuis le pod client de test, wget -qO- http://my-service.production.svc.cluster.local:8080/health renvoie HTTP 200.
  • [ ] État du contrôleur vérifié : kubectl logs -n kube-system -l app=aws-cloud-controller-manager --tail=20 ne montre aucune erreur. kubectl get events -n production --field-selector involvedObject.name=my-service montre une réconciliation réussie.
  • [ ] Procédure de restauration documentée : pour ce changement, la commande de restauration est kubectl apply -f service-sauvegarde-1717000000.yaml. Si migration de contrôleur, documentez également comment revenir au contrôleur précédent.
  • [ ] Surveillance post-changement : mettez en place une surveillance du service et des endpoints pendant 10 minutes : kubectl get service my-service -n production -w et kubectl get endpoints my-service -n production -w.
  • [ ] Secrets non exposés : confirmez qu'aucun secret n'est dans le manifeste du service ou l'historique des commandes. Toutes les informations d'identification sont dans des secrets Kubernetes référencés par des annotations ou des pods de contrôleur.

Conclusion

La mise à niveau et la migration des services Kubernetes est un processus, pas une commande unique. Ce guide a parcouru les phases essentielles : inventaire de l'environnement, configuration sûre, vérification, modes d'échec et checklist opérationnelle. Le principe fondamental est d'observer avant de changer, de changer une chose à la fois, de vérifier avec du trafic réel et d'avoir toujours un chemin de restauration.

Commencez par un service à faible risque dans un espace de noms de test. Exécutez les commandes d'inventaire, exportez le manifeste actuel, apportez un seul changement (comme l'ajout d'une annotation de contrôleur) et vérifiez la connectivité depuis un client de test. Ce n'est qu'après ce succès que vous devez passer aux services en production et aux migrations plus importantes comme les mises à niveau de contrôleur ou les changements de mode proxy.

N'oubliez pas que les composants comme Ingress, EndpointSlice et Network Policy sont liés mais séparés ; incluez-les dans votre planification uniquement lorsqu'ils affectent directement la mise à niveau ou la migration du service. Une mise à niveau réussie n'est pas qu'un simple changement de version ; c'est une transition contrôlée et vérifiable qui maintient vos applications accessibles.

Votre prochaine action : choisissez un service dans votre cluster, exécutez les commandes d'inventaire des versions et de l'environnement et enregistrez la sortie. Identifiez ensuite une petite amélioration réversible que vous pouvez tester localement. Cela renforce la mémoire musculaire pour des migrations plus importantes et plus complexes. Les opérations fiables reposent sur des échecs visibles, des secrets protégés, des changements ciblés et une récupération documentée.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO