## Introduction

Le réseau Kubernetes repose sur kube-proxy pour implémenter les abstractions de Service, en traduisant les IP virtuelles et les ports en points de terminaison routables. Il s'exécute sur chaque nœud, surveille le plan de contrôle et programme le plan de données — généralement iptables, IPVS ou l'espace utilisateur. Lorsque kube-proxy se comporte mal, tout le cluster en ressent les effets : les services deviennent inaccessibles, l'établissement des connexions ralentit et la latence augmente. L'optimisation des performances n'est pas un réglage ponctuel ; c'est un processus itératif d'observation, d'hypothèse, de modification et de vérification.

Ce guide s'adresse aux opérateurs de cluster, aux ingénieurs DevOps et aux ingénieurs en fiabilité des sites qui gèrent Kubernetes en production. Il relie des actions de réglage pratiques — ajuster les intervalles de synchronisation, changer de mode de proxy, dimensionner correctement les ressources — à des résultats mesurables. Vous apprendrez à collecter les bonnes métriques, à appliquer les changements de configuration en toute sécurité et à éviter les pièges courants qui transforment un petit changement en panne.

L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment revenir en arrière si l'état attendu n'est pas atteint.

## Inventaire de la version et de l'environnement

Avant de toucher au moindre paramètre, connaissez la version de votre kube-proxy et son mode de déploiement. Les versions diffèrent par les modes par défaut, les métriques disponibles et les problèmes connus. Exécutez :

```bash
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o wide
```

La sortie attendue montre un pod par nœud. Notez le tag d'image, par exemple `v1.28.2`. Inspectez ensuite un pod :

```bash
kubectl describe pod -n kube-system kube-proxy-<node-name> | grep -A2 "Image:"
```

Prérequis :
- Accès au cluster avec `kubectl` et autorisations de lecture des pods, configmaps et daemonsets dans `kube-system`.
- Point de terminaison des métriques activé (généralement sur le port 10249). Vérifiez la configuration :

```bash
kubectl get configmap kube-proxy -n kube-system -o yaml
```

Recherchez `metricsBindAddress: 0.0.0.0:10249` et `mode: iptables` ou `ipvs`. Si les métriques sont désactivées, activez-les dans la configmap et redémarrez kube-proxy.

Rayon d'impact : la lecture est sans danger. Les modifications de la configmap affectent tous les nœuds. Sauvegardez toujours :

```bash
kubectl get configmap kube-proxy -n kube-system -o yaml > kube-proxy-config-backup-$(date +%Y%m%d).yaml
```

Vérification : après tout changement, confirmez que les pods sont en cours d'exécution et que la configuration est appliquée :

```bash
kubectl rollout status daemonset kube-proxy -n kube-system
```

Attendez le succès. Si `kubectl rollout status` échoue, consultez les journaux du pod :

```bash
kubectl logs -n kube-system kube-proxy-<node-name> --tail=50
```

## Chemin de configuration sécurisé

Kube-proxy est configuré via une ConfigMap dans `kube-system`. La modifier directement est risqué ; suivez plutôt un processus contrôlé.

### Métriques de base

Avant de modifier quoi que ce soit, capturez les métriques de performance de base. Utilisez `curl` sur le point de terminaison des métriques d'un nœud. Si vous êtes sur le nœud :

```bash
curl -s http://127.0.0.1:10249/metrics | grep -E 'kubeproxy_sync_proxy_rules_duration_seconds|kubeproxy_network_programming_duration_seconds'
```

Si vous n'êtes pas sur le nœud, utilisez `kubectl port-forward` :

```bash
kubectl port-forward -n kube-system pod/kube-proxy-<node-name> 10249:10249
```
Puis dans un autre terminal : `curl -s http://127.0.0.1:10249/metrics`.

Métriques clés :
- `kubeproxy_sync_proxy_rules_duration_seconds` : histogramme du temps de synchronisation des règles. Des percentiles élevés (p99 > 1s) indiquent un brassage iptables.
- `kubeproxy_network_programming_duration_seconds` : temps de programmation des règles réseau. Des valeurs élevées signifient des mises à jour lentes.

Enregistrez ces valeurs. Si votre Prometheus collecte kube-proxy, utilisez des requêtes comme :

```promql
histogram_quantile(0.99, sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket[5m])) by (le))
```

### Exemple de changement minimal

Supposons que la durée de synchronisation p99 soit de 2,3 s. Le coupable probable est la période de synchronisation iptables par défaut de 30 secondes trop courte ? En fait, la période de synchronisation (`iptables.syncPeriod`) est par défaut de 30 s. Si votre cluster a de nombreux services et points de terminaison, iptables peut devenir lent, et des synchronisations fréquentes aggravent la charge. Augmenter `syncPeriod` peut réduire l'utilisation du CPU mais retarde les mises à jour. Une première étape plus sûre est de passer en mode IPVS si pris en charge.

