
Gateway API est la nouvelle approche recommandée pour les besoins de routage avancés dans Kubernetes. Elle complète et dépasse les capacités d'Ingress, dont l'API reste stable mais gelée. Ce guide présente les concepts clés, les différences avec Ingress, et comment adopter Gateway API progressivement.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Les limitations d'Ingress et pourquoi Gateway API existe
- Les ressources GatewayClass, Gateway, HTTPRoute et ReferenceGrant
- La différence entre canaux Standard et Experimental
- Créer et vérifier une configuration de routage
- Les fonctionnalités avancées (headers, redirections, weights)
- Quand choisir Ingress ou Gateway API
Pourquoi Gateway API ?
Section intitulée « Pourquoi Gateway API ? »L'API Ingress date des débuts de Kubernetes et n'a plus évolué depuis sa stabilisation : tout ce qu'elle ne couvrait pas a été rajouté par les éditeurs sous forme d'annotations, propres à chaque contrôleur. Le résultat est une configuration qui ne survit pas à un changement d'implémentation. Gateway API repart de zéro avec des ressources typées et validées par l'API server, là où une annotation mal orthographiée était jusqu'ici ignorée sans le moindre message.
Ce que Gateway API change fondamentalement
Section intitulée « Ce que Gateway API change fondamentalement »Gateway API n'est pas seulement "Ingress avec plus de features". C'est une manière différente d'organiser les responsabilités réseau dans Kubernetes :
- Plus gouvernable, Séparation claire entre admin cluster, équipe plateforme et développeurs
- Plus composable, Ressources distinctes qui s'assemblent
- Plus standardisé, Modèle portable entre implémentations
- Plus exigeant, Demande plus de préparation qu'Ingress
Limitations d'Ingress
Section intitulée « Limitations d'Ingress »Ces limites ne sont pas des défauts d'implémentation mais des choix de conception : une ressource Ingress mélange dans un seul objet ce qui relève de l'infrastructure (ports, certificats) et ce qui relève de l'application (chemins, backends). Toute personne autorisée à créer un Ingress touche donc aux deux, ce qui interdit la délégation aux équipes de développement.
| Limitation | Impact |
|---|---|
| Annotations vendor-specific | Configuration non portable |
| Un seul niveau de config | Pas de séparation infra/dev |
| HTTP(S) uniquement | Pas de TCP/UDP natif |
| Routage basique | Manipulation headers limitée |
| Pas de traffic splitting | Canary complexe à implémenter |
Ce qu'apporte Gateway API
Section intitulée « Ce qu'apporte Gateway API »La colonne de droite mérite d'être lue attentivement : Gateway API garantit la portabilité du modèle, pas celle du comportement. Un manifeste écrit pour Traefik s'applique tel quel sur Envoy Gateway, mais rien n'assure que le filtre exotique qu'il utilise soit implémenté des deux côtés. La page de conformité du projet reste la référence à consulter avant de s'engager sur une fonctionnalité.
| Avantage | Réalité |
|---|---|
| Standardisé | Le modèle et les ressources sont portables, mais le niveau de support des fonctionnalités dépend encore de l'implémentation choisie |
| Expressif | Routage avancé sans annotations propriétaires |
| Séparation des rôles | Infra vs développeurs clairement modélisée |
| Multi-protocole | HTTP, HTTPS, TCP, UDP, gRPC au niveau du modèle d'API, le support opérationnel dépend du contrôleur |
| Extensible | Policies pour rate limiting, auth, etc. |
Quand choisir Ingress ou Gateway API ?
Section intitulée « Quand choisir Ingress ou Gateway API ? »Le critère décisif n'est pas technique mais organisationnel : combien d'équipes partagent le même point d'entrée. Sur un cluster où une seule personne gère l'exposition de trois applications, Ingress fait le travail avec moins de concepts à maîtriser. Dès que plusieurs équipes publient des routes sur une infrastructure commune, la séparation des ressources devient un gain net. Les deux API cohabitent sans conflit dans un même cluster, ce qui autorise une bascule progressive.
| Besoin | Ingress | Gateway API |
|---|---|---|
| Exposer vite une appli simple | ✅ Bien adapté | ⚠️ Possible mais plus structuré |
| Routage avancé multi-équipes | ⚠️ Limité | ✅ Très adapté |
| Politique claire infra/dev | ❌ Faible | ✅ Forte |
| Portabilité inter-contrôleurs | ⚠️ Moyenne (annotations) | ✅ Meilleure |
| Adoption dans cluster existant simple | ✅ Plus facile | ⚠️ Demande plus de préparation |
| Traffic splitting natif | ❌ Non | ✅ Oui |
| TCP/UDP/gRPC | ❌ Non | ✅ Selon contrôleur |
Recommandation :
- Nouveau projet avec besoins avancés → Gateway API
- Projet existant stable et simple → Ingress reste acceptable
- Besoin de gouvernance multi-équipes → Gateway API
Architecture et concepts
Section intitulée « Architecture et concepts »Gateway API sépare les responsabilités en trois niveaux :
| Ressource | Qui la gère | Responsabilité |
|---|---|---|
| GatewayClass | Cluster admin | Choix du contrôleur |
| Gateway | Équipe plateforme | Ports, TLS, domaines autorisés |
| HTTPRoute | Développeurs | Règles de routage applicatif |
| ReferenceGrant | Équipe plateforme | Autorise les références cross-namespace |
Canaux Standard et Experimental
Section intitulée « Canaux Standard et Experimental »Gateway API publie ses fonctionnalités via deux canaux :
| Canal | Usage | Stabilité |
|---|---|---|
| Standard | Production | Fonctionnalités GA, stables |
| Experimental | Tests, labs | Fonctionnalités en développement, peuvent changer |
Pour connaître les fonctionnalités de chaque canal, consultez le guide Getting Started officiel.
Installation
Section intitulée « Installation »Le déploiement se fait en deux temps, et les oublier tous les deux est l'erreur d'installation la plus fréquente. Les CRDs (Custom Resource Definitions) ajoutent les types Gateway, HTTPRoute et consorts au vocabulaire de l'API server ; le contrôleur est le programme qui lit ces objets et configure réellement un proxy. Sans contrôleur, vos ressources sont acceptées par le cluster mais aucun trafic n'est routé.
Installer les CRDs
Section intitulée « Installer les CRDs »Gateway API n'est pas inclus par défaut. Installez les CRDs depuis le Standard channel :
# Consultez la dernière version sur https://gateway-api.sigs.k8s.io/guides/# Exemple avec une version récente (à adapter) :kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/standard-install.yaml
# Vérificationkubectl get crd | grep gatewayInstaller un contrôleur
Section intitulée « Installer un contrôleur »Les CRDs seuls ne suffisent pas. Vous avez besoin d'un contrôleur qui implémente Gateway API :
| Contrôleur | Notes |
|---|---|
| Traefik | Support complet, simple à déployer |
| Envoy Gateway | Référence Gateway API, très complet |
| NGINX Gateway Fabric | Performant, support enterprise |
| Cilium | eBPF-based, intégré au CNI |
| Istio | Service mesh complet |
| Kong | API Gateway avec plugins |
Ressources Gateway API
Section intitulée « Ressources Gateway API »Quatre ressources composent le modèle, et elles s'emboîtent dans un ordre imposé : une HTTPRoute ne sert à rien sans un Gateway qui l'accepte, lequel ne démarre pas sans une GatewayClass prise en charge par un contrôleur. Le ReferenceGrant s'ajoute dès qu'une référence traverse une frontière de namespace. Les manifestes qui suivent forment un ensemble cohérent, à lire dans cet ordre.
GatewayClass
Section intitulée « GatewayClass »Définit l'implémentation utilisée (géré par l'admin cluster). Le champ controllerName désigne le contrôleur qui prendra en charge cette classe : c'est une chaîne fixée par l'éditeur, à reprendre exactement telle qu'elle figure dans sa documentation. Une GatewayClass est une ressource de portée cluster, elle n'appartient à aucun namespace :
apiVersion: gateway.networking.k8s.io/v1kind: GatewayClassmetadata: name: traefikspec: controllerName: traefik.io/gateway-controllerVérifiez les GatewayClass disponibles :
kubectl get gatewayclassConfigure les points d'entrée (géré par l'équipe plateforme). Chaque listener décrit une combinaison port, protocole et politique d'attachement ; c'est également ici que se termine le TLS, avec mode: Terminate qui déchiffre au niveau du Gateway. La création d'un Gateway provoque en général celle d'un Service de type LoadBalancer par le contrôleur, donc l'allocation d'une adresse publique :
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: main-gateway namespace: gateway-systemspec: gatewayClassName: traefik listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same - name: https port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: wildcard-cert allowedRoutes: namespaces: from: Selector selector: matchLabels: gateway-access: "true"Points clés :
- listeners, Définit les ports et protocoles
- allowedRoutes, Contrôle quels namespaces peuvent attacher des routes
- tls, Configuration TLS par listener
HTTPRoute
Section intitulée « HTTPRoute »Définit les règles de routage (géré par les développeurs). Le champ parentRefs désigne le Gateway auquel la route demande à s'attacher : la demande n'aboutit que si la politique allowedRoutes du Gateway l'autorise, ce qui donne à l'équipe plateforme le dernier mot. Les hostnames déclarés ici doivent être compatibles avec ceux du listener, sans quoi la route est acceptée mais ne reçoit aucun trafic :
apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: api-routes namespace: mon-appspec: parentRefs: - name: main-gateway namespace: gateway-system hostnames: - "api.example.com" rules: - matches: - path: type: PathPrefix value: /api/v1 backendRefs: - name: api-service port: 80 - matches: - path: type: PathPrefix value: /api/v2 backendRefs: - name: api-v2-service port: 80ReferenceGrant
Section intitulée « ReferenceGrant »Autorise les références cross-namespace (essentiel pour la gouvernance). Par défaut, Kubernetes refuse qu'une ressource pointe vers un objet situé dans un autre namespace : sans cette autorisation explicite, n'importe quelle route pourrait monter le Secret TLS du voisin. Le ReferenceGrant se crée toujours dans le namespace qui détient l'objet convoité, ici celui du certificat, et c'est donc son propriétaire qui consent :
apiVersion: gateway.networking.k8s.io/v1kind: ReferenceGrantmetadata: name: allow-gateway-to-secret namespace: cert-namespacespec: from: - group: gateway.networking.k8s.io kind: Gateway namespace: gateway-system to: - group: "" kind: Secret name: wildcard-certCe ReferenceGrant permet au Gateway dans gateway-system de référencer le Secret wildcard-cert dans cert-namespace.
Vérifier l'état des ressources
Section intitulée « Vérifier l'état des ressources »Gateway API fournit un status riche sur chaque ressource. Utilisez-le pour diagnostiquer :
Vérifier les GatewayClass
Section intitulée « Vérifier les GatewayClass »Une classe ACCEPTED: True prouve qu'un contrôleur l'a reconnue et se déclare responsable. Si la colonne reste vide ou à False, le contrôleur n'est pas installé ou le controllerName ne correspond pas au sien.
kubectl get gatewayclass# La colonne ACCEPTED doit être TrueVérifier les Gateway
Section intitulée « Vérifier les Gateway »Deux conditions distinctes se suivent : Accepted signifie que la configuration est valide, Programmed que le proxy sous-jacent l'a réellement appliquée et écoute. Un Gateway Accepted mais pas Programmed traduit souvent une adresse de load balancer jamais attribuée.
kubectl get gateways -A
kubectl describe gateway main-gateway -n gateway-system# Cherchez les conditions : Accepted, ProgrammedVérifier les HTTPRoute
Section intitulée « Vérifier les HTTPRoute »Le bloc Parents du statut est renseigné par le Gateway lui-même, ce qui en fait la preuve que l'attachement a été accepté. La condition ResolvedRefs concerne les backends : elle passe à False si un Service référencé n'existe pas ou n'expose pas le port demandé.
kubectl get httproutes -A
kubectl describe httproute api-routes -n mon-app# Cherchez : Parents (le Gateway parent) et les conditions Accepted/ResolvedRefsDépannage : HTTPRoute non attaché
Section intitulée « Dépannage : HTTPRoute non attaché »C'est le problème le plus courant. Votre HTTPRoute existe mais le trafic ne passe pas.
-
Vérifiez que le Gateway existe et est ACCEPTED
Fenêtre de terminal kubectl get gateway main-gateway -n gateway-system# Status doit être ACCEPTED -
Vérifiez que l'HTTPRoute référence le bon Gateway
Fenêtre de terminal kubectl describe httproute api-routes -n mon-app | grep -A5 "Parent Refs" -
Vérifiez les conditions de l'HTTPRoute
Fenêtre de terminal kubectl describe httproute api-routes -n mon-app | grep -A10 "Status"# Cherchez : Accepted, ResolvedRefs -
Vérifiez que le namespace est autorisé
Si le Gateway utilise
allowedRoutes.namespaces.from: Selector, vérifiez que votre namespace a le bon label :Fenêtre de terminal kubectl get ns mon-app --show-labels -
Vérifiez que le Service backend existe
Fenêtre de terminal kubectl get svc api-service -n mon-app
| Symptôme | Cause probable | Solution |
|---|---|---|
HTTPRoute Accepted: False | Gateway introuvable ou mauvais namespace | Vérifiez parentRefs |
HTTPRoute ResolvedRefs: False | Service backend introuvable | Vérifiez le nom/port du Service |
Gateway Programmed: False | Contrôleur pas prêt | Vérifiez les logs du contrôleur |
| Trafic ne passe pas | Namespace non autorisé | Vérifiez allowedRoutes et labels |
Exemples pratiques
Section intitulée « Exemples pratiques »Les extraits qui suivent ne montrent que le bloc spec d'une HTTPRoute : ajoutez-y les parentRefs et les hostnames de votre contexte pour obtenir un manifeste applicable. Ils couvrent les cinq besoins qui reviennent en production, du simple découpage par chemin jusqu'à la réécriture d'en-têtes.
Routage par chemin
Section intitulée « Routage par chemin »L'ordre des règles dans le fichier n'a aucune importance : la spécification impose de retenir la correspondance la plus spécifique, un chemin exact l'emportant sur un préfixe, et le préfixe le plus long sur le plus court. Inutile donc de classer vos règles de la plus fine à la plus large comme le réflexe nginx y pousse.
spec: rules: - matches: - path: type: PathPrefix value: /users backendRefs: - name: users-service port: 80 - matches: - path: type: PathPrefix value: /orders backendRefs: - name: orders-service port: 80Routage par header
Section intitulée « Routage par header »La comparaison est exacte par défaut et sensible à la casse pour la valeur, pas pour le nom de l'en-tête. Ce mécanisme sert surtout aux déploiements sombres : les testeurs positionnent l'en-tête et atteignent la version candidate, tous les autres restent sur la version stable.
spec: rules: - matches: - headers: - name: X-Version value: "beta" backendRefs: - name: api-beta port: 80 - matches: - path: type: PathPrefix value: /api backendRefs: - name: api-stable port: 80Traffic splitting (Canary)
Section intitulée « Traffic splitting (Canary) »Les weight ne sont pas des pourcentages mais des parts relatives : la proportion reçue par un backend vaut son poids divisé par la somme des poids de la règle. Un poids à 0 retire un backend de la répartition sans supprimer sa déclaration, ce qui permet de couper un canari en une seule modification.
spec: rules: - matches: - path: type: PathPrefix value: /api backendRefs: - name: api-v1 port: 80 weight: 90 - name: api-v2 port: 80 weight: 10Redirections
Section intitulée « Redirections »Le filtre RequestRedirect répond directement au client, sans jamais joindre de backend : une règle qui l'utilise n'a donc pas besoin de backendRefs. Le statusCode accepte 301 (permanent, mis en cache par les navigateurs) ou 302, et le choix se corrige mal une fois la réponse mémorisée côté client.
spec: rules: - matches: - path: type: Exact value: /old-page filters: - type: RequestRedirect requestRedirect: scheme: https hostname: new.example.com statusCode: 301Manipulation de headers
Section intitulée « Manipulation de headers »RequestHeaderModifier agit sur la requête envoyée au backend, jamais sur la réponse renvoyée au client, qui relève du filtre ResponseHeaderModifier. Retirer un en-tête interne avant de transmettre est une bonne pratique de sécurité : cela empêche un client de forger un en-tête auquel votre application ferait confiance.
spec: rules: - matches: - path: type: PathPrefix value: /api filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: X-Environment value: "staging" remove: - X-Internal-Header backendRefs: - name: api-service port: 80Migration depuis Ingress
Section intitulée « Migration depuis Ingress »Migrer ne consiste pas à convertir des fichiers un par un : un Ingress correspond à deux ressources Gateway API portées par deux équipes différentes. La bascule se fait donc application par application, en gardant les deux API actives le temps de la transition, puisqu'elles peuvent servir le même nom de domaine sur des points d'entrée distincts.
Prérequis pour migrer
Section intitulée « Prérequis pour migrer »La migration depuis Ingress suppose généralement qu'une équipe plateforme ait déjà :
- Déployé un contrôleur compatible Gateway API
- Créé une
GatewayClass(ou utilisé celle créée automatiquement) - Publié un
Gatewayauquel les équipes applicatives peuvent rattacher leurs routes
Les développeurs ne "remplacent" pas juste un Ingress par un HTTPRoute, ils attachent leur route à un Gateway existant.
Équivalence des concepts
Section intitulée « Équivalence des concepts »Ce tableau sert de grille de lecture pour traduire un manifeste existant. Les deux dernières lignes concentrent le vrai travail : ce qui vivait dans des annotations propriétaires devient un champ typé, dont le nom et la structure changent d'un contrôleur à l'autre. Toutes les annotations n'ont pas d'équivalent, certaines correspondent à des fonctionnalités encore en canal Experimental.
| Ingress | Gateway API |
|---|---|
| IngressClass | GatewayClass |
| Ingress | Gateway + HTTPRoute |
host: | HTTPRoute hostnames: |
path: | HTTPRoute matches.path: |
backend: | HTTPRoute backendRefs: |
| Annotations TLS | Gateway listeners.tls: |
| Annotations rewrite | HTTPRoute filters.URLRewrite: |
Exemple de migration
Section intitulée « Exemple de migration »Cet exemple illustre le déplacement de responsabilité : l'annotation rewrite-target, spécifique à NGINX, devient un filtre URLRewrite standard, et tout ce qui touchait au point d'entrée disparaît du manifeste du développeur. Le fichier final est plus long mais ne contient plus rien de propriétaire.
Ingress (avant) :
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: api-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80Gateway API (après) :
# L'équipe plateforme a déjà créé le Gateway# Le développeur crée uniquement l'HTTPRoute :apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: api-route namespace: mon-appspec: parentRefs: - name: main-gateway namespace: gateway-system hostnames: - "api.example.com" rules: - matches: - path: type: PathPrefix value: /api filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefixMatch replacePrefixMatch: / backendRefs: - name: api-service port: 80Maturité et évolution
Section intitulée « Maturité et évolution »Le socle HTTP est stable et utilisable en production sans réserve ; ce sont les protocoles autres que HTTP et les politiques avancées qui restent mouvants. La mention « selon certaines implémentations » est déterminante : une ressource peut être GA dans la spécification tout en n'étant supportée par aucun contrôleur que vous envisagez. Vérifiez toujours le couple ressource et contrôleur, jamais la ressource seule.
| Aspect | État (2026) |
|---|---|
| HTTPRoute, Gateway, GatewayClass | GA (Standard channel) |
| GRPCRoute, TLSRoute | GA sur certaines implémentations |
| ReferenceGrant | GA |
| TCPRoute, UDPRoute | Experimental sur certaines implémentations |
| BackendTLSPolicy | Experimental |
Gateway API est en GA pour son socle principal et continue d'évoluer via les canaux Standard et Experimental. Consultez régulièrement les release notes pour suivre les nouveautés.
À retenir
Section intitulée « À retenir »| Ressource | Rôle | Géré par |
|---|---|---|
| GatewayClass | Choix implémentation | Admin cluster |
| Gateway | Listeners, TLS, namespaces autorisés | Équipe plateforme |
| HTTPRoute | Règles de routage | Développeurs |
| ReferenceGrant | Autorise références cross-namespace | Équipe plateforme |
Ce que Gateway API apporte :
- Gouvernance, Séparation claire des responsabilités infra/dev
- Portabilité, Configuration standardisée (mais vérifiez le support du contrôleur)
- Traffic splitting, Canary natif sans annotations
- Manipulation headers, Filtres intégrés
- Multi-protocole, HTTP, TCP, gRPC (selon implémentation)
Ce que Gateway API demande :
- Plus de préparation, Gateway doit exister avant les routes
- Vérification de conformité, Toutes les features ne sont pas supportées partout
- Compréhension du modèle, Plus de concepts qu'Ingress
Message clé : Ingress reste acceptable pour les cas simples. Gateway API devient le meilleur choix dès qu'on veut de la gouvernance, du routage avancé, ou une standardisation durable.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Ces questions portent sur les points qui coûtent le plus cher en pratique : le rôle de chaque ressource, les conditions de statut et les règles d'attachement entre namespaces. Un score inférieur à 70 % désigne les sections à relire avant de déployer.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Pod Networking : Le chemin réseau réel entre la Gateway et les Pods de destination.
- mTLS pod-to-pod : Le chiffrement du trafic interne, complément du TLS terminé en bordure.