Gateway API est le successeur standardisé de l’Ingress, porté par le groupe SIG-Network de Kubernetes. Là où Ingress est un objet unique et rigide (host + path → service, tout le reste passant par des annotations propriétaires non portables d’un contrôleur à l’autre), Gateway API découpe le même besoin en plusieurs objets — pensés dès le départ pour être partagés entre plusieurs équipes.


Rôle dans l’architecture

GatewayClass "envoy"          ← posé par l'admin infra (le type d'implémentation)
       │
       ▼
Gateway "gw-prod"             ← équipe infra/plateforme (IP, ports, certificats TLS)
       │
       ├── HTTPRoute "api"    ← équipe applicative A (/api → Service api-svc)
       ├── HTTPRoute "app"    ← équipe applicative B (/ → Service frontend-svc)
       └── HTTPRoute "auth"   ← équipe applicative C (/auth → Service auth-svc)
ObjetRôlePropriétaire typique
GatewayClassRéférence l’implémentation utilisée (Envoy Gateway, Istio, Contour…) — équivalent de ingressClassName, mais comme une ressource à part entièreAdmin infra/plateforme
GatewayL’instance concrète : adresse IP, listeners (ports, protocoles), certificats TLSÉquipe infra/plateforme
HTTPRoute / TCPRoute / TLSRoute / GRPCRouteLes règles de routage vers les Services, rattachées à un Gateway existantÉquipe applicative

Le gain principal : une équipe applicative peut créer et modifier son propre HTTPRoute sans jamais avoir les droits (RBAC) de toucher au Gateway partagé — impossible à isoler proprement avec un Ingress unique, où routage et infrastructure du LB sont mélangés dans le même objet.


Implémentations courantes (contrôleurs)

Comme pour Ingress, Gateway API est une spec : elle ne fait rien seule, il faut un contrôleur qui la traduit en vrai routage.

ContrôleurParticularité
Envoy GatewayImplémentation de référence, maintenue par le projet Envoy — la plus simple pour démarrer
IstioGateway API comme remplaçant progressif de son propre CRD VirtualService/Gateway historique
ContourBasé sur Envoy également, orienté simplicité opérationnelle
ciliumLe CNI du cluster peut aussi servir de Gateway API controller (évite de déployer un composant supplémentaire)
Kong, TraefikSupportent Gateway API en plus de leur CRD propriétaire historique

Sur un cloud managé, le cloud-provider fournit en général sa propre implémentation (ex. GKE Gateway Controller, qui traduit vers son Load Balancer géré plutôt que de déployer des pods proxy — voir Ingress et Cloud Load Balancing pour le détail côté GKE).


Installation via Helm (Envoy Gateway)

helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.1.0 \
  --namespace envoy-gateway-system \
  --create-namespace
 
kubectl wait --timeout=5m -n envoy-gateway-system \
  deployment/envoy-gateway --for=condition=Available

Installe le contrôleur et enregistre automatiquement la GatewayClass correspondante.


Exemple : GatewayClass + Gateway + HTTPRoute

1. GatewayClass (posée une fois par l’admin infra — souvent déjà créée par l’install du contrôleur)

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

Dit “ce type de Gateway est géré par Envoy” (controllerName est une chaîne fixe imposée par le contrôleur). En pratique tu la touches rarement — le chart Helm du contrôleur la crée automatiquement à l’installation.

2. Gateway (l’instance concrète, avec le TLS)

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gw-prod
  namespace: infra
spec:
  gatewayClassName: envoy
  listeners:
  - name: https
    protocol: HTTPS
    port: 443
    hostname: "*.exemple.com"
    tls:
      mode: Terminate
      certificateRefs:
      - name: monapp-tls-secret       # ex. généré par cert-manager
    allowedRoutes:
      namespaces:
        from: All                     # autorise des HTTPRoute d'autres namespaces à s'y attacher

L’instance réelle : port 443, TLS via un Secret cert-manager. Le champ clé pour le multi-équipe est allowedRoutes.namespaces.from: All, qui autorise des HTTPRoute d’autres namespaces (donc d’autres équipes) à s’y attacher — sans lui, seules les HTTPRoute du même namespace seraient acceptées.

3. HTTPRoute (créée par l’équipe applicative, dans son propre namespace)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-route
  namespace: team-api
spec:
  parentRefs:
  - name: gw-prod
    namespace: infra
  hostnames:
  - "api.exemple.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: api-svc
      port: 8080

Créée par l’équipe applicative, dans son propre namespace. parentRefs la relie au Gateway de l’équipe infra ; matches/backendRefs font le routage / → api-svc:8080, comme un Ingress classique.

L’équipe team-api ne touche qu’à son HTTPRoute, dans son namespace — jamais au Gateway gw-prod qui vit dans infra.


Modes TLS : Terminate vs Passthrough

Deux façons fondamentalement différentes de gérer le TLS au niveau du Gateway — le choix détermine aussi quel type de Route peut s’y attacher.

Terminate (le cas standard, vu ci-dessus)

