## Introduction

Les adresses IP virtuelles (VIP) de Kubernetes sont les identités réseau stables que les clients utilisent pour atteindre les services exécutés dans un cluster. Elles ne sont pas liées à un pod ou à un nœud unique ; elles sont plutôt implémentées par les composants du plan de contrôle et du plan de données tels que kube-proxy, les gestionnaires de contrôleur cloud et les plugins réseau. Au fil du temps, les clusters doivent mettre à niveau ces composants, migrer d'une implémentation de VIP à une autre (par exemple, du mode iptables au mode IPVS) ou déplacer des services entre différentes technologies d'équilibrage de charge. Mal exécutées, ces modifications peuvent entraîner des interruptions d'application généralisées, des pertes de trafic ou des règles réseau défaillantes.

Ce guide propose une approche pratique, étape par étape, pour mettre à niveau et migrer les adresses IP virtuelles Kubernetes. Il s'adresse aux ingénieurs de plateforme, aux consultants DevOps et aux équipes techniques de startups qui doivent effectuer ces opérations en toute sécurité. Nous mettons l'accent sur les commandes réelles, les sorties attendues, les signaux d'échec et les décisions de récupération. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, protéger les données sensibles, vérifier chaque étape et documenter les chemins de récupération avant d'en avoir besoin.

Tout au long de l'article, nous utiliserons un exemple concret de mise à niveau de kube-proxy du mode iptables au mode IPVS, et de migration d'un service d'un équilibreur de charge hérité d'un fournisseur cloud vers une implémentation plus récente. Les principes s'appliquent à d'autres composants liés aux VIP, mais ce scénario concret maintient les conseils ancrés dans la pratique.

## 1. Inventaire des versions et de l'environnement

Avant toute mise à niveau ou migration, vous devez savoir exactement ce qui est en cours d'exécution. Cela inclut la version du cluster, le système d'exploitation du nœud, le mode et la version de kube-proxy, le plugin réseau et la version du contrôleur d'équilibreur de charge du fournisseur cloud. Une incompatibilité de versions entre composants peut entraîner un comportement imprévisible des VIP.

### Commandes d'observation en lecture seule

Commencez par des commandes en lecture seule pour capturer l'état actuel. Ces commandes ne modifient rien et peuvent être exécutées en toute sécurité à tout moment.

Vérifiez les versions du cluster et des nœuds :
```bash
kubectl version --short
kubectl get nodes -o wide
```

La sortie attendue affiche les versions client et serveur, et pour chaque nœud son IP interne, son IP externe le cas échéant, et le système d'exploitation. Par exemple :
```
Client Version: v1.28.2
Server Version: v1.27.6
NAME    STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE
node1   Ready    control-plane   12d   v1.27.6   10.0.0.4      <none>        Ubuntu 22.04.3 LTS
node2   Ready    <none>          12d   v1.27.6   10.0.0.5      <none>        Ubuntu 22.04.3 LTS
```

Vérifiez le mode et la version de kube-proxy. Le mode est généralement défini via une ConfigMap ou un paramètre de ligne de commande. Sur chaque nœud, vous pouvez inspecter le pod kube-proxy en cours d'exécution (s'il s'exécute en DaemonSet) ou le processus.

Si kube-proxy s'exécute en DaemonSet :
```bash
kubectl get daemonset -n kube-system kube-proxy -o wide
kubectl logs -n kube-system <kube-proxy-pod> | grep -i mode
```
Ligne de journal attendue pour le mode iptables :
```
I1012 10:00:00.000000       1 server_others.go:212] Using iptables Proxier.
```
Pour le mode IPVS :
```
I1012 10:00:00.000000       1 server_others.go:212] Using ipvs Proxier.
```

Vérifiez la version du contrôleur d'équilibreur de charge du fournisseur cloud, le cas échéant. Par exemple, sur AWS, vérifiez le déploiement du contrôleur d'équilibreur de charge AWS :
```bash
kubectl get deployment -n kube-system aws-load-balancer-controller -o yaml | grep image
```

