Ceux d’entre nous qui vivent immergés dans le monde de la technologie sont habitués à la vague continue de nouveaux termes et de nouvelles technologies, qui ne sont souvent que du bruit et du marketing. Heureusement, de temps en temps, les vagues nous livrent quelques trésors. Dans ce cas, la vague nous a laissé sur le rivage le Service Mesh.
Les architectures monolithiques sont reconnues depuis longtemps comme un problème en termes d’amélioration de la maintenabilité, de l’évolutivité et de la stabilité des applications, ainsi que de facilitation des tâches des équipes de développement. Au cours des 20 dernières années, on a assisté à une évolution vers un découplage et une autonomie accrus des composants d’une application, dès les architectures SOA, en passant par les bus de messages, jusqu’aux microservices.
Ces dernières années, l’émergence des technologies de conteneurs a accéléré cette évolution, en fournissant à l’écosystème de développement et d’exploitation des infrastructures et des outils qui facilitent et, d’une certaine manière, poussent à l’adoption des microservices comme éléments constitutifs des applications. Ce qui était un bloc est devenu des dizaines de petits composants autonomes (microservices), avec des fonctionnalités très spécifiques. Pour utiliser une analogie simple, ce modèle de conception est analogue à celui utilisé par le système d’exploitation UNIX depuis sa création : au lieu de fournir des programmes complexes et lourds avec des dizaines de fonctionnalités, l’environnement est fourni avec de petits utilitaires hautement spécialisés dans l’exécution d’une tâche très spécifique et simple, et une série de mécanismes d’interconnexion qui permettent de les combiner pour résoudre des problèmes plus complexes. Ce modèle de conception des systèmes d’exploitation a été couronné de succès au cours des 50 dernières années. Il ne semble donc pas être un mauvais exemple à prendre en compte pour guider l’architecture des applications.
La prolifération des plateformes de conteneurs, avec Kubernetes en tête, a jonché les centres de données de milliers de conteneurs. Les applications sont désormais constituées de dizaines ou de centaines de conteneurs, dont le schéma de communication entre eux constitue leur système nerveux, tout comme dans un organisme vivant. Cette communication s’effectue sur le réseau existant, dans la plupart des cas le réseau d’un cluster Kubernetes. Et c’est là que les premières difficultés apparaissent.
Si, dans le fonctionnement traditionnel d’une simple application classique, avec ses couches de frontend et de backend typiques, les flux de trafic sont bien définis et facilement traçables, imaginez ce qui se passe dans une application basée sur des dizaines de microservices, répartis sur plusieurs systèmes physiques, ou même dans une infrastructure hybride, où une partie se trouve dans un centre de données propriétaire et le reste dans un cloud public. Le nombre de flux de communication explose géométriquement à mesure que la taille de l’application augmente, et en garder la trace devient une tâche ingérable. L’idée de surveiller ces flux ou de résoudre un problème fonctionnel ou de performance est angoissante.

