Envoy Envoy

Architecture d'Envoy : listeners, clusters et chaînes de filtres

Comment une requête circule réellement dans Envoy, du socket où elle arrive jusqu'à l'upstream vers lequel elle est envoyée.

9 min Débutant

La conception d’Envoy découle directement de son objectif fondateur : rendre le réseau transparent pour les applications, et permettre de distinguer rapidement un problème réseau d’un problème applicatif. Cet objectif façonne le vocabulaire (listeners, clusters, filtres) à partir duquel chaque élément de configuration d’Envoy est construit. Ce guide présente ce que fait chacun d’eux et comment une requête circule à travers.

Downstream et upstream

Envoy appelle downstream tout ce qui lui envoie une requête et upstream tout ce vers quoi il la transmet. Le downstream peut être le navigateur d’un utilisateur final, un autre service du mesh, tout ce qui ouvre une connexion vers Envoy. L’upstream est l’endroit vers lequel Envoy décide de router la requête : une instance applicative, un autre service, une API externe. Chaque élément de configuration d’Envoy se situe d’un côté ou de l’autre de cette ligne.

Listeners : par où arrivent les connexions

Un listener se lie à un port et y accepte des connexions. Une même instance d’Envoy peut définir plusieurs listeners, chacun avec son propre port et son propre pipeline de traitement, si bien qu’une instance peut, par exemple, terminer le TLS sur le 443 tout en traitant du trafic en clair sur le 8080 avec des règles entièrement différentes. Tout ce qu’un listener doit faire d’une connexion avant qu’elle puisse être routée (terminaison TLS, détection de protocole, etc.) passe par les filtres qui lui sont attachés, que le guide suivant de cette série couvre en détail.

Clusters : vers où vont les connexions

Un cluster est un groupe logique nommé d’un ou plusieurs endpoints upstream vers lesquels Envoy peut router du trafic. Si vous venez de Kubernetes, la comparaison qui fait souvent tilt : un cluster est à peu près l’analogue d’un Service, et les endpoints individuels qu’il contient sont à peu près les analogues des Pods qui se trouvent derrière. Envoy suit la santé de chaque endpoint, applique la politique de répartition de charge configurée pour le cluster et choisit une cible parmi les endpoints sains pour chaque requête.

Filtres et chaînes de filtres

Une fois qu’un listener accepte une connexion, les données traversent une séquence de filtres, de petites unités ciblées qui font chacune un seul travail, enchaînées en une chaîne de filtres. Les filtres les plus basiques opèrent au niveau réseau (TCP ou UDP), sur le flux d’octets brut, avant que quoi que ce soit n’ait été analysé comme un protocole de plus haut niveau. Envoy fournit d’office des filtres réseau pour la gestion des protocoles MongoDB, Redis et Kafka, entre autres.

Pour le trafic HTTP en particulier, un filtre réseau précis fait l’essentiel du travail : le HTTP Connection Manager, qui analyse les octets bruts pour en faire des requêtes HTTP, des en-têtes et des corps, et expose sa propre chaîne imbriquée de filtres de niveau HTTP (journalisation des accès, retries, manipulation d’en-têtes, et plus) qui opèrent une fois que le trafic est du HTTP et non plus de simples octets. Le guide suivant de cette série lui est entièrement consacré.

Routes : choisir un cluster

Une fois que le trafic atteint la couche HTTP, les routes décident vers quel cluster va une requête donnée, en fonction de caractéristiques de la requête elle-même : hôte, chemin, en-têtes. Une requête vers example.com/api peut correspondre à une route qui l’envoie vers un cluster example-com, tandis qu’un autre hôte ou chemin correspond à une tout autre route. La correspondance des routes est ce qui transforme « une requête HTTP est arrivée » en « voici le cluster précis auquel elle appartient ».

Mise en perspective : le trajet d’une requête

client downstream
      │
      ▼
   listener (lié à un port)
      │
      ▼
  chaîne de filtres (filtres réseau, puis HTTP Connection Manager)
      │
      ▼
   correspondance de routes (hôte, chemin, en-têtes)
      │
      ▼
    cluster (un groupe nommé d'endpoints)
      │
      ▼
  répartition de charge + health checking
      │
      ▼
 endpoint upstream

Une requête arrive sur un listener, traverse la chaîne de filtres de ce listener, est associée à un cluster par les règles de routage, et le cluster manager d’Envoy choisit un endpoint sain dans ce cluster auquel l’envoyer réellement. Tout ce que fait Envoy (TLS, limitation de débit, retries, observabilité) se rattache à l’une de ces étapes plutôt que d’exister comme une préoccupation à part, ce qui correspond exactement à la conception « le réseau est transparent, les problèmes sont faciles à localiser » que le projet s’était fixée : comme chaque étape est explicite et inspectable, une réponse lente ou une requête en échec peut généralement être attribuée à un listener, un filtre ou un cluster précis plutôt que de nécessiter de deviner.

Pour un récit nettement plus détaillé de ce qui se passe exactement à chaque étape, y compris les parties de l’architecture (threads de travail, pooling de connexions) que ce guide simplifie volontairement, la documentation d’Envoy sur la « vie d’une requête » détaille pas à pas tout le flux interne.

Guides populaires