Cloud et infrastructure

Trois goulets d'étranglement distincts limitent la montée en charge du plan de contrôle Kubernetes

Les clusters Kubernetes échouent à grande échelle non seulement à cause du nombre de nœuds, mais aussi en raison du renouvellement des nœuds (churn), de l'état des objets ou de l'intensité des écritures. De nouvelles coutures architecturales offrent des correc

Illustration des goulets d'étranglement de la montée en charge Kubernetes représentés par des engrenages mécaniques avec des coutures ajustables.
Illustration générée pour cet article

Traduit automatiquement depuis l'original anglais.

Les défis liés à la montée en charge de Kubernetes sont souvent mal diagnostiqués comme étant de simples limites liées au nombre de nœuds. Cependant, une analyse récente révèle trois modes de défaillance distincts : le renouvellement des nœuds (churn), l'état et la capacité des nœuds. Lorsque les clusters dépassent cinq mille nœuds ou gèrent des charges de travail intensives par agents, la mise à l'échelle horizontale standard des serveurs API peut aggraver la pression sur la mémoire plutôt que de la soulager. La compréhension de ces goulets d'étranglement spécifiques permet aux équipes d'infrastructure d'appliquer des correctifs architecturaux ciblés en utilisant des composants amont standards.

Ce qui s'est passé

De nombreuses équipes d'ingénierie partent du principe que la montée en charge du plan de contrôle Kubernetes est un problème linéaire résolu en ajoutant davantage de serveurs API. Pourtant, les clusters de production réels démontrent que cette approche échoue souvent lorsque le goulot d'étranglement sous-jacent n'est pas le volume de requêtes, mais la résidence en mémoire ou l'intensité des écritures. Par exemple, une flotte d'apprentissage automatique peut rester stable à quelques milliers de nœuds avant de passer à quinze mille, provoquant des plaintes d'etcd et l'épuisement de la mémoire des serveurs API. En revanche, une plateforme d'agents avec seulement quelques milliers de nœuds peut subir des milliers de transitions d'objets par minute, créant une tempête d'écritures qui submerge le plan de contrôle indépendamment du nombre de nœuds.

Un troisième scénario implique des clusters de plateforme comptant des centaines d'opérateurs et des dizaines de milliers d'objets statiques. Ici, le problème n'est pas l'activité mais l'état : chaque serveur API conserve une copie de tous les objets dans son cache de surveillance (watch cache). L'ajout de serveurs API dans ce contexte réplique l'intégralité du cache, augmentant l'utilisation de la mémoire sans améliorer les performances. Ces trois scénarios — limités par les nœuds, par le renouvellement (churn) et par l'état — nécessitent des solutions différentes, alors que la plupart des guides publics se concentrent exclusivement sur les nombres de nœuds jusqu'à cinq mille.

L'absence de stratégies documentées pour des clusters plus grands ou plus complexes conduit les équipes à effectuer des changements contre-productifs. Ajouter des serveurs API à un cluster limité par l'état augmente la pression sur la mémoire car chaque nouvelle instance réplique l'intégralité du cache de surveillance. La solution ne réside pas dans des forks personnalisés, mais dans la compréhension des « coutures » de l'architecture Kubernetes, où les composants peuvent être découplés et configurés indépendamment pour gérer des types de charge spécifiques.

Comment cela fonctionne

La scalabilité de Kubernetes est contrainte par quatre « coutures » architecturales, qui sont des points de substitution entre les composants. La première couture est le stockage, qui détermine quel backend héberge quels types de ressources. Toutes les données ne nécessitent pas le même niveau de durabilité ; les éléments éphémères tels que les baux de nœud (node leases) et les événements peuvent être routés loin du cluster etcd principal pour réduire la charge d'écriture. La deuxième couture est la vivacité des nœuds, qui gère la manière dont les données de battement de cœur (heartbeat) atteignent le plan de contrôle. En absorbant les renouvellements de baux dans une couche orientée vers les nœuds ou en utilisant des rafraîchissements de baux en mémoire dans etcd, les clusters peuvent réduire drastiquement le QPS d'écriture généré par des milliers de kubelets.

