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 :
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 :
kubectl describe pod -n kube-system kube-proxy-<node-name> | grep -A2 "Image:"
Prérequis :
- Accès au cluster avec
kubectlet autorisations de lecture des pods, configmaps et daemonsets danskube-system. - Point de terminaison des métriques activé (généralement sur le port 10249). Vérifiez la configuration :
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 :
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 :
kubectl rollout status daemonset kube-proxy -n kube-system
Attendez le succès. Si kubectl rollout status échoue, consultez les journaux du pod :
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 :
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 :
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 :
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 :
- Modifiez la ConfigMap :
kubectl edit configmap kube-proxy -n kube-system
- Changez
mode: "ipvs"(ou définissez-le s'il est absent). Enregistrez et quittez.
- Redémarrez les pods kube-proxy :
kubectl rollout restart daemonset kube-proxy -n kube-system
- Vérifiez le mode :
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 :
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 :
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 :
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 :
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 :
kubectl logs -n kube-system kube-proxy-<node-name> --tail=100
- Dump des règles iptables actuelles (sur le nœud) :
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 :
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 :
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) :
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
- 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.
- 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 :
kubectl top pod -n kube-system -l k8s-app=kube-proxy
Si proche des limites, ajustez dans la spécification du DaemonSet.
- Négliger les paramètres du noyau. Pour iptables,
net.netfilter.nf_conntrack_maxetnet.ipv4.ip_forwardsont essentiels. Pour IPVS,net.ipv4.vs.conntrackpeut avoir de l'importance. Alignez les paramètres sysctl des nœuds avec les exigences de kube-proxy.
- 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 restartet surveillez.
- 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.
- 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) oush(source hashing) si nécessaire. Définissez-le dans la ConfigMap sousipvs.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.