Gestion du trafic sur ISTIO:


1. Introduction à la gestion du trafic sur ISTIO:

1.1 Introduction à la gestion du trafic:

La gestion du trafic constitue la fonctionnalité la plus importante d’ISTIO. Cette fonctionnalité a pour but, tout d’abord, de comprendre comment circulent les requêtes dans un système Mesh, et permet aussi de contrôler le flux de ces requêtes à travers des API réseau. Mais pour cela, il faudrait connaître le principe de fonctionnement de ces API réseaux d’ISTIO et comment les configurer pour répondre aux besoins, comme par exemple, assurer un déploiement en mode canary sur un environnement de production ou bien d’autres exemples.

 

Si on est amené à installer ISTIO sur un cluster Kubernetes par exemple, ISTIO va instantanément détecter les services qui tournent sur ce cluster. Pour cela, ISTIO a besoin d’un service registry interne, cette registry va contenir  l’ensemble des services contenu dans un certain Service Mesh. Pour peupler cette registry, ISTIO a besoin de se connecter à un service discovery system.

1.2 Routage du trafic sur ISTIO:

Comme vous le savez peut-être, le terme Routage est un terme très vaste dans l’univers des Réseaux informatiques, il inclut plusieurs couches du modèle OSI constituant une pile réseau assez compliquée. Nous n’allons pas nous étaler sur toutes ces couches du modèle OSI, mais plutôt sur celle qui nous intéresse en parlant d’ISTIO, la couche 7. Cette couche 7 nommée couche application, permet le routage des paquets via des règles basées sur l’URI ou sur l’entête du paquet en question. Le proxy est ce qui caractérise le mieux cette couche.

Il est connu sur kubernetes qu’il existe un Ingress Controller qui contrôle tous les trafics de type ingress, permettant ainsi d’exposer des applications HTTP et HTTPS, tournant sur le cluster, sur internet. Sur ISTIO, Ingress Controller est substitué par des objets API réseaux: Virtual services, Gateway et Destination rule.

Le routage du trafic sur ISTIO se base sur les objets susmentionnés, qui ne sont autres que des Custom Ressources sur Kubernetes. Ils décrivent comment est fait le routage sur ISTIO et principalement entre le control plane et la data plane

  • Au niveau control plane: La configuration de chaque Virtual services, Gateway et Destination rule sera enregistrée sur l’etcd via l’API server sur Kubernetes, et repris par la suite par un composant d’ISTIO nommé Pilot. Ce composant (Pilot) va convertir la configuration des 3 CRs en une configuration Envoy qui sera automatiquement envoyée au data plane.
  • Au niveau data plan: Plusieurs Envoy proxies sont déployés sous forme de sidecars. Envoy constitue un composant phare dans la gestion du trafic sur ISTIO, étant le point central dans la communication réseau entre les différents microservices de notre Service Mesh, tout le trafic envoyé ou reçu par un microservice est proxifié à travers Envoy.

On peut donc en conclure que ISTIO nous offre bien des possibilités très avancées de gestion et de contrôle du trafic dans un Service Mesh, comme l’ajout de certaines règles sur le trafic entrant ou sortant de notre Mesh, ou bien appliquer une règle de répartition de charge sur un subset bien précis d’un certain service, ou encore rediriger un pourcentage précis d’un trafic à une nouvelle version d’un service dans le cadre d’un A/B testing. 

Et bien d’autres fonctionnalités sous forme de configurations formulées à ISTIO en utilisant les  Custom Resources de Kubernetes suivants:

  • Virtual Services
  • Destination Rule
  • Gateways
  • Services Entries
  • Sidecars

Nous allons voir dans le reste de cet article à quoi ressemblent ces Custom Resources ( ou du moins les 3 premiers ) et comment elles sont configurées.

2. Les Gateways

2.1 Principe

ISTIO Gateway offre des fonctionnalités de routage avancées du trafic ISTIO, permettent de configurer les paramètres au niveau des couches 4-6 ( couche du modèle OSI) comme les ports à exposer, les paramètres TLS etc, Cela offre une couche de routage supplémentaire à celle de la couche 7 déjà configurée par les VirtualServices de ISTIO que nous détaillerons plus tard.

ISTIO Gateway est basé sur Envoy qui joue le rôle de Load Balancer et d’un reverse proxy, pour le trafic entrant vers le Mesh et aussi pour le trafic sortant.

 

