Istio Circuit Breaker : désactivation des conteneurs défectueux

Les vacances sont terminées et nous sommes de retour avec notre deuxième article de la série Istio Service Mesh.

Istio Circuit Breaker : désactivation des conteneurs défectueux

Le sujet d’aujourd’hui est le disjoncteur, qui traduit en génie électrique russe signifie « disjoncteur », dans le langage courant – « disjoncteur ». Seulement dans Istio, cette machine ne déconnecte pas un circuit en court-circuit ou surchargé, mais des conteneurs défectueux.

Comment cela devrait fonctionner idéalement

Lorsque les microservices sont gérés par Kubernetes, par exemple au sein de la plateforme OpenShift, ils évoluent automatiquement en fonction de la charge. Étant donné que les microservices s'exécutent dans des pods, il peut y avoir plusieurs instances d'un microservice conteneurisé sur un point de terminaison, et Kubernetes acheminera les requêtes et équilibrera la charge entre elles. Et – idéalement – ​​tout cela devrait fonctionner parfaitement.

Nous rappelons que les microservices sont petits et éphémères. L’éphémère, qui signifie ici la facilité d’apparaître et de disparaître, est souvent sous-estimée. La naissance et la mort d'une autre instance d'un microservice dans un pod sont des choses tout à fait attendues, OpenShift et Kubernetes gèrent cela bien, et tout fonctionne très bien - mais encore une fois en théorie.

Comment ça marche vraiment

Imaginez maintenant qu'une instance spécifique d'un microservice, c'est-à-dire un conteneur, soit devenue inutilisable : soit elle ne répond pas (erreur 503), soit, ce qui est plus désagréable, elle répond, mais trop lentement. En d’autres termes, il devient problématique ou ne répond pas aux demandes, mais il n’est pas automatiquement supprimé du pool. Que faut-il faire dans ce cas ? Réessayer ? Dois-je le supprimer du schéma de routage ? Et que signifie « trop lent » : combien y en a-t-il en nombre et qui les détermine ? Peut-être juste faire une pause et réessayer plus tard ? Si oui, combien de temps plus tard ?

Qu'est-ce que l'éjection de pool dans Istio

Et ici, Istio vient à la rescousse avec ses machines de protection par disjoncteur, qui suppriment temporairement les conteneurs défectueux du pool de ressources de routage et d'équilibrage de charge, en mettant en œuvre la procédure d'éjection du pool.

À l'aide d'une stratégie de détection des valeurs aberrantes, Istio détecte les modules de courbe qui ne sont pas alignés et les supprime du pool de ressources pendant une durée spécifiée, appelée fenêtre de veille.

Pour montrer comment cela fonctionne dans Kubernetes sur la plateforme OpenShift, commençons par une capture d'écran de microservices fonctionnant normalement à partir de l'exemple du référentiel Démos des développeurs Red Hat. Ici, nous avons deux pods, v1 et v2, chacun exécutant un conteneur. Lorsque les règles de routage Istio ne sont pas utilisées, Kubernetes utilise par défaut un routage circulaire équilibré :

Istio Circuit Breaker : désactivation des conteneurs défectueux

Se préparer à un crash

Avant d'effectuer Pool Ejection, vous devez créer une règle de routage Istio. Disons que nous souhaitons répartir les requêtes entre les pods dans un rapport 50/50. De plus, nous augmenterons le nombre de conteneurs v2 de un à deux, comme ceci :

oc scale deployment recommendation-v2 --replicas=2 -n tutorial

Nous définissons maintenant une règle de routage afin que le trafic soit réparti entre les pods dans un rapport 50/50.

Istio Circuit Breaker : désactivation des conteneurs défectueux
Voici à quoi ressemble le résultat de cette règle :

Istio Circuit Breaker : désactivation des conteneurs défectueux
On peut trouver à redire au fait que cet écran n'est pas 50/50, mais 14:9, mais avec le temps, la situation s'améliorera.

Faire un bug

Désactivons maintenant l'un des deux conteneurs v2 afin d'avoir un conteneur v1 sain, un conteneur v2 sain et un conteneur v2 défectueux :

Istio Circuit Breaker : désactivation des conteneurs défectueux

Réparer le problème

Nous avons donc un conteneur défectueux et il est temps de procéder à l'éjection de la piscine. À l'aide d'une configuration très simple, nous exclurons ce conteneur défaillant de tout schéma de routage pendant 15 secondes dans l'espoir qu'il reviendra à un état sain (soit redémarrage, soit restauration des performances). Voici à quoi ressemble cette configuration et les résultats de son travail :

Istio Circuit Breaker : désactivation des conteneurs défectueux
Istio Circuit Breaker : désactivation des conteneurs défectueux
Comme vous pouvez le constater, le conteneur v2 défaillant n'est plus utilisé pour le routage des requêtes car il a été supprimé du pool. Mais après 15 secondes, il reviendra automatiquement à la piscine. En fait, nous venons de montrer comment fonctionne Pool Ejection.

Commençons par construire l'architecture

Pool Ejection, combiné aux capacités de surveillance d'Istio, vous permet de commencer à créer un cadre de remplacement automatique des conteneurs défectueux afin de réduire, voire d'éliminer, les temps d'arrêt et les pannes.