### Prérequis et compatibilité

Avant de modifier quoi que ce soit, confirmez que la nouvelle version ou le nouveau mode est compatible avec la version de votre cluster et votre plugin réseau. Par exemple, le mode IPVS nécessite les modules du noyau `ip_vs`, `ip_vs_rr`, `ip_vs_wrr`, `ip_vs_sh`, et `nf_conntrack`. Vous pouvez les vérifier sur un nœud :
```bash
lsmod | grep ip_vs
```
S'ils ne sont pas chargés, vous devrez peut-être les installer ou les charger manuellement.

Consultez également le changelog de Kubernetes pour tout changement concernant kube-proxy ou le comportement des VIP de Service. Pour les migrations d'équilibreur de charge cloud, consultez le guide de migration du fournisseur pour connaître les annotations et CRD prises en charge.

### Le plus petit changement justifié

Ne procédez jamais à une mise à niveau big-bang. Par exemple, si vous passez d'iptables à IPVS, faites-le un nœud à la fois ou utilisez une mise à jour progressive du DaemonSet kube-proxy. Pour une migration de service, commencez par un service de test avec un trafic minimal, ou utilisez un déploiement canari.

## 2. Chemin de configuration sécurisé

Une fois l'inventaire réalisé, planifiez le changement de configuration. La clé est d'effectuer le changement de manière contrôlée et réversible.

### Sauvegarder la configuration actuelle

Avant de modifier un composant, exportez sa configuration actuelle. Pour kube-proxy, la configuration se trouve souvent dans une ConfigMap :
```bash
kubectl get configmap -n kube-system kube-proxy -o yaml > kube-proxy-config-backup.yaml
```
Pour un service, exportez son YAML :
```bash
kubectl get service my-service -o yaml > my-service-backup.yaml
```
Stockez ces sauvegardes dans un emplacement sous contrôle de version.

### Appliquer les changements progressivement

Pour changer le mode de kube-proxy, vous pouvez modifier la ConfigMap puis redémarrer les pods kube-proxy. Cependant, une mise à jour progressive du DaemonSet est plus sûre. Si vous utilisez un fichier de configuration, modifiez-le puis appliquez :
```bash
kubectl edit configmap -n kube-system kube-proxy
```
Changez `mode: ""` en `mode: "ipvs"` (ou de `iptables` à `ipvs`), puis enregistrez. Après l'enregistrement, déclenchez une mise à jour progressive :
```bash
kubectl rollout restart daemonset -n kube-system kube-proxy
```

Surveillez la mise à jour :
```bash
kubectl rollout status daemonset -n kube-system kube-proxy
```
Sortie attendue :
```
Waiting for daemon set "kube-proxy" rollout to finish: 0 out of 3 new pods have been updated...
Waiting for daemon set "kube-proxy" rollout to finish: 1 out of 3 new pods have been updated...
...
daemon set "kube-proxy" successfully rolled out
```

Pour la migration d'un service, vous pouvez créer un nouveau service avec les annotations du nouvel équilibreur de charge et déplacer progressivement le trafic. Par exemple, si vous migrez d'un ELB AWS hérité vers un Network Load Balancer (NLB), créez un nouveau service avec les annotations appropriées :
```yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service-nlb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer
```
Appliquez-le, puis mettez à jour le DNS ou l'ingress pour pointer progressivement vers la nouvelle VIP.

### Utiliser des valeurs fictives au lieu de secrets

Lorsque vous testez des changements de configuration, n'utilisez jamais de véritables secrets. Utilisez des valeurs factices ou des espaces réservés spécifiques à l'environnement (par exemple, `example.com` pour le DNS, `10.0.0.0/16` pour le CIDR) dans vos manifestes de test. Cela évite les fuites accidentelles et indique clairement ce qui doit être personnalisé par environnement.

## 3. Vérification et diagnostics

Après avoir appliqué les changements, vous devez vérifier que la VIP fonctionne correctement. Cela implique de vérifier la connectivité, d'observer le comportement du plan de données et d'inspecter les journaux.

