L'Ingress de Kubernetes a tenu pendant huit ans, mais ses limites étaient connues dès l'origine : ressource simple à l'extrême, dépendance forte aux annotations propriétaires de chaque controller, pas de support natif pour gRPC, TCP, UDP ou TLS passthrough. Chaque éditeur (NGINX, Traefik, HAProxy, Contour, AWS ALB, GCE) ajoutait ses propres conventions, et les migrations entre controllers tournaient au cauchemar.
Gateway API règle cette dette. Conçue par le SIG Network de Kubernetes pour remplacer Ingress, l'API est désormais en GA depuis la v1.0 (octobre 2023), avec une v1.5 stable en mars 2026. Cet article présente le modèle, les ressources, les implémentations matures, et donne un cadre clair pour migrer depuis Ingress.
Plan de l'article
- Pourquoi Gateway API
- Le modèle : GatewayClass, Gateway, Routes
- Les ressources principales
- Implémentations matures
- Comparaison Gateway API vs Ingress
- Cas concret : migration depuis Ingress NGINX
- Limites et points d'attention
Pourquoi Gateway API
L'Ingress souffrait de trois problèmes structurels.
Modèle trop simple. Une seule ressource pour tout : routage HTTP, hostnames, TLS, parfois redirections. Pour des cas avancés (rate limiting, mTLS, canary, header rewrite), tout passait par des annotations propriétaires différentes selon le controller.
Pas de séparation des responsabilités. La même équipe configurait l'infrastructure (load balancer, certificats, ports) et le routage applicatif (paths, services). Pour une plateforme multi-équipes, c'était souvent un goulet.
Couverture protocole réduite. HTTP/HTTPS uniquement officiellement. gRPC, TCP, UDP, TLS passthrough : tout devait passer par des CRDs propres à chaque controller (IngressRoute Traefik, VirtualServer NGINX Plus, etc.).
Gateway API règle ces points en distinguant clairement trois rôles (infrastructure provider, cluster operator, application developer), en supportant nativement plusieurs protocoles et en offrant un modèle composable où plusieurs Routes peuvent attacher des règles à un même Gateway.
Le modèle : GatewayClass, Gateway, Routes
Gateway API définit une chaîne de ressources, chacune attribuée à un rôle :
┌─────────────────┐
│ GatewayClass │ ← Infrastructure provider
│ (NGINX/Istio │ (qui implémente quoi)
│ /Envoy/...) │
└────────┬────────┘
│
┌────────▼────────┐
│ Gateway │ ← Cluster operator
│ (LB physique, │ (LB, ports, TLS)
│ ports, TLS) │
└────────┬────────┘
│
┌─────┼─────┬──────────────┐
│ │ │ │
┌──▼──┐┌─▼──┐┌─▼──┐ ┌──────▼──────┐
│HTTP ││gRPC││TLS │ │ TCPRoute │ ← Application developer
│Route││Rt. ││Rt. │ │ / UDPRoute │
└─────┘└────┘└────┘ └─────────────┘
- GatewayClass : déclare quelle implémentation gère les Gateways. Une
GatewayClass"envoy-gateway" ou "istio" indique au control plane comment matérialiser les Gateways qui s'y rattachent. - Gateway : ressource opérationnelle. Définit un point d'entrée (hostname, ports, certificats TLS). Implémenté par un load balancer ou un proxy concret.
- Routes (HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute) : règles de routage. Attachées à un Gateway via
parentRefs.
Les ressources principales
GatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: envoy-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
Ressource cluster-scoped. Une seule par implémentation, déployée par l'équipe infrastructure.
Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
namespace: gateway-system
spec:
gatewayClassName: envoy-gateway
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: prod-tls-cert
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: 'allowed'
Le Gateway expose un point d'entrée (port 443, TLS terminé). Les allowedRoutes contrôlent quels namespaces peuvent y attacher des Routes. C'est la frontière entre cluster operator et application developer.
HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: my-app
labels:
gateway-access: 'allowed'
spec:
parentRefs:
- name: prod-gateway
namespace: gateway-system
hostnames:
- 'api.example.com'
rules:
- matches:
- path:
type: PathPrefix
value: /v2
backendRefs:
- name: api-v2
port: 8080
weight: 90
- name: api-v2-canary
port: 8080
weight: 10
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: api-v1
port: 8080
Les HTTPRoute supportent nativement le traffic splitting (canary, blue/green) via les weight, le header matching et header manipulation, le timeout et retry, sans annotations propriétaires.
Implémentations matures
Plusieurs implémentations sont conformes Gateway API v1.x et utilisables en production :
| Implémentation | Maturité | Cas d'usage |
| Envoy Gateway | Mature | Implémentation de référence, cluster k8s standalone |
| Istio | Mature (depuis 1.20) | Si déjà investi dans Istio service mesh |
| NGINX Gateway Fabric | Mature | Continuité avec NGINX Ingress |
| Cilium | Mature | Si déjà sur Cilium pour le réseau |
| Traefik | Mature | Si déjà sur Traefik |
| Contour | Mature | VMware Tanzu / Cluster Bonsai |
| HAProxy Kubernetes Ingress | En production | Pour les utilisateurs HAProxy |
| Kong Ingress Controller | Mature | Si déjà sur Kong |
| AWS Gateway API Controller | Production | EKS avec ALB / NLB |
| GKE Gateway | Mature | GKE avec Google Cloud Load Balancer |
| Azure App Routing | En croissance | AKS |
Pour un nouveau cluster, Envoy Gateway est le choix par défaut : implémentation officielle de la spec, basée sur Envoy (le proxy le plus testé), maintenue par les contributeurs core.
Comparaison Gateway API vs Ingress
| Critère | Gateway API | Ingress |
| Standardisation des fonctionnalités | Native dans les CRDs | Annotations propriétaires |
| Protocoles | HTTP, HTTPS, gRPC, TCP, UDP, TLS | HTTP/HTTPS uniquement officiellement |
| Séparation des rôles | GatewayClass / Gateway / Route | Une ressource pour tout |
| Multi-namespace routing | Natif (allowedRoutes, namespaces) | Hacks d'annotations |
| Traffic splitting (canary) | Natif (weights) | Annotations propriétaires |
| Header manipulation | Natif | Annotations propriétaires |
| Référence multi-Gateway | Une Route attachable à plusieurs | Non |
| Migration entre controllers | Recompatibilité limitée | Annotations à réécrire |
| Maturité spec | GA depuis v1.0 (oct 2023) | GA depuis 2018 |
Pour les nouveaux clusters et les nouvelles applications, Gateway API est la voie recommandée. Ingress reste fonctionnel et continue d'être supporté, mais aucune nouvelle fonctionnalité majeure n'y sera ajoutée.
Cas concret : migration depuis Ingress NGINX
Migrer une application Ingress NGINX vers Gateway API se fait en deux étapes.
Avant :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/canary: 'true'
nginx.ingress.kubernetes.io/canary-weight: '10'
spec:
ingressClassName: nginx
tls:
- hosts: ['api.example.com']
secretName: prod-tls
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-canary
port:
number: 8080
Après (deux ressources : Gateway pour l'infra, HTTPRoute pour l'app) :
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
namespace: gateway-system
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: prod-tls
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
namespace: my-app
spec:
parentRefs:
- name: prod-gateway
namespace: gateway-system
hostnames: ['api.example.com']
rules:
- backendRefs:
- name: api-stable
port: 8080
weight: 90
- name: api-canary
port: 8080
weight: 10
Le canary, qui était une annotation nginx.ingress.kubernetes.io/canary-weight propriétaire, devient un weight standard. La même logique fonctionnera sur Envoy Gateway, Istio, Cilium ou tout autre implémenteur.
Limites et points d'attention
Pas toutes les implémentations supportent tout. La conformité couvre HTTPRoute en priorité. GRPCRoute, TLSRoute, TCPRoute, UDPRoute sont à différents stades de support selon les controllers. À vérifier sur la matrice de conformité officielle.
Migration progressive recommandée. Inutile de tout migrer d'un coup. Faire cohabiter Ingress et Gateway API sur le même cluster est parfaitement viable pendant la transition.
Outils tiers en cours d'adaptation. Les outils périphériques (cert-manager, ExternalDNS, Argo Rollouts, monitoring qui scrute les Ingress) ont rattrapé Gateway API en 2024-2025, mais vérifier les versions sur l'écosystème spécifique.
Apprentissage du modèle 3-rôles. La séparation GatewayClass / Gateway / Route est plus puissante mais demande une discipline d'organisation, en particulier dans les clusters mono-équipe où Ingress suffisait.
Annotations spécifiques pas totalement éliminées. Pour les fonctionnalités les plus avancées (rate limiting global, WAF, custom headers de sécurité), certaines implémentations exposent encore des extensions via annotations. La spec progresse régulièrement (Policy Attachment, etc.).
Cas d'usage où Gateway API gagne
- Plateformes multi-équipes : la séparation Gateway (équipe infra) / Route (équipe app) clarifie les rôles.
- Multi-protocole : gRPC, TCP, UDP, TLS passthrough sans CRDs propriétaires.
- Migration entre controllers : changer d'Envoy Gateway à Istio devient envisageable sans réécrire toutes les routes.
- Environnements multi-cloud : la même spec fonctionne sur EKS, GKE, AKS, on-premise.
Perspectives complémentaires
- Linkerd : service mesh ultra-léger
- Istio et le canary deployment
- Cilium et la sécurité réseau eBPF
- Envoy proxy moderne
- Traefik v2 routing
Sources
- Gateway API (dépôt kubernetes-sigs) spec, conformance
- Documentation officielle, concepts, ressources
- Conformance reports, état du support par implémentation
- Envoy Gateway, implémentation de référence
Conclusion
Gateway API n'est plus une promesse : c'est l'API stable que la communauté Kubernetes recommande pour tout nouveau cluster. Elle remplace Ingress sur tous les axes qui comptent (multi-protocole, séparation des rôles, traffic splitting natif, portabilité entre controllers) sans sacrifier la simplicité pour les cas basiques. La migration depuis Ingress est progressive et bien outillée.