Ainsi, les Gateways d’ISTIO permettent d’exposer une destination sur le mesh à un réseau publique à travers une gateway, et cela en mappant le FQDN et qui est le nom interne de cette destination, par exemple reviews.namespace.svc.cluster.local, à une url publique  par exemple reviews.beopenit.com. Tout en précisant le port d’exposition de l’url publique et le protocole concerné, comme on pourra le voir dans un exemple.

ISTIO gateway inclue une couche sécurité qui permet d’authentifier le client et lui prouver que l’url d’exposition reviews.beopenit.com appartient bien à la gateway vers laquelle il envoie son flux. Il permet aussi de contrôler les requêtes HTTP en ajoutant une redirection HTTPS et en précisant le mode TLS désiré.

2.2 Exemple

L’exemple suivant décrit la configuration d’une Gateway name: istio-gateway qui joue le rôle d’un proxy en exposant le port number: 443 sur le host ext-host.example.com, pour le trafic entrant. ISTIO va alors configurer le proxy qui tourne sur le pod qui contient le label : app: my-gateway-controller  afin qu’il écoute sur le port 443.

Copy to Clipboard

3. Les Virtual services 

3.1 Principe:

Les Virtual Services décrivent comment les requêtes sont acheminées vers un certain service dans un Service Mesh distinct. Chaque Virtual Service consiste en une collection de règles de routage sur chaque requête permettant de matcher chaque requête à une destination précise définie dans la registry interne du Service Mesh.

Les Virtual Services peuvent aussi router des requêtes vers différentes versions d’un même service. Ces requêtes sont ainsi routées en se basant sur les champs de l’entête ou encore en se basant sur le chemin HTTP précisé, ou même en fonction du point de répartition attribué à certaines versions d’un certain service.

3.2 Pourquoi utiliser les virtualservices:

Le cas le plus typique d’utilisation des Virtual Services consiste à envoyer des requêtes vers différentes versions d’un service, aussi nommée subset. Cela est abstrait pour le client qui envoie ses requêtes en destination d’un certain service, Envoy intercepte alors le trafic en question et le route vers les différents subsets, en dépit des règles configurées sur les Virtual Services. On peut alors décider, par exemple, faire du Round-Robin entre les différentes version d’un service. Ou bien encore, de router 20% du trafic vers une version 2, puis rediriger le reste vers une autre version 1, puis basculer la charge graduellement vers la dernière version ( version 2 ) permettant ainsi d’effectuer un canary rollout. Et bien d’autres fonctionnalités.

3.3 Exemples de virtualservice:

On a dit ultérieurement que les Virtual Services forment un ensemble de règle de routage des requêtes vers une certaines destination. Ces règles de routage sont appliquées à des requêtes envoyés vers des Hosts bien spécifiques à travers une certaine Gateways. Voyons un peu dans les exemples suivant comment sont formulées ces règles:

  • Routage basé sur le prefix de l’uri

Dans l’exemple suivant, le trafic entrant via la gateway istio-gateway, sera routé en se basant sur les règles du VirtualService suivantes et qui match le trafic en se basant sur les URIs des requêtes, et redirige par la suite les requêtes vers l’un des deux services correspondant (review ou rating).

Si le client utilise un chemin qui n’est pas défini dans les règles du VirtualService comme /test par exemple, Envoy retournera une erreur 404 puisqu’il ne trouvera aucun uri qui matche le chemin demandé.

  

Copy to Clipboard

 

  • Routage basé sur un match condition sur l’entête de la requête

Dans l’exemple suivant, le trafic entrant via la gateway istio-gateway, sera routé en se basant sur la règle du VirtualService suivante et qui match le trafic en se basant sur la présence d’un certain utilisateur défini comme exact: jason dans le champ end-user dans l’entête de la requête HTTP.

Copy to Clipboard

 

  • Répartition de trafic entre differents subsets:

Dans l’exemple suivant, le trafic entrant via la gateway istio-gateway, sera réparti entre deux versions bien distinctes définies par subset: v1 et subset: v2 du même service host: reviews. Cette répartition se fera en fonction de la proportion de trafic allouée à chaque subset, et renseignée par la valeur weight: 85

Cette méthode est efficace pour faire un test sur la nouvelle version v2 en lui redirigeant 15% du trafic destiné à la destination reviews, tout en prévoyant un retour en arrière rapide si la nouvelle version est défaillante ou si le déploiement de cette nouvelle version n’est pas un succès.