La NASA a une devise forte - L'échec n'est pas une option, dont l'auteur est considéré comme le directeur de vol Gène Kranz. Cela peut être traduit en russe par « L’échec n’est pas une option », et le sens ici est que tout peut fonctionner si vous avez suffisamment de volonté. Cependant, dans la vraie vie, les échecs ne surviennent pas par hasard, ils sont inévitables, partout et en tout. Et comment les gérer dans le cas des microservices ? À notre avis, il vaut mieux s'appuyer non pas sur la volonté, mais sur les capacités des conteneurs, Kubernetes, Red Hat OpenShiftEt Istio.

Istio, comme nous l'écrivions plus haut, met en œuvre le concept de disjoncteurs, qui a fait ses preuves dans le monde physique. Et tout comme un disjoncteur électrique coupe une section problématique d'un circuit, le logiciel Circuit Breaker d'Istio ouvre la connexion entre un flux de requêtes et un conteneur de problèmes lorsque quelque chose ne va pas avec le point de terminaison, par exemple lorsque le serveur tombe en panne ou commence à fonctionner. ralentir.

De plus, dans le second cas, les problèmes ne font que s'aggraver, car les freins d'un conteneur non seulement provoquent une cascade de retards dans les services qui y accèdent et, par conséquent, réduisent les performances du système dans son ensemble, mais génèrent également des demandes adressées à un service déjà lent, ce qui ne fait qu'aggraver la situation .

Disjoncteur en théorie

Circuit Breaker est un proxy qui contrôle le flux de requêtes vers un point de terminaison. Lorsque ce point cesse de fonctionner ou, selon les paramètres spécifiés, commence à ralentir, le proxy rompt la connexion avec le conteneur. Le trafic est ensuite redirigé vers d’autres conteneurs, simplement en raison de l’équilibrage de charge. La connexion reste ouverte pendant une fenêtre de veille donnée, disons deux minutes, puis est considérée comme semi-ouverte. Une tentative d'envoi de la requête suivante détermine l'état ultérieur de la connexion. Si tout va bien avec le service, la connexion revient en état de fonctionnement et se ferme à nouveau. Si le problème persiste avec le service, la connexion est déconnectée et la fenêtre de veille est réactivée. Voici à quoi ressemble un diagramme d'état simplifié d'un disjoncteur :

Istio Circuit Breaker : désactivation des conteneurs défectueux
Il est important de noter ici que tout cela se produit au niveau, pour ainsi dire, de l'architecture du système. Ainsi, à un moment donné, vous devrez apprendre à vos applications à fonctionner avec Circuit Breaker, par exemple en fournissant une valeur par défaut en réponse ou, si possible, en ignorant l'existence du service. Un modèle de cloison est utilisé pour cela, mais cela dépasse le cadre de cet article.

Disjoncteur en pratique

Par exemple, nous exécuterons deux versions de notre microservice de recommandation sur OpenShift. La version 1 fonctionnera correctement, mais dans la v2, nous intégrerons un délai pour simuler les ralentissements sur le serveur. Pour visualiser les résultats, utilisez l'outil siège:

siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io

Istio Circuit Breaker : désactivation des conteneurs défectueux
Tout semble fonctionner, mais à quel prix ? À première vue, nous avons une disponibilité de 100 %, mais y regardez de plus près : la durée maximale de la transaction peut atteindre 12 secondes. Il s’agit clairement d’un goulot d’étranglement qui doit être élargi.

Pour ce faire, nous utiliserons Istio pour éliminer les appels aux conteneurs lents. Voici à quoi ressemble la configuration correspondante en utilisant Circuit Breaker :

Istio Circuit Breaker : désactivation des conteneurs défectueux
La dernière ligne avec le paramètre httpMaxRequestsPerConnection signale que la connexion avec doit être déconnectée lorsque l'on tente de créer une autre - une deuxième - connexion en plus de celle existante. Étant donné que notre conteneur simule un service lent, de telles situations se produiront périodiquement, puis Istio renverra une erreur 503, mais voici ce que Siege affichera :

Istio Circuit Breaker : désactivation des conteneurs défectueux

OK, nous avons le disjoncteur, quelle est la prochaine étape ?

Nous avons donc implémenté l'arrêt automatique sans toucher du tout au code source des services eux-mêmes. À l'aide du disjoncteur et de la procédure d'éjection de pool décrite ci-dessus, nous pouvons retirer les conteneurs de frein du pool de ressources jusqu'à ce qu'ils reviennent à la normale et vérifier leur état à une fréquence spécifiée - dans notre exemple, il s'agit de deux minutes (paramètre sleepWindow).

Notez que la capacité d'une application à répondre à une erreur 503 est toujours définie au niveau du code source. Il existe de nombreuses stratégies pour utiliser le disjoncteur, selon la situation.

Dans le prochain article : Nous parlerons du traçage et de la surveillance déjà intégrés ou facilement ajoutés à Istio, ainsi que de la manière d'introduire intentionnellement des erreurs dans le système.

Source: habr.com

Ajouter un commentaire