Ce document explique comment résoudre les problèmes de 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 "hotspots", 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 sont 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 les connexions réseau surutilisées.
- Épuisement des ressources : certains pods ou nœuds affichent une utilisation du processeur ou de la mémoire nettement plus élevée que le 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 sains 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 les autres, ce qui se produit souvent lorsque vous utilisez
externalTrafficPolicy: Localavec un placement de pods inégal. - Sessions client persistantes : toutes les requêtes d'un même client à fort volume 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 modèles de trafic à l'aide des métriques suivantes :
- Pour la couche 7 (Ingress/passerelle) : représentez graphiquement
loadbalancing.googleapis.com/backend/request_countet regroupez les données 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, l'é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 distribution inégale
Le problème suivant se produit lorsque les équilibreurs de charge pour lesquels l'affinité de session est activée acheminent systématiquement les requêtes d'un 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 entraîne un hotspot où il reçoit une charge nettement plus importante que les autres, tandis que les 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 permet une véritable affinité de session basée sur les adresses IP 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 divers paramètres réseau, tels qu'un 4-tuple (adresse IP client, adresse IP de destination, port de destination, protocole) ou un 5-tuple (y compris le port source). Bien que ce hachage puisse fournir une certaine "affinité" de connexion en acheminant de manière cohérente les connexions avec des valeurs de tuple identiques vers le même backend, il ne garantit pas que toutes les connexions d'une adresse IP client spécifique iront toujours vers le même pod si d'autres éléments de tuple changent.
Pour en savoir plus, consultez Affinité de session.
Pour GKE Gateway, la CRD GCPTrafficDistributionPolicy configure l'affinité de session. Pour en savoir plus, consultez Configurer des ressources Gateway à 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 des connexions à 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 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 regroupement de connexions entraîne une distribution 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 ont 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, ce qui crée des points chauds où ces pods sont surchargés tandis que d'autres restent sous-utilisés.
Les équilibreurs de charge mettent en œuvre le regroupement 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 regroupement 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 distribution inégale causée par le regroupement de connexions, implémentez des stratégies au niveau de l'application ou du client :
Configurez 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 distribuer les nouvelles tentatives de connexion entre les pods de backend disponibles, ce qui améliore la distribution globale du trafic.
Fermez et rouvrez régulièrement 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 régulièrement les connexions. Bien que cela entraîne un léger surcoût de rétablissement de la connexion, cela offre à l'équilibreur de charge de nouvelles opportunités de distribuer les tentatives de connexion ultérieures à différents pods de backend moins utilisés. Cette approche est particulièrement efficace pour les services où l'arrêt et le rétablissement de la connexion ne sont pas trop perturbateurs.
Mettre en œuvre 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 permettre aux connexions existantes de se terminer ou de se drainer. Cela permet au trafic de basculer plus facilement vers d'autres pods et d'éviter qu'il ne se concentre sur les pods en cours d'arrêt.
En gérant activement le comportement des connexions, 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 distribution 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 distribution est inégale.
Pour résoudre les déséquilibres causés par le hachage, tenez compte des points suivants :
Utilisez 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 même client sur plusieurs pods de backend.
Ajustez le comportement du client : configurez les clients pour qu'ils utilisent plusieurs connexions ou un pool de ports sources plus important.
La 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 sur les nœuds et que l'équilibreur de charge n'utilise pas l'équilibrage de charge natif en conteneurs. Les nœuds comportant plus de pods reçoivent plus de trafic, ce qui peut entraîner une surcharge de certains nœuds et une sous-utilisation d'autres.
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 distribution inégale
Le paramètre externalTrafficPolicy de votre service a un impact sur le routage du trafic.
- Cluster : permet à l'équilibreur de charge de répartir le trafic vers n'importe quel nœud du cluster. Utilisez le paramètre
Clusterpour obtenir la répartition la plus uniforme possible entre 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œuds entraîne une distribution 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.