Copy to Clipboard

 

    • Hosts

Il s’agit de la liste des services destinations vers lesquelles les requêtes seront acheminées lorsqu’une règle de routage est matchée.

Note: Un service peut être désigné comme un simple nom de service comme reviews, alors que sur ISTIO, le service sera traduit avec son propre nom DNS sur le cluster, c’est à dire : reviews.<namespace>.svc.cluster.local.

 

Copy to Clipboard

 

    • Routing rules

Définies sur le champ http de la spec, ils décrivent les match conditions qui impliquent les décisions de routage à prendre vers la destination indiquée sur le champ hosts (de la destination, que nous allons voir en détails par la suite).

  • Match condition:

Dans l’exemple qui a été choisi, la règle de routage contient une condition définie sur le champ match, qui filtre seulement sur les requêtes en provenance de l’utilisateur défini sous le nom de jason, comme il est décrit sur la spec avec le bout de code suivant:

 

Copy to Clipboard

 

  • Destination:

Une fois la condition (ci-dessus) matchée, les requêtes seront routées vers la destination définie sur le champ route. Qui n’est autre qu’un service Kubernetes dans notre cas :

 

Copy to Clipboard

 

Note: Vous remarquerez que sur le host de notre destination nous avons utilisée juste un nom de court pour notre service (reviews) qui renvoie au vrai FQDN du même service, cela est dû au fait que notre service en question et le virtualservice correspondant, font partie du même namespace Kubernetes.

Le champ destination permet aussi de  définir quel subset de notre service kubernetes on veut requêter. Ces subset définissent des règles supplémentaires à notre virtualservice et qui sont  configurées par les Destination Rule, que nous verrons par la suite.

4. Destination rule:

Dans les points précédents on a vu comment est fait le routage du trafic client entrant, vers un service bien définit sur la service registry du Mesh. On a aussi mentionné qu’un service en destination peut avoir plusieurs Subsets et qu’on pouvait, avec des règles de routage, définir quel trafic rediriger vers un subset et à quel pourcentage.

Un subset étant simplement la destination finale de notre requête et qui permet de diviser un service en plusieurs subsets définis par des Labels. Il s’agit d’un changement mineur sur le service entre une version est une autre. On peut par exemple utuliser les subsets pour définir plusieurs versions différentes d’un service et utiliser un VirtualService pour contrôler l’acheminement du trafic entre ces différentes versions.

4.1 Principe:

Après le routage du trafic, les Destination Rules vont définir les politiques à appliquer au trafic destiné à un certain service.

ISTIO utilise par défaut une politique de répartition de charge de type Round-Robin, dans laquelle chaque instance contenue dans le groupe d’instance, reçoit à son tour une requête. Mais cette politique peut être customisée , car ISTIO offre plus de flexibilité avec les fonctionnalités suivantes, spécifiées dans la Destination Rule  pour un subset spécifique ou pour un service en particulier :

  • Random: Les requêtes sont réparties entre chaque instance du groupe instances de façon aléatoire
  • Weighted: Les requêtes sont réparties en dépit du pourcentage de trafic configuré entre chaque instance du groupe instances.
  • Least requests: Les requêtes sont réparties aux instances définies avec avec le moins de requêtes possible.

4.2 Exemple:

Dans l’exemple suivant, différents subset ont été définis pour le le service host: reviews. Chaque subset est défini par un label, qui n’est autre qu’une paire clef/valeur utilisée pour définir la version d’un service précis.

Nous avons aussi  dans cet exemple une Destination Rule qui applique une politique de trafic par défaut loadBalancer: simple: RANDOM pour tous les subsets, et une autre politique de trafic loadBalancer: simple: ROUND_ROBIN  pour un subset spécifique version: v2.

Copy to Clipboard

 

En conclusion pour les deux derniers points, on pourrait présenter la relation entre Virtual service, Gateway et Service avec l’image suivante :

Photo credit: https://www.salzberginsurance.com/img/~www.salzberginsurance.com/1370143_66842063.jpg


 

Rédigé le 19/02/ 2020, par : Ali Hassan AYOUJIL
Rédigé le 19/02/ 2020, par : Ali Hassan AYOUJILIngénieur Cloud Devops chez BEOpenIT