Home >> Blog >> Comment choisir le meilleur Service Mesh pour simplifier vos microservices ?

Comment choisir le meilleur Service Mesh pour simplifier vos microservices ?

11 septembre 2023

By Pascal LIBENZI.

Il est fréquent d’entendre le terme service Mesh (ou maillage de services en français) avec l’émergence de l’orchestration de conteneurs, surtout avec une architecture microservices.

Pour rappel, le but d’un service Mesh, comme évoqué dans notre article précédent sur les Cloud Native Applications, est d’enlever le maximum de complexité technique à vos micro-services, déléguer le plus possible de fonctionnalités techniques au service Mesh, et éviter des éccueils qui seraient dû à de multiples implémentations de la même fonctionnalité standard dans tous les microservices.

Ces discussions mènent à la question de quel service Mesh est le meilleur et pourquoi nous en sélectionnerions un plutôt qu’un autre. Afin de rendre ces discussions plus claires et de vous aider dans ce choix, il faut comprendre et mettre en place une liste de ce qu’on attend d’un service Mesh.

Effectivement choisir son service Mesh peut parfois s’avérer assez compliqué, tant tous les concurrents de ce milieu proposent tous des fonctionnalités qui paraissent très intéressantes lorsqu’on opère des clusters Kubernetes sur notre infrastructure.

Et c’est pourtant une étape cruciale dans la construction de votre plateforme, et nous vous conseillons donc de prendre le temps d’analyser les solutions qui s’offrent à vous, faire une analyse assez poussée avant d’arrêter votre choix à une solution plutôt qu’une autre.

Le but de cet article est donc de servir de guide pour un tel choix. Nous décrivons ici ce qu’on peut attendre d’un service Mesh, afin de pouvoir comparer les produits du marché.

Définition du terme Service Mesh

Un service Mesh est une couche d’infrastructure dédiée à la gestion de la communication entre les microservices au sein d’une architecture distribuée. Il fonctionne à un niveau assez bas de l’infrastructure et peut intervenir au niveau des couches 4 et/ou 7 du réseau de manière transparente (L4=couche de transport TCP, L7=couche applicative HTTP).

Le service Mesh offre des fonctionnalités telles que la sécurité des communications, la gestion du trafic, l’observabilité, la découverte de services et la résilience aux pannes.

Nous reviendrons sur les points essentiels à comparer après avoir passé en revue l’architecture d’un service Mesh.

Bien qu’on puisse envisager l’utilisation de service Mesh sur différentes infrastructures, nous nous concentrerons dans cet article sur une utilisation au sein de clusters Kubernetes car il s’agit du cas d’utilisation le plus fréquent.

De quoi est constitué un service Mesh ?

Comme évoqué dans la définition du service Mesh, l’architecture d’un service Mesh peut différer d’une implémentation à une autre, et nous allons voir ici les architectures sur lesquelles se basent les services Mesh.

Architecture Data Plane (architecture décentralisée)

Avec cette architecture, chaque conteneur est accompagné d’un sidecar proxy, qui est déployé en tant que conteneur aux côtés du microservice dans le pod. Le proxy est alors responsable de la gestion du trafic réseau entre les microservices.
Lorsqu’un microservice A veut joindre un microservice B, le trafic passe par le proxy qui intercepte la demande, et prend alors le relai sur ce qui doit être fait au niveau réseau (routage, chiffrement, …). Il transmet ensuite la requête au sidecar proxy du microservice B, qui va lui aussi effectuer les opérations nécessaires, par exemple déchiffrer le message, et transmettre par la suite la requête au microservice B.

Cette architecture data plane permet d’avoir une gestion fine du trafic et des fonctionnalités avancées au niveau de chaque proxy sidecar. Chaque proxy sidecar peut collecter des métriques, effectuer des contrôles de sécurité, etc. L’ensemble des proxies sidecars constitue le "data plane" qui assure la communication entre les microservices.

L’inconvénient de ce type d’architecture (qui n’est plus vraiment utilisée aujourd’hui) est que la gestion de la configuration se fait au sein de chaque sidecar, et par conséquent il est assez difficile de maintenir une configuration cohérente au travers de tout le cluster.

Architecture data plane

Architecture Control Plane (architecture centralisée)