Client ──HTTPS chiffré──► Gateway (Envoy)
                              │ déchiffre avec la clé privée
                              │ du certificat (Secret K8s)
                              │ lit le Host header + path
                              ▼
                         HTTPRoute (matching)
                              │
                              ▼
                    Service ──HTTP en clair──► Pod
  • Le Gateway possède le certificat (certificateRefs) et déchiffre tout le trafic — seule façon d’accéder au contenu HTTP (Host, path, headers) pour router finement.
  • Route attachée : HTTPRoute.
  • Le pod ne reçoit que du HTTP en clair, sans certificat à gérer lui-même.

Passthrough (le Gateway ne déchiffre rien)

Client ──HTTPS chiffré (jamais déchiffré)──► Gateway (Envoy)
                              │ lit UNIQUEMENT le SNI
                              │ (le nom de domaine, en clair
                              │  dans le handshake TLS,
                              │  avant le chiffrement complet)
                              ▼
                         TLSRoute (matching sur SNI seulement —
                                    pas de Host header HTTP,
                                    tout le reste reste chiffré)
                              │
                              ▼
                    Service ──HTTPS toujours chiffré──► Pod
                                                          │ le pod déchiffre
                                                          │ avec SON PROPRE
                                                          │ certificat
  • Le Gateway ne possède aucun certificat applicatif — pas de certificateRefs. Il route en aveugle, uniquement à partir du SNI (lisible même en Passthrough, car il fait partie de la négociation TLS, avant le chiffrement symétrique).
  • Route attachée : TLSRoute — pas HTTPRoute, impossible de matcher sur un path ou un header puisque le contenu reste chiffré de bout en bout.
  • C’est le pod applicatif qui termine le TLS avec son propre certificat — utile quand une équipe veut garder le contrôle total de son certificat (conformité, chiffrement de bout en bout, mTLS applicatif) sans le confier à l’équipe infra qui possède le Gateway.
# Gateway — listener TLS (pas HTTPS), mode Passthrough
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gw-prod
  namespace: infra
spec:
  gatewayClassName: envoy
  listeners:
  - name: tls-passthrough
    protocol: TLS              # pas "HTTPS"
    port: 443
    hostname: "secure.exemple.com"
    tls:
      mode: Passthrough        # pas de certificateRefs — rien à déchiffrer
    allowedRoutes:
      kinds:
      - kind: TLSRoute
# TLSRoute — matching uniquement sur le SNI, créée par l'équipe applicative
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: secure-route
  namespace: team-secure
spec:
  parentRefs:
  - name: gw-prod
    namespace: infra
  hostnames:
  - "secure.exemple.com"
  rules:
  - backendRefs:
    - name: secure-svc         # le pod derrière gère lui-même son TLS
      port: 443
Terminate + HTTPRoutePassthrough + TLSRoute
Qui détient le certificatLe Gateway (équipe infra)Le pod applicatif (équipe app)
Ce que voit le GatewayContenu HTTP en clair (Host, path, headers)Rien — seulement le SNI
Routage possibleHost + path + headers (fin)SNI uniquement (grossier)
Trafic Gateway → Service → PodEn clairToujours chiffré
Cas d’usageLe cas standard, la grande majorité des apps webConformité stricte, mTLS applicatif, équipe qui refuse de partager son certificat

Fonctionnalités avancées standardisées

Contrairement aux annotations Ingress (propriétaires, un langage différent par contrôleur), ces comportements sont définis dans la spec Gateway API elle-même — donc portables d’une implémentation à l’autre :

rules:
- matches:
  - path:
      type: PathPrefix
      value: /
  backendRefs:
  - name: frontend-v1
    port: 80
    weight: 90        # 90% du trafic
  - name: frontend-v2
    port: 80
    weight: 10        # 10% du trafic — canary release standardisé, sans CRD tiers
  • Pondération de trafic (weight) entre plusieurs backendRefs — canary/blue-green sans outil tiers.
  • Matching avancé : sur headers, query params, méthode HTTP — pas seulement host/path comme Ingress.
  • Filtres standardisés : réécriture d’URL/headers, redirection, miroir de requêtes (RequestMirror).
  • Multi-protocole : TCPRoute, TLSRoute (passthrough), GRPCRoute — Ingress était pensé HTTP(S) uniquement.

Comparaison avec Ingress

IngressGateway API
ObjetsUn seul (Ingress)Trois, séparés par rôle (GatewayClass/Gateway/HTTPRoute)
RBACTout dans un objet — difficile d’isoler infra vs applicatifIsolation native infra (Gateway) vs applicatif (HTTPRoute)
Fonctionnalités avancéesVia annotations propriétaires, non portablesStandardisées dans l’API, portables entre implémentations
ProtocolesHTTP(S) uniquementHTTP(S), TCP, TLS passthrough, gRPC
StatutToujours supporté, mode maintenance dans l’écosystèmeRecommandé pour tout nouveau déploiement

Vérification

# Ressources Gateway API déployées
kubectl get gatewayclass
kubectl get gateway -A
kubectl get httproute -A
 
# Statut détaillé d'un Gateway (conditions Programmed/Accepted)
kubectl describe gateway gw-prod -n infra
 
# IP/hostname assignée
kubectl get gateway gw-prod -n infra -o jsonpath='{.status.addresses}'

Liens