### Vérifier les services et les endpoints

Tout d'abord, confirmez que le service dispose d'une VIP valide et que les endpoints sont renseignés :
```bash
kubectl get service my-service -o wide
kubectl get endpoints my-service
```
Sortie attendue pour un service sain :
```
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
my-service   LoadBalancer   10.96.0.100    203.0.113.10  80:30080/TCP   1h
NAME         ENDPOINTS           AGE
my-service   10.244.1.5:8080     1h
```
Si les endpoints sont vides, le sélecteur peut ne correspondre à aucun pod. Vérifiez les étiquettes des pods.

### Tester la connectivité

Depuis l'intérieur du cluster, testez l'accès à la ClusterIP :
```bash
kubectl run test-pod --image=alpine --restart=Never --rm -it -- sh
/ # wget -qO- http://10.96.0.100
```
Vous devriez voir la réponse de votre application. Pour un service de type LoadBalancer, testez l'IP externe depuis l'extérieur du cluster (ou depuis un nœud).

### Diagnostiquer les problèmes de kube-proxy

Si le trafic échoue, vérifiez les journaux de kube-proxy pour détecter les erreurs :
```bash
kubectl logs -n kube-system <kube-proxy-pod> --tail=50
```
Recherchez les messages concernant l'échec de synchronisation des règles, les erreurs IPVS ou la connectivité au serveur API. Pour le mode IPVS, vous pouvez inspecter les règles IPVS sur le nœud :
```bash
ipvsadm -Ln
```
Sortie attendue montrant les services virtuels et leurs serveurs réels, par exemple :
```
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.100:80 rr
  -> 10.244.1.5:8080              Masq    1      0          0
```
Si les règles IPVS sont manquantes ou incorrectes, kube-proxy peut ne pas fonctionner en mode IPVS, ou il peut y avoir un problème de permission.

### Valider le déplacement du trafic

Lors de la migration des services, utilisez une approche canari : envoyez un petit pourcentage du trafic vers la nouvelle VIP et surveillez les taux d'erreur. Par exemple, utilisez un script simple avec curl pour interroger les deux points de terminaison et comparer les réponses. Ou, si vous disposez d'un contrôleur d'ingress, ajustez ses règles de routage pour répartir le trafic.

## 4. Modes de défaillance et récupération

Quelle que soit la prudence, les choses peuvent mal tourner. Prévoyez les modes de défaillance courants et sachez comment récupérer rapidement.

### Modes de défaillance courants