Avec cette architecture, le control plane est responsable de la configuration et de la coordination des proxies sidecars proxies déployés avec les microservices.
Le control plane est constitué d’un ou plusieurs composants qui travaillent de concert pour gérer les politiques réseaux et la configuration des sidecar proxies. Il centralise les informations sur les microservices, et les transmets aux proxies afin que ceux-ci puissent appliquer les règles définies au niveau du service Mesh.

Cette architecture permet une gestion centralisée et cohérente des politiques de communication entre les microservices. Elle facilite la mise en place de politiques réseau dans tout le cluster.

Ces deux architectures ne sont pas mutuellement exclusives, bien au contraire. L’architecture data plane permet de contrôler le trafic entre les microservices, tandis que l’architecture Control Plane offre une gestion centralisée des politiques et des configurations pour les proxies sidecars. L’architecture Control Plane s’appuie sur l’architecture Data Plane en ajoutant une couche de centralisation de la configuration, afin de rendre la cohérence des fonctionnalités offertes par les sidecars plus aisée.

La plupart des services Mesh ont une approche Control Plane + Data Plane (Istio va par exemple fournir les composants Pilot, Mixer, Citadel, et Galley au niveau du control plane), qui peut être décrite comme suit:

Architecture Control Plane

Dans le cas d’Istio ceci se présente ainsi:
Architecture Istio

Architecture no-sidecar

Avec l’avènement du service Mesh dans les clusters Kubernetes, l’utilisation des sidecar proxies a fini par poser question. Si le workload est seulement très légèrement impacté (tant en terme de performance que d’utilisation de ressources), il n’en reste pas moins qu’avec parfois plusieurs milliers de pods dans un cluster Kubernetes, le coût d’un proxy, si léger puisse-t-il être, finit par ne plus être négligeable en terme de coût.

Qui plus est, afin de modifier une règle de routage réseau par exemple, le sidecar proxy doit être modifié et donc le pod doit être redémarré, ceci quelle que soit la modification qui est faite du côté d’une fonctionnalité du service Mesh. Bien que ce ne soit pas dramatique, imaginons un changement qui impacte tous les pods d’un cluster, il faut alors que tous les pods soient redémarrés afin que la configuration réseau soit prise en compte.

Il vient alors l’idée de pouvoir déléguer ces fonctionnalités un cran plus bas, par exemple en instrumentalisant le noyau Linux via eBPF pour Cillium, ou encore en utilisant des tunnels réseaux transparents pour le microservice mais qui passeront donc par le control plane du service Mesh.

Une autre difficulté induite par les proxies est le fait que quelle que soit la fonctionnalité que vous voulez utiliser le sidecar proxy embarque tout ce qui peut être nécessaire au niveau du service Mesh. Autrement dit si je ne veux qu’utiliser la fonctionnalité de chiffrement réseau, mon proxy contiendra tout de même toutes les autres dépendances nécessaires au routage, à l’observabilité (export de métriques), et bien d’autres fonctionnalités que je ne veux pas forcément adopter dans l’immédiat, augmentant de fait la surface d’attaque de mon pod inutilement (même si nous sommes suffisamment confiant dans notre implémentation de service Mesh choisie, utiliser des briques inutiles augmentera le nombre de mise à jour de sécurité nécessaire au fil du temps).

Le nouveau modèle sans sidecar, quelle que soit son implémentation, vise les buts suivants:

  • Séparation des couches L4 et L7
  • Permet d’adopter uniquement les capacités nécessaires
  • Supprime le data plane des pods
  • Permet d’utiliser plus en profondeur les fonctionnalités offertes par le CNI sous-jacent
  • Réduit la surface d’attaque du data plane
  • Améliore les performances (attention, ceci est induit par la séparation L4/L7, ce n’est tout de même pas un remède miracle, si vous avez besoin d’une fonctionnalité L7 alors le gain en performance est mitigé)

Dans le cas de l’implémentation Ambient d’Istio, cela s’implémente par:

  • un DaemonSet (le Ztunnel) – donc déployé sur chaque noeud – qui s’occupe de la couche L4 (mTLS, telemetry, authentication, L4 authorizations)
  • des "Waypoint" proxies qui s’occupent de la partie L7 (VirtualService routing, L7 telemetry, L7 authorizations policies).

Fonctions d’un service Mesh

On reprendra les différentes fonctionnalités vues dans notre article sur ce qu’est une Cloud Native Application, où nous avions déjà évoqué les services Mesh pour nous aider dans une architecture microservices :