La troisième couture est le sharding (partitionnement), qui définit comment les objets sont divisés entre les contrôleurs et les caches. Si les couches ne s'accordent pas sur l'axe de partitionnement, les contrôleurs gaspillent des ressources en cherchant des objets hors de leur périmètre. La quatrième couture est la résidence en cache, qui contrôle ce qu'un serveur API conserve en mémoire. Un cluster limité par l'état souffre parce que chaque serveur API met en cache chaque objet. En restreignant le contenu du cache uniquement aux objets pertinents pour un shard ou un rôle spécifique, l'utilisation de la mémoire peut être considérablement réduite, bien qu'une surcharge de base pour les objets RBAC reste inévitable.

Détails clés

  • Les clusters limités par les nœuds sont contraints par les battements de cœur des kubelets, les renouvellements de baux représentant environ 70 % du QPS d'écriture à grande échelle.
  • Les clusters limités par le renouvellement (churn) font face à des taux d'écriture élevés provenant de ressources personnalisées de courte durée, telles que les sessions d'agents, indépendamment du nombre de nœuds.
  • Les clusters limités par l'état sont contraints par l'utilisation de la mémoire, car chaque serveur API réplique l'intégralité du cache de surveillance contenant des dizaines de milliers d'objets.
  • KEP-4743 définit la frontière de l'interface de stockage, permettant de router les types de ressources vers différents backends via --etcd-servers-overrides.
  • KEP-5866 introduit le filtrage par plage de hachage pour le trafic API, jetant les bases d'un sharding cohérent entre les contrôleurs et les caches.
  • Les configurations Role-Split séparent les pools de machines pour le service API, l'ordonnancement (scheduling) et etcd, permettant une montée en charge jusqu'à 20 000 nœuds.

Pourquoi c'est important

Pour les ingénieurs logiciels et les responsables d'infrastructure, reconnaître le type spécifique de limitation à l'échelle est crucial pour éviter des erreurs de configuration coûteuses. Traiter une plateforme d'agents limitée par le renouvellement comme un problème lié aux nœuds conduit à une surprovisioning des calculs tout en ignorant le goulot d'étranglement des écritures dans etcd. De même, ajouter des serveurs API à un cluster de plateforme limité par l'état augmente les coûts mémoire sans améliorer la latence. En identifiant si le cluster est limité par les battements de cœur des nœuds, le renouvellement des objets ou la résidence en état, les équipes peuvent appliquer des correctifs précis plutôt qu'une montée en charge brutale.

Ces informations mettent également en évidence l'importance d'utiliser des composants amont standards avec une configuration délibérée, plutôt que de compter sur des forks non documentés. L'échelle de recettes (« recipe ladder ») proposée offre un chemin allant des configurations classiques à haute disponibilité aux stores partitionnés et aux tranches shardées, le tout testé via l'intégration continue. Cette approche garantit que les stratégies de montée en charge restent valides à travers les versions de Kubernetes, car les échecs de configuration sont détectés tôt dans le pipeline CI plutôt qu'en production.

Ce que vous pouvez faire

  • Identifiez le goulot d'étranglement principal de votre cluster en analysant les sources du QPS d'écriture, en distinguant les baux de nœuds, le renouvellement des ressources personnalisées et l'état des objets statiques.
  • Implémentez des configurations Role-Split pour séparer le service API, l'ordonnancement et etcd sur des pools de machines dédiés pour les clusters jusqu'à 20 000 nœuds.
  • Utilisez --etcd-servers-overrides pour router les ressources éphémères comme les événements et les baux vers des backends séparés, réduisant ainsi la charge sur le cluster etcd principal.
  • Évaluez les couches orientées vers les nœuds pour absorber les renouvellements de baux et ne propager que les vraies transitions d'état, diminuant la charge d'écriture sur le plan de contrôle.
  • Contribuez des données réelles sur les taux d'écriture issus de clusters limités par le renouvellement auprès du SIG API Machinery pour aider à façonner le futur support de la configuration de stockage par CRD.
  • Examinez les branches prototypes pour KEP-5866 et les extensions de résidence en cache afin de préparer les futures fonctionnalités de sharding et d'optimisation mémoire.
  • #kubernetes
  • #scaling
  • #infrastructure
  • #devops
  • #cloud-native

Outils de la Boutique Bytechap

Continuer la lecture

Tous les articles