Bonnes pratiques de scaling pour Cloud Service Mesh sur GKE
Ce guide décrit les bonnes pratiques pour résoudre les problèmes de scaling des architectures Cloud Service Mesh gérées sur Google Kubernetes Engine. L'objectif principal de ces recommandations est d'assurer des performances, une fiabilité et une utilisation des ressources optimales pour vos applications de microservices à mesure qu'elles se développent.
Pour comprendre les limites d'évolutivité, consultez Limites d'évolutivité de Cloud Service Mesh.
L'évolutivité de Cloud Service Mesh sur GKE dépend du fonctionnement efficace de ses deux principaux composants : le plan de données et le plan de contrôle. Ce document se concentre principalement sur la mise à l'échelle du plan de données.
Identifier les problèmes de scaling du plan de contrôle par rapport à ceux du plan de données
Dans Cloud Service Mesh, des problèmes de scaling peuvent se produire dans le plan de contrôle ou le plan de données. Voici comment identifier le type de problème de mise à l'échelle que vous rencontrez :
Symptômes des problèmes de scaling du plan de contrôle
Détection de services lente : la détection et la disponibilité des nouveaux services ou points de terminaison prennent beaucoup de temps.
Délais de configuration : la propagation des modifications apportées aux règles de gestion du trafic ou aux règles de sécurité prend beaucoup de temps.
Latence accrue dans les opérations du plan de contrôle : les opérations telles que la création, la mise à jour ou la suppression de ressources Cloud Service Mesh deviennent lentes ou ne répondent plus.
Erreurs liées à Traffic Director : vous pouvez observer des erreurs dans les journaux Cloud Service Mesh ou les métriques du plan de contrôle indiquant des problèmes de connectivité, d'épuisement des ressources ou de limitation de l'API.
Étendue de l'impact : les problèmes liés au plan de contrôle affectent généralement l'ensemble du maillage, ce qui entraîne une dégradation généralisée des performances.
Symptômes des problèmes de scaling du plan de données
Latence accrue dans la communication entre services : les requêtes adressées à un service du maillage présentent une latence ou des délais avant expiration plus élevés, mais l'utilisation du processeur/de la mémoire n'est pas élevée dans les conteneurs du service.
Utilisation élevée du processeur ou de la mémoire dans les proxys Envoy : une utilisation élevée du processeur ou de la mémoire peut indiquer que les proxys ont du mal à gérer la charge de trafic.
Impact localisé : les problèmes liés au plan de données affectent généralement des services ou des charges de travail spécifiques, en fonction des schémas de trafic et de l'utilisation des ressources des proxys Envoy.
Mise à l'échelle du plan de données
Pour mettre à l'échelle le plan de données, essayez les techniques suivantes :
- Configurer l'autoscaling horizontal des pods (AHP)
- Optimiser la configuration du proxy Envoy
- Surveiller et affiner
Configurer l'autoscaling horizontal des pods (AHP) pour les charges de travail
Utilisez l'autoscaling horizontal de pods (AHP) pour adapter dynamiquement les charges de travail avec des pods supplémentaires en fonction de l'utilisation des ressources. Tenez compte des points suivants lorsque vous configurez AHP :
Utilisez le paramètre
--horizontal-pod-autoscaler-sync-period
pourkube-controller-manager
afin d'ajuster la fréquence d'interrogation du contrôleur AHP. Le taux d'interrogation par défaut est de 15 secondes. Vous pouvez envisager de le définir sur une valeur inférieure si vous prévoyez des pics de trafic plus rapides. Pour savoir quand utiliser AHP avec GKE, consultez Autoscaling horizontal des pods.Le comportement de scaling par défaut peut entraîner le déploiement (ou l'arrêt) d'un grand nombre de pods à la fois, ce qui peut provoquer un pic d'utilisation des ressources. Envisagez d'utiliser des règles de scaling pour limiter la fréquence à laquelle les pods peuvent être déployés.
Utilisez EXIT_ON_ZERO_ACTIVE_CONNECTIONS pour éviter de supprimer des connexions lors de la réduction de la capacité.
Pour en savoir plus sur les AHP, consultez la section Autoscaling horizontal des pods dans la documentation Kubernetes.
Optimiser la configuration du proxy Envoy
Pour optimiser la configuration du proxy Envoy, tenez compte des recommandations suivantes :
Limites de ressources
Vous pouvez définir des demandes et des limites de ressources pour les sidecars Envoy dans vos spécifications de pods. Cela évite la contention des ressources et garantit des performances cohérentes.
Vous pouvez également configurer des limites de ressources par défaut pour tous les proxys Envoy de votre maillage à l'aide d'annotations de ressources.
Les limites de ressources optimales pour vos proxys Envoy dépendent de facteurs tels que le volume de trafic, la complexité de la charge de travail et les ressources des nœuds GKE. Surveillez et affinez en permanence votre maillage de services pour garantir des performances optimales.
Remarque importante :
- Qualité de service (QoS) : en définissant à la fois les requêtes et les limites, vous vous assurez que vos proxys Envoy disposent d'une qualité de service prévisible.
Définir le champ d'application des dépendances de service
Envisagez de réduire le graphique de dépendances de votre maillage en déclarant toutes vos dépendances via l'API Sidecar. Cela limite la taille et la complexité de la configuration envoyée à une charge de travail donnée, ce qui est essentiel pour les mailles plus grandes.
Par exemple, voici le graphique du trafic pour l'exemple d'application de boutique en ligne.
Beaucoup de ces services sont des feuilles dans le graphique et n'ont donc pas besoin d'informations de sortie pour les autres services du maillage. Vous pouvez appliquer une ressource side-car limitant le champ d'application de la configuration side-car pour ces services feuilles, comme illustré dans l'exemple suivant.
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: leafservices
namespace: default
spec:
workloadSelector:
labels:
app: cartservice
app: shippingservice
app: productcatalogservice
app: paymentservice
app: emailservice
app: currencyservice
egress:
- hosts:
- "~/*"
Pour savoir comment déployer cet exemple d'application, consultez Exemple d'application Online Boutique.
Un autre avantage de la portée sidecar est la réduction des requêtes DNS inutiles. La portée des dépendances de service permet de s'assurer qu'un side-car Envoy n'effectue des requêtes DNS que pour les services avec lesquels il communiquera réellement, au lieu de tous les clusters du maillage de services.
Pour les déploiements à grande échelle qui rencontrent des problèmes de taille de configuration importante dans leurs sidecars, il est fortement recommandé de définir le champ d'application des dépendances de service pour l'évolutivité du maillage.
Pour limiter le champ d'application de la configuration à toutes les charges de travail d'un même espace de noms, créez une ressource Sidecar dans cet espace de noms. Cela indique à tous les proxys Envoy de cet espace de noms de ne recevoir la configuration que pour les services de leur propre espace de noms.
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: sidecar
namespace: my-app
spec:
egress:
- hosts:
- "my-app/*"
Vous pouvez appliquer un comportement par défaut à chaque espace de noms de votre maillage en appliquant une seule ressource Sidecar à l'espace de noms racine, généralement istio-system.
Le Sidecar suivant limite le trafic sortant de chaque Sidecar du maillage aux services situés dans son propre espace de noms.
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: sidear
namespace: istio-system
spec:
egress:
- hosts:
- "./*"
Notez que Cloud Service Mesh impose une limite au nombre total de ressources Sidecar pouvant être créées dans un même maillage. En raison de cette contrainte, il est recommandé de créer un Sidecar au niveau de l'espace de noms.
Surveiller et affiner
Après avoir défini les limites de ressources initiales, il est essentiel de surveiller vos proxys Envoy pour vous assurer qu'ils fonctionnent de manière optimale. Utilisez les tableaux de bord GKE pour surveiller l'utilisation du processeur et de la mémoire, et ajuster les limites de ressources si nécessaire.
Pour déterminer si un proxy Envoy nécessite des limites de ressources plus élevées, surveillez sa consommation de ressources dans des conditions de trafic typiques et maximales. Voici ce que vous devez rechercher :
Utilisation élevée du processeur : si l'utilisation du processeur d'Envoy approche ou dépasse systématiquement sa limite, il peut avoir du mal à traiter les requêtes, ce qui entraîne une augmentation de la latence ou une perte de requêtes. Envisagez d'augmenter la limite de processeur.
Dans ce cas, vous pouvez être tenté d'utiliser le scaling horizontal, mais si le proxy side-car n'est pas en mesure de traiter les requêtes aussi rapidement que le conteneur d'application, l'ajustement des limites de processeur peut produire les meilleurs résultats.
Utilisation élevée de la mémoire : si l'utilisation de la mémoire d'Envoy approche ou dépasse sa limite, il peut commencer à abandonner des connexions ou rencontrer des erreurs de mémoire insuffisante (OOM, Out Of Memory). Augmentez la limite de mémoire pour éviter ces problèmes.
Journaux d'erreurs : examinez les journaux Envoy pour détecter les erreurs liées à l'épuisement des ressources, telles que les erreurs upstream connect error, disconnect or reset before headers ou too many open files. Ces erreurs peuvent indiquer que le proxy a besoin de plus de ressources. Pour d'autres erreurs liées aux problèmes de scaling, consultez la documentation sur le dépannage du scaling.
Métriques de performances : surveillez les métriques de performances clés, comme la latence des requêtes, les taux d'erreur et le débit. Si vous constatez une dégradation des performances corrélée à une utilisation élevée des ressources, il peut être nécessaire d'augmenter les limites.
En définissant et en surveillant activement les limites de ressources pour vos proxys de plan de données, vous pouvez vous assurer que votre maillage de services évolue efficacement sur GKE.
Mise à l'échelle du plan de contrôle
Cette section décrit les paramètres à ajuster pour mettre à l'échelle votre plan de contrôle.
Sélecteurs de découverte
Les sélecteurs de découverte sont un champ de MeshConfig qui vous permet de spécifier l'ensemble des espaces de noms que les plans de contrôle prennent en compte lors du calcul des mises à jour de configuration pour les side-cars.
Par défaut, Cloud Service Mesh surveille tous les espaces de noms du cluster. Cela peut constituer un goulot d'étranglement pour les grands clusters qui n'ont pas besoin de surveiller toutes les ressources.
Utilisez discoverySelectors
pour réduire la charge de calcul sur le plan de contrôle en limitant le nombre de ressources Kubernetes (telles que les services, les pods et les points de terminaison) qui sont surveillées et traitées.
Lorsque vous utilisez l'implémentation du plan de contrôle TRAFFIC_DIRECTOR
, Cloud Service Mesh ne crée que des ressources Google Cloud , telles que des services de backend et des groupes de points de terminaison réseau, pour les ressources Kubernetes dans les espaces de noms spécifiés dans discoverySelectors
.
Pour en savoir plus, consultez la section Sélecteurs de découverte dans la documentation d'Istio.
Intégrer la résilience
Vous pouvez ajuster les paramètres suivants pour renforcer la résilience de votre maillage de services :
Détection des anomalies
La détection des anomalies surveille les hôtes d'un service en amont et les supprime du pool d'équilibrage de charge lorsqu'un certain seuil d'erreur est atteint.
- Configuration clé :
outlierDetection
: paramètres contrôlant l'éviction des hôtes défaillants du pool d'équilibrage de charge.
- Avantages : permet de maintenir un ensemble d'hôtes opérationnels dans le pool d'équilibrage de charge.
Pour en savoir plus, consultez la section Détection des valeurs aberrantes dans la documentation Istio.
Tentatives
Atténuez les erreurs temporaires en renouvelant automatiquement les requêtes ayant échoué.
- Configuration clé :
attempts
: nombre de nouvelles tentatives à effectuer.perTryTimeout
: délai avant nouvelle tentative. Définissez une durée inférieure à votre délai avant expiration global. Il détermine la durée d'attente pour chaque tentative.retryBudget
: nombre maximal de nouvelles tentatives simultanées.
- Avantages : taux de réussite plus élevé pour les requêtes, impact réduit des échecs intermittents.
Facteurs à prendre en compte :
- Idempotence : assurez-vous que l'opération faisant l'objet d'une nouvelle tentative est idempotente, ce qui signifie qu'elle peut être répétée sans effets secondaires indésirables.
- Nombre maximal de tentatives : limitez le nombre de tentatives (par exemple, trois tentatives maximum) pour éviter les boucles infinies.
- Rupture de circuit : intégrez des tentatives avec des disjoncteurs pour éviter les tentatives lorsqu'un service échoue de manière répétée.
Pour en savoir plus, consultez la section Retries (Tentatives) dans la documentation d'Istio.
Délais avant expiration
Utilisez des délais avant expiration pour définir la durée maximale autorisée pour le traitement des requêtes.
- Configuration clé :
timeout
: délai avant expiration de la requête pour un service spécifique.idleTimeout
: durée pendant laquelle une connexion peut rester inactive avant d'être fermée.
- Avantages : amélioration de la réactivité du système, prévention des fuites de ressources, renforcement contre le trafic malveillant.
Facteurs à prendre en compte :
- Latence réseau : tenez compte du délai aller-retour (DAR) attendu entre les services. Prévoyez une marge pour les retards imprévus.
- Graphique des dépendances de service : pour les requêtes chaînées, assurez-vous que le délai avant expiration d'un service appelant est plus court que le délai avant expiration cumulé de ses dépendances afin d'éviter les défaillances en cascade.
- Types d'opérations : les tâches de longue durée peuvent nécessiter des délais d'attente beaucoup plus longs que les récupérations de données.
- Gestion des erreurs : les délais d'attente doivent déclencher une logique de gestion des exceptions appropriée (par exemple, nouvelle tentative, secours, disjoncteur).
Pour en savoir plus, consultez la section Délais d'expiration dans la documentation d'Istio.
Surveiller et affiner
Envisagez de commencer par les paramètres par défaut pour les délais d'attente, la détection des anomalies et les nouvelles tentatives, puis de les ajuster progressivement en fonction des exigences spécifiques de votre service et des modèles de trafic observés. Par exemple, examinez les données réelles sur le temps de réponse habituel de vos services. Ajustez ensuite les délais d'attente pour qu'ils correspondent aux caractéristiques spécifiques de chaque service ou point de terminaison.
Télémétrie
Utilisez la télémétrie pour surveiller en permanence votre maillage de services et ajuster sa configuration afin d'optimiser les performances et la fiabilité.
- Métriques : utilisez des métriques complètes, en particulier les volumes de requêtes, la latence et les taux d'erreur. Intégrez Cloud Monitoring pour la visualisation et les alertes.
- Traçage distribué : activez l'intégration du traçage distribué avec Cloud Trace pour obtenir des insights détaillés sur les flux de requêtes dans vos services.
- Journalisation : configurez la journalisation des accès pour capturer des informations détaillées sur les requêtes et les réponses.
Autres ressources à lire
- Pour en savoir plus sur Cloud Service Mesh, consultez la présentation de Cloud Service Mesh.
- Pour obtenir des conseils généraux sur l'ingénierie en fiabilité des sites (SRE) concernant la scalabilité, consultez les chapitres Gérer la surcharge et Gérer les défaillances en cascade du livre Google SRE.