Pour changer de mode :

1. Modifiez la ConfigMap :

```bash
kubectl edit configmap kube-proxy -n kube-system
```

2. Changez `mode: "ipvs"` (ou définissez-le s'il est absent). Enregistrez et quittez.

3. Redémarrez les pods kube-proxy :

```bash
kubectl rollout restart daemonset kube-proxy -n kube-system
```

4. Vérifiez le mode :

```bash
kubectl logs -n kube-system kube-proxy-<node-name> | grep "Using ipvs Proxier"
```

Récupération : si les services se cassent, annulez la modification de la ConfigMap et redémarrez à nouveau.

Prérequis pour IPVS : les modules du noyau du nœud (`ip_vs`, `ip_vs_rr`, etc.) doivent être chargés. Vérifiez :

```bash
lsmod | grep ip_vs
```

S'ils manquent, kube-proxy revient à iptables (ou échoue). Activez les modules via la configuration du nœud avant de basculer.

## Vérification et diagnostics

Le réglage n'est aussi bon que votre vérification. Après les changements, comparez les métriques et testez la connectivité réelle des services.

### Test de connectivité d'un service

Depuis un pod à l'intérieur du cluster, testez un service :

```bash
kubectl run test-pod --image=busybox --restart=Never --rm -it -- wget -qO- --timeout=5 http://<service-name>.<namespace>.svc.cluster.local:8080
```

Remplacez par les détails de votre service. Le succès montre `200 OK` ou la sortie attendue. En cas de délai d'attente, vérifiez les points de terminaison :

```bash
kubectl get endpoints <service-name> -n <namespace>
```

Assurez-vous qu'il y a au moins une IP. S'il n'y en a pas, kube-proxy ne peut pas router.

### Mesure de la latence

Utilisez `curl` avec le chronométrage depuis un pod client :

```bash
kubectl exec -it <client-pod> -- curl -w "time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" -o /dev/null -s http://<service-name>.<namespace>.svc.cluster.local:8080
```

Enregistrez `time_connect` avant et après le réglage. Exemple de sortie :

```
time_namelookup: 0.004
time_connect: 0.012
time_starttransfer: 0.030
time_total: 0.035
```

Si `time_connect` est élevé (>100 ms), examinez la programmation des règles kube-proxy ou la latence réseau du nœud.

### Commandes de diagnostic

- Vérifiez les journaux kube-proxy :

```bash
kubectl logs -n kube-system kube-proxy-<node-name> --tail=100
```

- Dump des règles iptables actuelles (sur le nœud) :

```bash
sudo iptables-save | grep -c "KUBE-SERVICES"
```

Un grand nombre de règles (des milliers) peut ralentir la synchronisation. Avec IPVS, vérifiez la table des serveurs virtuels :

```bash
sudo ipvsadm -L -n | head
```

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

Kube-proxy peut échouer de manière subtile. Reconnaissez ces modes de défaillance courants et sachez comment récupérer.

### 1. Mauvaise configuration de la ConfigMap

**Symptôme :** Après modification de la ConfigMap, les pods kube-proxy plantent en boucle ou les services deviennent inaccessibles.

**Pourquoi :** YAML invalide ou options non prises en charge.

**Récupération :** Restaurez à partir de la sauvegarde :

```bash
kubectl apply -f kube-proxy-config-backup-<date>.yaml
kubectl rollout restart daemonset kube-proxy -n kube-system
```

Vérifiez ensuite l'état et les journaux des pods.

### 2. Modules du noyau IPVS manquants

**Symptôme :** Les journaux kube-proxy affichent `Failed to load kernel modules` ou `IPVS required kernel modules not found`. Les pods peuvent encore fonctionner avec le repli iptables, mais les performances en souffrent.

**Pourquoi :** L'image du nœud manque de modules IPVS.

**Récupération :** Installez les modules du noyau sur le nœud (par exemple, via le gestionnaire de paquets) ou revenez au mode iptables. Documentez les exigences de provisionnement des nœuds.

### 3. Épuisement de la table conntrack

**Symptôme :** `nf_conntrack: table full, dropping packet` dans les journaux du noyau. Délais de connexion sous charge.

**Pourquoi :** Fort taux de rotation des connexions, surtout en mode iptables. La valeur par défaut de `nf_conntrack_max` est trop basse.

**Récupération :** Augmentez la taille de la table conntrack (avec prudence) :

```bash
sudo sysctl -w net.netfilter.nf_conntrack_max=1048576
```

Rendez-la permanente dans `/etc/sysctl.conf`. Envisagez de réduire la charge de suivi des connexions en utilisant IPVS (qui a moins de surcharge conntrack) ou en ajustant le cycle de vie des pods.

### 4. Durée de synchronisation élevée après la mise à l'échelle des nœuds

**Symptôme :** La durée de synchronisation p99 dépasse 5 s lorsque de nombreux pods/points de terminaison changent.

**Pourquoi :** iptables est O(n) en nombre de règles. Avec des milliers de points de terminaison, les mises à jour des règles deviennent lentes.

**Récupération :** Passez à IPVS, qui utilise des tables de hachage (recherches O(1)) et évolue mieux. Ou ajustez `iptables.syncPeriod` à 60 s pour réduire la fréquence de synchronisation, mais cela retarde les mises à jour.

Testez toujours les changements d'abord dans un cluster non productif.

## Pièges courants et comment les éviter

1. **Modifier les paramètres sans mesures de base.** Sans métriques préalables, vous ne pouvez pas savoir si le réglage a aidé ou nui. Capturez toujours les métriques de base pendant au moins 24 heures.

2. **Ignorer les limites de ressources des nœuds.** kube-proxy utilise du CPU et de la mémoire, surtout en mode IPVS avec de nombreux services. Assurez-vous que le DaemonSet a des demandes/limites de ressources raisonnables. Vérifiez l'utilisation actuelle :

```bash
kubectl top pod -n kube-system -l k8s-app=kube-proxy
```

Si proche des limites, ajustez dans la spécification du DaemonSet.

3. **Négliger les paramètres du noyau.** Pour iptables, `net.netfilter.nf_conntrack_max` et `net.ipv4.ip_forward` sont essentiels. Pour IPVS, `net.ipv4.vs.conntrack` peut avoir de l'importance. Alignez les paramètres sysctl des nœuds avec les exigences de kube-proxy.

4. **Redémarrer kube-proxy pendant un trafic élevé.** Le redémarrage provoque une interruption temporaire car les règles sont reprogrammées. Planifiez les changements pendant les fenêtres de maintenance ou utilisez des mises à jour progressives avec `kubectl rollout restart` et surveillez.

5. **Ne pas tester la récupération.** Avant de faire un changement, ayez un plan de retour en arrière : sauvegardez la configuration, connaissez la commande exacte pour annuler et vérifiez que le retour fonctionne.

6. **Mal comprendre le planificateur IPVS.** Le round-robin par défaut peut ne pas être optimal pour toutes les charges de travail. Envisagez `lc` (least connections) ou `sh` (source hashing) si nécessaire. Définissez-le dans la ConfigMap sous `ipvs.scheduler`. Documentez pourquoi.

## Liste de contrôle des opérations

Utilisez cette liste de contrôle pour chaque changement de kube-proxy. Chaque élément est assigné à un propriétaire spécifique (par exemple, le responsable SRE) et a une fréquence de révision.

| Étape | Action | Propriétaire | Fréquence / Révision |
|---|---|---|---|
| 1 | Capturer les métriques de base (durée de synchronisation, CPU, mémoire) | SRE de garde | Avant chaque changement |
| 2 | Sauvegarder la ConfigMap actuelle | Ingénieur plateforme | Avant chaque changement |
| 3 | Évaluer le rayon d'impact : combien de nœuds ? Services critiques ? | Chef d'équipe | Avant chaque changement |
| 4 | Tester le changement dans un cluster de staging | Ingénieur DevOps | Trimestriel ou par changement |
| 5 | Appliquer le changement en production via GitOps ou PR approuvée | Responsable des mises en production | Par changement |
| 6 | Vérifier les métriques et la connectivité des services | SRE de garde | Dans les 15 minutes après le changement |
| 7 | Documenter le résultat dans le runbook | Propriétaire (assigner) | Immédiatement après le changement |
| 8 | Examiner les tendances de performance chaque semaine | Responsable SRE | Hebdomadaire |
| 9 | Revoir les paramètres de réglage si la charge de travail change | Responsable ingénierie | Mensuel ou lors de versions majeures |

Exemple : Priya Shah, responsable ingénierie, examine les histogrammes de durée de synchronisation chaque lundi et décide si un réglage supplémentaire est nécessaire.

## Conclusion

L'optimisation des performances de kube-proxy est une discipline continue. Commencez par l'inventaire de l'environnement et les métriques de base, apportez des changements minimaux avec des plans de retour clairs, vérifiez les résultats avec des commandes concrètes et apprenez des modes de défaillance. En suivant des pratiques de configuration sûres et en évitant les pièges courants, vous pouvez garder le réseau Kubernetes rapide et fiable. Attribuez des responsabilités claires et révisez régulièrement les décisions de réglage à mesure que votre cluster évolue. Le bénéfice est une latence plus faible, moins de connexions interrompues et une plateforme plus prévisible pour vos applications.