Chiffrement des communications inter-services

Dans une démarche d’architecture zero-trust, le chiffrement des communications inter-services est une fonctionnalité fondamentale d’un service Mesh. Il est essentiel que le chiffrement mTLS (mutual Transport Layer Security) entre les pods soit facile à configurer et transparent dans son fonctionnement. Cela signifie que la mise en place du chiffrement des communications devrait être simplifiée, sans nécessiter des configurations complexes. De plus, il est important d’avoir la possibilité de rendre le chiffrement facultatif pour les applications qui ne supportent pas encore le TLS. Cela permet de gérer des cas spécifiques, tels que les migrations d’applications, où le chiffrement peut ne pas être immédiatement possible. Si un mode permissif du mTLS est disponible, il devrait être utilisé uniquement de manière temporaire et limitée aux phases de migration.

Polices de sécurité réseau

Les règles de routage dans un service Mesh doivent permettre la mise en place de politiques de sécurité avancées entre les différents composants Kubernetes. Il est essentiel d’avoir une granularité fine dans la définition de ces politiques de sécurité ("least privilege principle"), afin de contrôler précisément les communications entre les services. Par exemple, il peut être nécessaire de limiter les communications entre certains services spécifiques ou de définir des politiques de sécurité au niveau du namespace. En permettant une configuration générique, le service Mesh offre une flexibilité supplémentaire pour appliquer les politiques de sécurité de manière cohérente et évolutive.

Observabilité du réseau

La capacité d’observer et de comprendre les communications entre les services est cruciale pour le bon fonctionnement d’un système basé sur un service Mesh. Il est essentiel de pouvoir identifier facilement les flux de communication entre les différents services, ainsi que de détecter rapidement les éventuelles erreurs ou dysfonctionnements. La visualisation graphique en temps réel des communications est un atout précieux qui facilite l’exploitation et le dépannage du système. Elle permet de visualiser de manière intuitive les flux de données, d’identifier les goulots d’étranglement et de surveiller les performances globales du réseau. Par exemple Kiali, qui est intégré facilement avec Istio, permet cette visualisation. Hubble pour Cilium permet aussi cette visualisation facilitée des communications.

Authentification

L’ajout d’une couche d’authentification entre les microservices renforce la sécurité globale du système. Cela permet de garantir que seuls les services autorisés peuvent communiquer entre eux, en s’assurant de l’identité et de la légitimité des parties impliquées. L’authentification devient particulièrement importante lorsque certains composants ne supportent pas les mécanismes d’authentification récents. Un service Mesh offre la possibilité d’ajouter facilement cette couche d’authentification supplémentaire, renforçant ainsi la sécurité globale de l’architecture applicative.

Modes de déploiement

Les services Mesh offrent des fonctionnalités avancées de déploiement, notamment les déploiements "canari" et "Blue-Green". Ces modes de déploiement permettent de mettre en place des stratégies plus sophistiquées que le déploiement Rollout de base de Kubernetes. Le déploiement "canari" consiste à déployer une nouvelle version d’une application sur une partie du trafic, tandis que le déploiement "Blue-Green" consiste à basculer tout le trafic vers une nouvelle version de l’application avant de retirer l’ancienne version. Ces modes de déploiement offrent une meilleure gestion des mises à jour et des déploiements en minimisant les interruptions de service et les risques liés aux mises à jour logicielles. A noter qu’il existe d’autres types de stratégie de déploiement que peuvent gérer les services Mesh: Recreate, Rolling, A/B testing, Blue/Green Mirroring (traffic shadowing), …

Maturité et communauté associée au service Mesh

Il est essentiel de choisir une solution de service Mesh qui a fait ses preuves et est utilisée en production par de nombreux acteurs. Une solution mature offre généralement une stabilité et une fiabilité accrues, ainsi qu’une communauté active prête à aider en cas de difficultés. En s’appuyant sur une communauté établie, vous pouvez bénéficier de conseils, de bonnes pratiques et de résolutions de problèmes éprouvées.

Possibilité de fonctionnement sans sidecar container

Lorsque vous avez un grand nombre de workloads ou de microservices, l’ajout de sidecar proxies pour chaque service peut entraîner une surcharge en termes de coûts financiers et d’impact environnemental. La possibilité de fonctionner sans sidecar containers offre donc un avantage significatif, en réduisant la complexité et les ressources nécessaires, tout en optimisant les performances et l’efficacité.