Illustration 1- L’architecture de microservices d’Uber en 2018. Source : Uber.
Modèle d’adolecía et fonctions du cycle de vie des applications
En plus de relever ce défi, il est vite apparu que le modèle manquait d’un certain nombre de fonctionnalités qui faciliteraient grandement le cycle de vie des applications, comme :
- Équilibrage de la charge: la capacité de répartir le trafic sur plusieurs instances d’un même microservice.
- Routage intelligent: prendre des décisions de routage en fonction de politiques, en fonction de périodes de temps, de l’état d’autres services, du type de trafic ou de son contenu, par exemple. Cette fonctionnalité est essentielle pour adopter des modèles de déploiement de type A/B, blue/green ou canary.
- Découverte de services: compte tenu de la complexité que peut atteindre une application basée sur des microservices, il est très pratique de disposer d’un mécanisme de découverte de services, afin qu’un microservice qui doit communiquer avec un autre sache où le trouver.
- Résilience: facilité de réacheminement du trafic vers un service de secours en cas de défaillance du service principal.
- Observabilité: dans le monde des applications monolithiques, les interactions entre leurs composants peuvent être retracées à l’aide d’outils de débogage et de profiling. Dans le monde des microservices, ces interactions sont des flux de communication au niveau du réseau, très complexes, dynamiques. Il est souhaitable de pouvoir surveiller et analyser ces interactions pour, par exemple, diagnostiquer des problèmes, optimiser les performances ou prévoir la capacité.
- Sécurité: les données entre les différents microservices doivent être cryptées et les deux extrémités doivent se valider mutuellement à l’aide de certificats numériques, car il n’y a pas de contrôle (depuis la couche application) des réseaux par lesquels les données transitent. En outre, il serait souhaitable de pouvoir gérer les permissions, afin d’empêcher tout flux de communication non autorisé, ce qui améliorerait considérablement la sécurité de l’application.
Il ne semble pas raisonnable de demander aux équipes de développement de mettre en œuvre ces fonctionnalités dans les microservices eux-mêmes, principalement en raison de l’augmentation considérable du temps et des coûts. Ce qui semble plus logique, c’est de créer des bibliothèques qui mettent en œuvre ces fonctionnalités, afin qu’elles puissent être intégrées dans les applications. Ce fut la première approche (Stubby de Google, Hysterix de Netflix ou Finagle de Twitter), mais on s’est vite rendu compte que la maintenance de ces bibliothèques était très complexe et coûteuse. Par exemple, une des motivations de l’utilisation des microservices est que chaque microservice peut utiliser le langage que l’équipe de développement en charge juge le plus approprié, indépendamment du reste des microservices. Cette diversité des environnements de développement doit être transférée à ces bibliothèques, ce qui oblige leurs développeurs à porter les mêmes fonctionnalités dans des dizaines de langages. D’autre part, lorsqu’une vulnérabilité est corrigée ou qu’un problème est résolu, il est nécessaire de reconstruire tous les microservices, éventuellement dans une nouvelle version, et un nouveau déploiement de l’application.
Il était donc logique de séparer ces fonctionnalités des microservices eux-mêmes, qui devaient être agnostiques par rapport aux détails de mise en œuvre des microservices. Ceci est réalisé par l’utilisation d’un proxy local à chaque microservice, qui gère les communications entrantes et sortantes vers et depuis le microservice. Du point de vue du microservice, sa seule interface avec le monde est ce proxy, qu’il doive accepter des connexions ou qu’il ait besoin de communiquer avec un autre composant de l’application. C’est ce proxy qui gère les tâches d’équilibrage, de gestion du trafic, de sécurité, etc. de manière transparente pour l’application. Grâce à la technologie des conteneurs, la mise en œuvre de ces proxies est indépendante de la technologie utilisée dans le microservice qui lui est associé.
Ce réseau de proxies est le plan de données de facto de l’application, qui gère la communication entre tous ses composants. La configuration et la supervision de ce plan de données sont assurées par le plan de contrôle correspondant. Les deux plans de données et de contrôle permettent l’établissement d’un maillage de communication, que nous appelons service mesh. Des exemples d’implémentations sont Linkerd, Istio ou Consul Connect.
Conceptualmente, a lo que se llega es a una red overlay sobre la infraestructura de red existente. Este tipo de redes nace como solución para satisfacer funcionalidades que la red sobre la que se apoya (underlay) carece. Algunos ejemplos de este tipo de redes son, por ejemplo:
Sur le plan conceptuel, nous aboutissons à un réseau overlay sur l’infrastructure de réseau existante. Ce type de réseau est né comme une solution pour satisfaire les fonctionnalités qui font défaut au réseau sous-jacent (underlay). Des exemples de tels réseaux sont, par exemple :
- Le réseau Tor, qui a été créé pour garantir l’anonymat des utilisateurs, ce que l’Internet ne peut pas faire nativement.
- Les VPN, qui sont développés pour assurer la sécurité sous forme de communications cryptées et d’authentification de pair à pair.
- Le réseau CNI de Kubernetes, qui fournit un réseau plat entre les conteneurs indépendamment des serveurs physiques qui composent un cluster, comme Weave, Flannel ou Calico.
En général, l’apparence d’un overlay préoccupe beaucoup les responsables des communications et de la sécurité dans les organisations, car elle échappe à leur contrôle. Par exemple, un réseau overlay pourrait interconnecter des services qui dans l‘underlay seraient isolés par des politiques de sécurité. Il est également courant qu’au fil du temps, certaines des fonctionnalités qui ont motivé la création de l’overlay finissent par être mises en œuvre, de manière beaucoup plus efficace, dans l’underlay. C’est, par exemple, ce qui s’est passé avec les overlays de Kubernetes et les SDN tels que Cisco ACI.
La question que de nombreuses organisations se posent dans ce scénario est la suivante : dois-je intégrer un service mesh dans mon environnement et adapter mes développements pour l’utiliser ? La réponse n’est pas facile. Les avantages sont évidents, mais il faut tenir compte de certains inconvénients au moment de prendre la décision :
- Immaturité: la technologie permettant de mettre en œuvre le service mesh est relativement récente, et certaines mises en œuvre n’ont encore que quelques heures de vol à leur actif.
- Préparation de l’équipe: la courbe d’apprentissage pour les profils de développement et d’exploitation est assez raide.
Dans la plupart des cas, la meilleure approche sera un environnement hybride, dans lequel coexisteront des applications qui peuvent tirer parti du service mesh et des applications plus traditionnelles qui ne valent pas la peine d’être migrées vers le nouveau schéma. Au fil du temps, le rapport entre les applications sur le service meshaugmentera progressivement.
Au cours des prochaines années, nous verrons tous ces inconvénients disparaître et le service mesh deviendra un élément essentiel dans l’architecture des applications.
Si quieres más información sobre Satec no dudes ponerte en contacto aquí 👈