1. **Les pods kube-proxy plantent après le changement de mode** : cela se produit souvent lorsque les modules du noyau requis sont manquants ou que les autorisations sont insuffisantes. Les journaux des pods afficheront des erreurs. Récupération : vérifiez les modules du noyau du nœud, assurez-vous que kube-proxy dispose des privilèges nécessaires (généralement il s'exécute en mode privilégié ou avec CAP_NET_ADMIN), ou revenez au mode précédent en modifiant la ConfigMap et en redémarrant.

2. **La VIP du service devient inaccessible après la migration** : cela peut être dû à des règles de pare-feu, des changements de politique réseau ou une mauvaise configuration de l'équilibreur de charge cloud. Récupération : vérifiez la console du fournisseur cloud pour l'état de l'équilibreur de charge, vérifiez les groupes de sécurité et testez la connectivité étape par étape. Si nécessaire, rétablissez le YAML du service à la configuration précédente en utilisant la sauvegarde.

3. **Un déploiement partiel laisse des modes mixtes** : si seuls certains nœuds sont passés à IPVS, le trafic passant par ces nœuds peut se comporter différemment (par exemple, différents algorithmes de planification). Récupération : terminez le déploiement ou revenez en arrière sur tous les nœuds en modifiant la ConfigMap et en redémarrant tous les pods kube-proxy.

4. **La résolution DNS échoue pour la VIP** : si vous utilisez ExternalDNS ou similaire, la nouvelle VIP peut ne pas être enregistrée dans le DNS. Récupération : vérifiez les journaux d'ExternalDNS, assurez-vous que les annotations du service sont correctes et vérifiez manuellement les enregistrements DNS.

### Procédure de rollback (retour en arrière)

Ayez toujours un plan de rollback prêt avant d'effectuer des changements. Pour le changement de mode de kube-proxy, le rollback est simple :
```bash
kubectl edit configmap -n kube-system kube-proxy
# remettre le mode à la valeur précédente
kubectl rollout restart daemonset -n kube-system kube-proxy
```

Pour la migration d'un service, vous pouvez simplement supprimer le nouveau service et réappliquer l'ancien si le trafic n'a pas encore été entièrement déplacé. Si le trafic a été déplacé et que vous devez revenir en arrière, mettez à jour le DNS ou l'ingress pour pointer à nouveau vers l'ancienne VIP, puis supprimez le nouveau service après avoir confirmé qu'aucun trafic ne lui est destiné.

### Surveillance et alertes

Mettez en place une surveillance pour les métriques clés : durée de synchronisation de kube-proxy, erreurs iptables/ipvs, disponibilité des endpoints de service et contrôles de santé de l'équilibreur de charge. Utilisez des tableaux de bord Prometheus et Grafana pour les visualiser. Les alertes doivent se déclencher si les endpoints sont vides pour un service, si kube-proxy ne s'exécute sur aucun nœud, ou si l'IP externe ne répond pas.

## 5. Liste de contrôle des opérations

Utilisez cette liste de contrôle avant, pendant et après la mise à niveau ou la migration. Chaque élément a un propriétaire et une fréquence de révision. Le propriétaire est une seule personne responsable, pas une équipe.

| Étape | Action | Commande / Signal | Propriétaire | Fréquence de révision |
|------|--------|------------------|-------|------------------|
| 1. Inventaire | Capturer les versions du cluster et des composants | `kubectl version --short`, `kubectl get nodes -o wide`, vérifier les journaux du mode kube-proxy | Priya Shah, Responsable Plateforme | Avant chaque mise à niveau, base trimestrielle |
| 2. Sauvegarde | Exporter les configurations actuelles | `kubectl get configmap -n kube-system kube-proxy -o yaml > backup.yaml` et sauvegardes YAML des services | Carlos Mendez, SRE | À chaque changement, stocké dans git |
| 3. Compatibilité | Vérifier les prérequis pour la nouvelle version/mode | Vérifier les modules du noyau, la documentation du fournisseur cloud | Lin Wei, Ingénieur Réseau | Par mise à niveau |
| 4. Tester en staging | Appliquer le changement à un cluster de test d'abord | Exécuter les étapes de migration dans l'environnement de préproduction | Priya Shah | Avant le changement en production |
| 5. Déploiement en production | Appliquer le changement progressivement | `kubectl edit configmap ...`, `kubectl rollout restart daemonset ...` | Carlos Mendez | Pendant la fenêtre de maintenance |
| 6. Vérifier | Tester la connectivité de la VIP | `kubectl run test-pod ... wget http://<cluster-ip>` | Lin Wei | Immédiatement après le déploiement |
| 7. Surveiller | Surveiller les erreurs et les anomalies de trafic | Vérifier les journaux kube-proxy, les métriques de l'équilibreur de charge | Carlos Mendez | Pendant 24 heures après le changement |
| 8. Documenter | Mettre à jour les runbooks et les schémas d'architecture | Rédiger un rapport post-incident si nécessaire | Priya Shah | Dans la semaine suivant le changement |

## 6. Pièges courants et comment les éviter

D'après notre expérience, les erreurs suivantes sont courantes lors de la manipulation des VIP Kubernetes.

### Piège 1 : Vouloir tout changer d'un coup

**Pourquoi cela arrive** : Les équipes veulent minimiser les temps d'arrêt et regroupent plusieurs changements dans une seule fenêtre de maintenance. Par exemple, mettre à niveau kube-proxy et changer de plugin réseau en même temps.

**Comment l'éviter** : N'effectuez qu'un seul changement à la fois. Si vous devez mettre à niveau plusieurs composants, séquencez-les avec des tests intermédiaires. Par exemple, mettez d'abord à niveau kube-proxy, vérifiez, puis mettez à niveau le plugin réseau.

**Récupération** : Si vous avez déjà effectué un changement groupé et que des problèmes surviennent, revenez à la dernière configuration saine connue pour tous les composants modifiés, puis réappliquez les changements un par un.

### Piège 2 : Ne pas vérifier les modules du noyau pour IPVS

**Pourquoi cela arrive** : Le mode IPVS nécessite des modules du noyau spécifiques qui peuvent ne pas être chargés sur des images de système d'exploitation minimales. Le pod kube-proxy peut démarrer mais échouer à programmer les règles IPVS, entraînant des pertes de trafic.

**Comment l'éviter** : Avant de passer à IPVS, exécutez `lsmod | grep ip_vs` sur tous les nœuds. Si les modules sont manquants, installez `ipvsadm` et chargez les modules, ou configurez le système d'exploitation pour les charger au démarrage. Certains services Kubernetes gérés le font automatiquement, mais les clusters autogérés nécessitent des vérifications manuelles.

**Récupération** : Si vous découvrez des modules manquants après le changement, vous pouvez soit les charger à la volée et redémarrer kube-proxy, soit revenir au mode iptables jusqu'à ce que les modules soient correctement installés sur l'ensemble du cluster.

### Piège 3 : Ignorer les Endpoint Slices

**Pourquoi cela arrive** : Les Endpoint Slices sont une API plus récente pour suivre les endpoints, et les composants plus anciens peuvent ne pas être compatibles. Lors d'une mise à niveau, si kube-proxy est mis à jour mais pas le contrôleur EndpointSlice, le routage VIP peut échouer.

**Comment l'éviter** : Assurez-vous que tous les composants qui consomment des endpoints sont mis à jour ensemble ou sont rétrocompatibles. Consultez la matrice de compatibilité des versions Kubernetes.

**Récupération** : Si les endpoints ne sont pas renseignés dans les EndpointSlices, vérifiez les journaux du contrôleur et revenez en arrière si nécessaire.

### Piège 4 : Ne pas tester avec un canari

**Pourquoi cela arrive** : Les équipes appliquent un nouveau service LoadBalancer et basculent immédiatement tout le trafic via DNS, en espérant que tout se passe bien.

**Comment l'éviter** : Utilisez une approche canari. Créez le nouveau service à côté de l'ancien, testez-le avec un petit sous-ensemble du trafic (par exemple, avec un DNS pondéré ou un contrôleur d'ingress), et augmentez progressivement le pourcentage tout en surveillant les taux d'erreur.

**Récupération** : Si le nouveau service échoue sous le trafic canari, supprimez simplement la règle de routage canari et enquêtez sans affecter la plupart des utilisateurs.

## Conclusion

La mise à niveau et la migration des adresses IP virtuelles Kubernetes sont des opérations critiques qui nécessitent une planification, une observation et une vérification minutieuses. Les principaux points à retenir de ce guide sont :

- Commencez toujours par un inventaire complet des versions et des configurations.
- Effectuez les changements par petites étapes réversibles.
- Utilisez des commandes concrètes pour vérifier la fonctionnalité à chaque étape.
- Connaissez les modes de défaillance courants et ayez un plan de rollback.
- Maintenez une liste de contrôle des opérations avec des propriétaires clairs et des fréquences de révision.

En suivant ces pratiques, vous pouvez minimiser les temps d'arrêt et vous assurer que vos services restent accessibles tout au long de la mise à niveau ou de la migration. Comme prochaine étape, choisissez une vérification à faible risque de ce guide, comme vérifier le mode de kube-proxy ou tester la connectivité d'un service, et exécutez-la sur votre cluster pour établir une base de référence.

N'oubliez pas : un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de la récupération avant qu'un incident ne force la décision.