Envoy Gateway multi-namespace et responsabilité d'équipe : allowedRoutes, ReferenceGrant et gouvernance inter-équipes

6 min read

L'une des plus grandes valeurs de Gateway API n'est pas seulement de produire un YAML plus propre : c'est qu'il répond enfin clairement à une vieille question :

Qui possède la couche d'entrée ? Qui peut changer les routes ? Les namespaces peuvent-ils se référencer entre eux ?

Beaucoup de douleurs autour d'Ingress venaient du fait que tout était emmêlé. Les équipes plateforme craignaient des changements d'exposition non autorisés. Les équipes applicatives avaient l'impression de devoir ouvrir un ticket juste pour changer un path. Au final, tout le monde se torturait mutuellement dans le YAML.

L'approche de Gateway API consiste à dire clairement :

  • L'entrée plateforme peut être gouvernée indépendamment
  • Les routes peuvent être déléguées aux équipes applicatives
  • Les comportements inter-namespace nécessitent une autorisation explicite

Cet article explique ce modèle de responsabilité de haut en bas.

Commencez ici : attachement et référence sont deux choses différentes

C'est la distinction la plus souvent confondue.

Attachement d'une Route à un Gateway / Listener

Cela est gouverné par :

  • Les parentRefs de la route
  • Les allowedRoutes du listener

Autrement dit, la possibilité pour une route de s'attacher à un listener n'est pas déterminée par ReferenceGrant, mais par le fait que le listener accepte ou non cet attachement.

Références inter-namespace à des ressources

C'est là que ReferenceGrant entre généralement en jeu. Par exemple :

  • Un Gateway veut référencer un Secret dans un autre namespace
  • Un HTTPRoute veut référencer un Service dans un autre namespace

La question n'est pas celle de l'attachement, mais plutôt : "le namespace cible vous a-t-il officiellement autorisé à utiliser ses ressources ?"

Beaucoup de gens mélangent ces deux idées et commencent à douter de leur santé mentale. Les règles sont beaucoup moins mystérieuses une fois les rôles séparés.

allowedRoutes : décidez d'abord qui peut s'attacher

Le listener le plus restrictif ressemble à ceci :

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shared-gateway
  namespace: infra
spec:
  gatewayClassName: eg
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      allowedRoutes:
        namespaces:
          from: Same

Cela signifie que seules les routes du namespace infra peuvent s'attacher à ce listener.

Pour autoriser des namespaces d'équipe spécifiques à s'attacher, utilisez Selector :

allowedRoutes:
  namespaces:
    from: Selector
    selector:
      matchLabels:
        shared-gateway-access: "true"

Ce pattern fonctionne bien pour les équipes plateforme. Vous n'avez pas besoin de tout verrouiller complètement, mais vous n'êtes pas non plus obligé d'ouvrir en from: All et de laisser tout le monde entrer sans limite. Vous pouvez exiger qu'un namespace mérite le droit de s'attacher en portant un label spécifique.

💡 allowedRoutes s'applique par listener, pas par Gateway. Différents listeners peuvent donc avoir différentes politiques d'accès.

ReferenceGrant : c'est le namespace cible qui décide

Si une route ou un gateway veut référencer des ressources dans un autre namespace, le namespace cible doit l'autoriser.

Par exemple, le HTTPRoute d'une équipe applicative veut envoyer du trafic vers un backend dans un namespace partagé :

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: app-route
  namespace: team-a
spec:
  parentRefs:
    - name: shared-gateway
      namespace: infra
      sectionName: https
  rules:
    - backendRefs:
        - name: shared-api
          namespace: shared-services
          port: 8080

Le namespace shared-services doit alors fournir un ReferenceGrant :

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-team-a-route
  namespace: shared-services
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute
      namespace: team-a
  to:
    - group: ""
      kind: Service

En français simple :

  • Les ressources HTTPRoute dans team-a
  • Sont autorisées à référencer des ressources Service dans shared-services

Notez bien que l'autorisation est créée par le namespace cible, pas par la source. La source ne peut pas simplement déclarer qu'elle veut un accès : c'est le propriétaire de la ressource qui décide. Cette conception est en réalité très saine, car les propriétaires doivent contrôler qui accède à leurs ressources.

Répartition courante entre équipe plateforme et équipes applicatives

Le modèle de responsabilité le plus courant ressemble à ceci :

L'équipe plateforme possède

  • GatewayClass
  • Gateway
  • Listener
  • La gestion des certificats TLS
  • Les politiques allowedRoutes

Les équipes applicatives possèdent

  • HTTPRoute / GRPCRoute dans leurs propres namespaces
  • Les services backend
  • Les ajustements de règles de routage

Les bénéfices de cette séparation sont clairs :

  • L'équipe plateforme protège le périmètre d'exposition et la frontière de sécurité de l'entrée
  • Les équipes applicatives peuvent quand même avancer vite sur leurs propres règles de trafic
  • Personne n'a besoin de toucher au Gateway partagé simplement pour changer un path

Vous pouvez aussi donner tous les droits à un seul groupe, ce n'est pas faux. Mais dans les grandes équipes, ce modèle a tendance à évoluer vers "tout le monde peut le modifier, donc quand ça casse personne ne sait qui a fait quoi".

Conseils pratiques : comment éviter les catastrophes multi-tenant

Habitudes réellement utiles :

  • Les Gateways partagés utilisent par défaut allowedRoutes.namespaces.from: Selector
  • Les conventions de labels de namespace doivent être stables, ne renommez pas team-a en allow-gw le mois prochain
  • Toutes les références inter-namespace vers backend/Secret passent par ReferenceGrant
  • Les noms de routes doivent indiquer l'équipe ou le service, par exemple team-a-api-route
  • Les listeners partagés doivent toujours utiliser sectionName pour éviter que les routes s'attachent à la mauvaise entrée

Un principe à garder :

Si vous pouvez faire respecter une frontière au niveau de la couche d'entrée, ne comptez pas uniquement sur la documentation et l'espoir que chacun s'auto-discipline.

En ingénierie, le processus l'emporte sur l'accord verbal. On dirait un conseil de quelqu'un de beaucoup plus âgé, mais c'est sincèrement utile.

Résumé en une ligne

Dans Gateway API, allowedRoutes contrôle "qui peut entrer", et ReferenceGrant contrôle "à quoi ces personnes peuvent accéder une fois dedans". Gardez bien ces deux idées distinctes, et les scénarios multi-namespace / multi-équipes deviennent beaucoup plus gérables.

Étape suivante

Une fois les responsabilités et les permissions clarifiées, la dernière pièce du puzzle est : Quand une configuration ne prend pas effet, quel status, quelle condition et quelle commande faut-il regarder en premier ?

L'article suivant couvre le débogage et l'interprétation du status : 👉 Guide du status et du débogage