Guide de conception des listeners Envoy Gateway : patterns multi-port, multi-hostname et multi-ingress

5 min read

Beaucoup de gens qui apprennent Gateway API traitent Listener comme "ah oui, c'est juste le champ port: 80." Mais dans les déploiements réels, Listener est loin d'être un figurant : c'est plutôt le centre de contrôle du trafic pour toute votre couche d'entrée.

Un listener ne se contente pas d'ouvrir un port. Il définit :

  • Quel protocole accepter
  • Quel hostname accepter
  • S'il faut effectuer TLS
  • Quels types de routes sont autorisés à s'attacher

Autrement dit, un listener est un contrat d'entrée. Écrivez des contrats propres, et les routes en aval, la répartition des responsabilités d'équipe et la complexité du débogage deviennent plus propres elles aussi.

Construire le bon modèle mental : un listener = un slot d'entrée

Prenez ce Gateway :

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: eg
spec:
  gatewayClassName: eg
  listeners:
    - name: http
      protocol: HTTP
      port: 80
    - name: https
      protocol: HTTPS
      port: 443
      hostname: app.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: app-cert
    - name: grpc
      protocol: HTTPS
      port: 8443
      hostname: grpc.example.com
      tls:
        mode: Terminate
        certificateRefs:
          - name: grpc-cert

Ce n'est pas juste "un Gateway avec trois trous". Voyez-le plutôt comme :

  • Le listener http : pour le HTTP en clair
  • Le listener https : pour app.example.com
  • Le listener grpc : un point d'entrée dédié aux services gRPC

Une fois que vous pensez ainsi, beaucoup de décisions de conception deviennent immédiatement claires. Vous n'assemblez pas seulement du YAML, vous dessinez des frontières d'entrée.

Trois patterns de découpage courants

Pattern 1 : découper par protocole

L'approche la plus intuitive :

  • HTTP sur un listener
  • HTTPS sur un listener
  • gRPC sur un listener
  • TCP/TLS passthrough séparés à part

Cela donne des responsabilités claires. Même si gRPC et les API web générales peuvent tous deux tourner sur HTTP/2, leurs modèles de service diffèrent. Les garder séparés évite que les routes interfèrent les unes avec les autres.

Pattern 2 : découper par hostname

Si vous avez plusieurs domaines, un pattern courant consiste à mettre un listener par hostname principal :

listeners:
  - name: app
    hostname: app.example.com
    protocol: HTTPS
    port: 443
  - name: admin
    hostname: admin.example.com
    protocol: HTTPS
    port: 443

Cela fonctionne bien pour :

  • Séparer la gouvernance publique et la gouvernance d'administration
  • Des hostnames différents nécessitant des certificats différents
  • Garder des frontières d'attachement de routes bien nettes

Pattern 3 : découper par responsabilité d'équipe ou d'environnement

Dans les setups multi-équipes, les listeners peuvent servir de frontières de gouvernance :

  • public-api pour le trafic produit externe
  • internal-api pour les systèmes internes
  • partner-api pour les intégrations partenaires

Ici, la valeur du listener dépasse la simple configuration technique : il devient une frontière de permissions et de responsabilités. Ce pattern change réellement la donne dans les équipes moyennes à grandes, car il réduit la catastrophe du "même point d'entrée où tout le monde peut attacher n'importe quoi".

sectionName et allowedRoutes : deux champs critiques

Une route s'attache à un listener précis via parentRefs.sectionName :

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
spec:
  parentRefs:
    - name: eg
      sectionName: https
  hostnames:
    - "app.example.com"
  rules:
    - backendRefs:
        - name: app-service
          port: 8080

Cette route ne cherchera que le listener https. Sans préciser sectionName, le système applique des règles pour trouver des listeners compatibles, mais dans les configurations multi-listeners, être explicite est presque toujours plus sûr.

L'autre champ critique est allowedRoutes :

listeners:
  - name: public
    protocol: HTTPS
    port: 443
    allowedRoutes:
      namespaces:
        from: Same

Cela signifie que seules les routes présentes dans le même namespace que le Gateway peuvent s'attacher. Valeurs courantes :

  • Same : uniquement le même namespace
  • All : n'importe quel namespace
  • Selector : uniquement les namespaces correspondant à un sélecteur de labels

Si vous voulez construire délibérément des frontières de plateforme, ce champ est très puissant. Il décide lui-même, au niveau du listener, de "qui peut s'attacher à cette entrée".

Conseil pratique : comment structurer les listeners sans le regretter plus tard

Un principe très utile :

Chaque listener porte une responsabilité clairement définie.

Par exemple :

  • Un listener sert un groupe principal de hostnames
  • Un listener gère un type de protocole principal
  • Un listener est ouvert à un type de route ou à un ensemble fixe de namespaces

Ne concentrez pas tout le trafic dans un listener universel en espérant que les routes s'organiseront ensuite toutes seules. Ce pattern a l'air efficace au début, mais trois mois plus tard il ressemble au tiroir à câbles mystérieux qu'on finit tous par avoir chez soi : tout est dedans, rien n'est retrouvable.

Suggestions concrètes :

  • Les noms de listeners doivent être sémantiques : https-public, grpc-internal
  • Dans les setups multi-listeners, utilisez toujours sectionName
  • Ne mélangez pas des hostnames importants dans un même listener
  • Commencez par restreindre allowedRoutes par défaut, ne démarrez pas avec from: All

Résumé en une ligne

Traitez Listener comme un contrat d'entrée, pas comme un simple réglage de port. Des frontières propres côté listener signifient que les routes s'attachent correctement, que les équipes possèdent naturellement leur périmètre et que le débogage ressemble moins à la poursuite d'un chat dans un labyrinthe.

Étape suivante

Une fois la conception des listeners réglée, la question suivante revient souvent : Entre différents namespaces et différentes équipes, qui peut attacher des routes, et qui peut référencer quoi ?

L'article suivant couvre les patterns inter-namespace et la répartition de responsabilité : 👉 Multi-namespace et responsabilité d'équipe