Ce document explique comment résoudre les problèmes liés à la répartition inégale du trafic vers les services Kubernetes.
Identifier les symptômes d'une répartition inégale du trafic
Une répartition inégale du trafic, souvent appelée "points chauds", se produit lorsqu'un sous-ensemble de pods ou de nœuds gère une quantité disproportionnée de la charge de travail totale, tandis que d'autres restent sous-utilisés.
Les symptômes courants incluent les suivants :
- Goulots d'étranglement des performances : les utilisateurs peuvent rencontrer des délais avant expiration intermittents, des erreurs HTTP 5xx ou une perte de paquets sur des connexions réseau surutilisées.
- Épuisement des ressources : des pods ou des nœuds spécifiques affichent une utilisation du processeur ou de la mémoire nettement supérieure à celle du reste du parc.
- Schémas de déséquilibre du trafic:
- Déséquilibre par pod : le trafic n'atteint qu'un petit sous-ensemble de pods disponibles, même si tous les pods sont signalés comme étant opérationnels et prêts.
- Déséquilibre par nœud : un ou plusieurs nœuds reçoivent beaucoup plus de
paquets ou de requêtes que d'autres, ce qui est souvent le cas lorsque vous utilisez
externalTrafficPolicy: Localavec un placement de pods inégal. - Sessions client persistantes : toutes les requêtes d'un même client à volume élevé sont systématiquement acheminées vers le même pod de backend.
Diagnostic à l'aide de Cloud Monitoring
Pour confirmer ces symptômes, visualisez les schémas de trafic à l'aide des métriques suivantes :
- Pour la couche 7 (Ingress/passerelle) : tracez
loadbalancing.googleapis.com/backend/request_countet regroupez-les parbackend_targetpour comparer les volumes de requêtes entre différents backends.
Comprendre les causes courantes d'une répartition inégale du trafic
Cette section décrit les causes courantes d'une répartition inégale du trafic vers les services Kubernetes. Ce déséquilibre peut entraîner des goulots d'étranglement des performances, un épuisement des ressources sur certains pods et une disponibilité réduite des applications, certains pods recevant beaucoup plus de trafic que d'autres, tandis que certains en reçoivent très peu ou pas du tout.
L'affinité de session entraîne une répartition inégale
Le problème suivant se produit lorsque les équilibreurs de charge avec l'affinité de session activée acheminent systématiquement les requêtes du même client vers le même pod de backend. Si un client particulier génère un volume de trafic important, ce pod est surchargé, ce qui crée un point chaud où il reçoit beaucoup plus de charge que d'autres, tandis que d'autres pods restent sous-utilisés.
Vous pouvez configurer l'affinité de session dans les objets de service Kubernetes à l'aide du champ sessionAffinity.
Lorsque sessionAffinity est défini sur ClientIP, le service s'assure que toutes les connexions provenant de la même adresse IP client sont systématiquement acheminées vers le même pod de backend. Cela fournit une véritable affinité de session basée sur l'adresse IP du client.
Lorsque sessionAffinity est défini sur None (comportement par défaut), les équilibreurs de charge de couche 4 distribuent généralement les connexions à l'aide d'un hachage de différents paramètres réseau, tels qu'un quadruplet (adresse IP du client, adresse IP de destination, port de destination, protocole) ou un quintuplet (y compris le port source). Bien que ce hachage puisse fournir une certaine "persistance" de connexion en acheminant systématiquement les connexions avec des valeurs de tuple identiques vers le même backend, il ne garantit pas que toutes les connexions provenant d'une adresse IP client spécifique seront toujours dirigées vers le même pod si d'autres éléments de tuple changent.
Pour en savoir plus, consultez la section Affinité de session.
Pour GKE Gateway, le CRD GCPTrafficDistributionPolicy configure l'affinité de session. Pour en savoir plus, consultez la section Configurer des ressources de passerelle
à l'aide de
règles.
Pour les équilibreurs de charge réseau passthrough externes régionaux, vous pouvez utiliser l'affinité de session pour maintenir la persistance de la connexion à un backend spécifique. Toutefois, notez que l'affinité de session peut elle-même entraîner une répartition inégale si certains clients génèrent plus de trafic que d'autres.
Pour en savoir plus, consultez les sections Affinité de session et Présentation de l'équilibreur de charge réseau passthrough externe basé sur un service de backend.
L'exemple suivant montre un fichier manifeste de service avec sessionAffinity: ClientIP :
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
sessionAffinity: ClientIP # This can cause uneven distribution
ports:
- port: 80
targetPort: 8080
selector:
app: my-app
Le pooling de connexions entraîne une répartition inégale
Le pooling de connexions se produit lorsque les équilibreurs de charge réutilisent les connexions existantes à des pods spécifiques, même si d'autres pods disposent d'une capacité disponible. Ce comportement peut entraîner un déséquilibre si certaines connexions sont plus longues ou gèrent beaucoup plus de requêtes que d'autres. Cela concentre le trafic sur certains pods, comme l'affinité de session, créant des points chauds où ces pods sont surchargés tandis que d'autres restent sous-utilisés.
Les équilibreurs de charge implémentent le pooling de connexions pour améliorer les performances en réduisant la surcharge liée à l'établissement de nouvelles connexions. Toutefois, s'il n'est pas géré correctement, le pooling de connexions peut entraîner une répartition inégale du trafic, en particulier avec les applications qui maintiennent des connexions de longue durée.
Pour atténuer la répartition inégale causée par le pooling de connexions, implémentez des stratégies au niveau de l'application ou du client :
Configurer les clients pour qu'ils utilisent plusieurs connexions : au lieu de s'appuyer sur une seule connexion de longue durée, configurez les clients pour qu'ils ouvrent et gèrent un pool de plusieurs connexions à l'équilibreur de charge. Cela permet à l'équilibreur de charge de répartir les nouvelles tentatives de connexion entre les pods de backend disponibles, ce qui améliore la répartition globale du trafic.
Fermer et rouvrir périodiquement les connexions : pour les applications qui maintiennent naturellement des connexions de longue durée, configurez-les ou configurez leurs clients pour qu’ils ferment et rouvrent périodiquement les connexions. Bien que cela entraîne une légère surcharge liée au rétablissement de la connexion, l'équilibreur de charge a de nouvelles possibilités de distribuer les tentatives de connexion suivantes à différents pods de backend moins utilisés. Cette approche est particulièrement efficace pour les services où la fin et le rétablissement de la connexion ne sont pas trop perturbants.
Implémenter un drainage de connexion agressif : assurez-vous que vos pods sont configurés pour un arrêt progressif et un drainage de connexion. Lorsqu'un pod est arrêté de manière progressive (par exemple, lors d'un déploiement ou d'un scaling à la baisse), l'équilibreur de charge doit cesser de lui envoyer de nouvelles connexions et autoriser les connexions existantes à se terminer ou à être drainées. Cela permet au trafic de passer plus facilement à d'autres pods et d'éviter qu'il ne soit concentré sur les pods en cours d'arrêt.
En gérant activement le comportement de connexion, vous pouvez aider les équilibreurs de charge à répartir le trafic de manière plus uniforme, même avec des connexions de longue durée.
Le hachage à 5 tuples entraîne une répartition inégale
Il s'agit du comportement par défaut de nombreux équilibreurs de charge de couche 4 lorsque vous ne configurez pas explicitement l'affinité de session. Si de nombreuses connexions proviennent du même client ou utilisent les mêmes combinaisons de ports, la répartition est inégale.
Pour résoudre les déséquilibres causés par le hachage, tenez compte des points suivants :
Utiliser l'équilibrage de charge de couche 7 : GKE Ingress et Gateway fonctionnent au niveau de la requête, ce qui leur permet de répartir les requêtes d'un seul client sur plusieurs pods de backend.
Ajuster le comportement du client : configurez les clients pour qu’ils utilisent plusieurs connexions ou un pool plus important de ports sources.
Une répartition inégale des pods entre les nœuds entraîne une répartition inégale
Ce problème se produit lorsque les pods ne sont pas répartis de manière uniforme entre les nœuds et que l'équilibreur de charge n'utilise pas l'équilibrage de charge natif en conteneurs. Les nœuds avec plus de pods reçoivent plus de trafic, ce qui peut entraîner une surcharge de certains nœuds tandis que d'autres sont sous-utilisés.
Ce problème est particulièrement pertinent lorsque vous utilisez externalTrafficPolicy: Local.
Les paramètres de la règle de trafic externe entraînent une répartition inégale
Le paramètre externalTrafficPolicy de votre service a un impact sur la façon dont le trafic est acheminé.
- Cluster : permet à l'équilibreur de charge de répartir le trafic sur n'importe quel nœud dans
le cluster. Utilisez le paramètre
Clusterpour obtenir la répartition la plus uniforme sur tous les nœuds et pods disponibles. - Local : achemine le trafic uniquement vers les pods s'exécutant sur le même nœud que celui qui a reçu le trafic. Cela peut entraîner une répartition inégale si vous ne répartissez pas les pods de manière uniforme entre les nœuds.
L'affinité de nœud entraîne une répartition inégale
L'utilisation de l'affinité de nœud pour limiter les pods à un sous-ensemble de nœuds peut entraîner une surcharge de ces nœuds, en particulier si la charge de travail n'est pas bien équilibrée entre eux.
Assurez-vous que vos pods ne sont pas épinglés à des nœuds spécifiques.