Ingress controller / gateway proposée

L’intégration d’une fonctionnalité d’ingress controller ou de gateway au sein du service Mesh présente des avantages pratiques. Cela élimine la nécessité d’ajouter un composant supplémentaire pour gérer les entrées dans le cluster, tout en offrant une meilleure observabilité. En ayant une vue centralisée des accès provenant de l’extérieur du cluster, il est plus facile de surveiller et de tracer les communications, ce qui permet une meilleure gestion de la sécurité et de la visibilité globale.

Complexité d’installation

L’installation d’un service Mesh ne devrait pas être une tâche ardue, surtout pour les fonctionnalités de base telles que le chiffrement des communications. La solution choisie doit offrir une expérience d’installation simplifiée, avec des processus clairs et bien documentés. Il est préférable que l’installation et la configuration ne prennent pas beaucoup de temps, afin de minimiser les retards et de permettre aux équipes de passer rapidement à d’autres tâches critiques.

Complexité d’utilisation

Un service Mesh doit être facile à opérer, sans constituer un obstacle à votre time-to-market. Il est important que l’équipe chargée de l’exploitation puisse comprendre facilement ce qui se passe dans le cluster et puisse effectuer des tâches de gestion, de surveillance et de dépannage sans trop de difficultés. Une interface utilisateur conviviale, des outils de gestion intuitifs et une documentation claire contribuent à faciliter l’utilisation du service Mesh.

Possibilité d’implémentation multi-clusters

Si vous utilisez plusieurs clusters et que vous devez établir des communications sécurisées entre eux, la possibilité de mettre en place un service Mesh multi-cluster (Cluster Mesh) est une caractéristique essentielle. Cela permet d’assurer la cohérence et la sécurité des communications à travers les différents clusters, en éliminant la nécessité de mettre en place des solutions spécifiques pour chaque cluster. Une implémentation multi-clusters simplifie la gestion globale du réseau et garantit une connectivité fiable et sécurisée entre les environnements.

Complétude et clarté de la documentation

Une documentation complète et claire est un facteur déterminant lors du choix d’un service Mesh. Une bonne documentation doit fournir des exemples concrets, des guides d’installation détaillés et des démonstrations pratiques. Une documentation de qualité témoigne de la maturité de la solution et facilite l’adoption en aidant les utilisateurs à comprendre rapidement les concepts clés, les fonctionnalités et les meilleures pratiques. En ayant une documentation précise, il est plus facile de résoudre les problèmes, de configurer et de tirer le meilleur parti du service Mesh choisi.

Une comparaison fréquemment mise à jour de différents services Mesh, qui ne rentre pas dans les détails de la comparaison, est disponible sur servicemesh.es

Notons que dans notre série où nous rentrerons plus en détails sur les services Mesh, leur installation et leurs fonctionnalités, nous ne passerons pas tous les services Mesh en revue, mais seulement les plus matures: Istio, Cilium, LinkerD et Kuma.

Conclusion

En conclusion, l’architecture microservices présente de nombreux défis en termes d’exploitabilité et de sécurisation des workloads. Les services Mesh sont des outils qui facilitent la mise en place d’architectures distribuées au sein de notre infrastructure tout en respectant les principes DRY (Don’t Repeat Yourself) et KISS (Keep It Simple, Stupid).

Pour choisir la bonne implémentation adaptée à vos cas d’utilisation, il est essentiel de définir vos priorités parmi les fonctionnalités proposées par les différents services Mesh et d’évaluer vos besoins spécifiques. L’exploitabilité et la facilité d’utilisation doivent être des critères clés dans votre choix, car ces outils sont conçus pour simplifier la mise en œuvre de votre plateforme, et atténuer les difficultés engendrées par l’architecture microservices.

Il est important de noter que cet article a abordé les concepts généraux des services Mesh et a mentionné quelques solutions populaires telles que Istio, Cilium, LinkerD et Kuma. Dans notre série approfondie sur les services Mesh, nous explorerons en détail ces solutions matures.

En fin de compte, en comprenant vos exigences et en prenant le temps d’analyser les différentes options, vous serez en mesure de choisir le service Mesh qui correspond le mieux à vos besoins et de créer une architecture microservices robuste, sécurisée et facile à gérer.

Laisser un commentaire

  Edit this page