Migrer d'ingress-nginx vers Gateway API : guide 2026

Par Adooniz
Illustration : le trafic quitte une vieille grille rouillée et rejoint une passerelle modulaire moderne faite de nœuds hexagonaux

En bref : le contrôleur communautaire ingress-nginx a été retiré en mars 2026 et son dépôt est en lecture seule depuis le 24 mars 2026. Il route toujours le trafic, mais plus personne ne publie de correctifs de sécurité. Passez à Gateway API (ou à un autre contrôleur Ingress maintenu). Générez un premier jet avec ingress2gateway, puis vérifiez à la main quatre habitudes d'ingress-nginx avant de basculer : regex insensibles à la casse, regex appliquées à tout l'hôte, réécritures qui touchent tous les chemins et redirections automatiques.

Read this article in English

Si vous utilisez ingress-nginx, vous êtes loin d'être seul : la déclaration du Steering Committee de Kubernetes cite une étude de Datadog selon laquelle environ la moitié des environnements cloud native en dépendent. Le travail est le même pour tout le monde : inventaire, choix de la cible, traduction, tests, bascule. Ce guide suit ces étapes dans l'ordre. Chaque commande et chaque version ci-dessous vient de la documentation officielle ou de notre propre labo du 24 octobre 2026 : kind avec Kubernetes v1.37.0, ingress-nginx v1.15.1, Envoy Gateway v1.9.2 et ingress2gateway v1.2.0.

Dernière vérification : 24 octobre 2026. Les versions évoluent vite. Vérifiez les pages de version indiquées dans les sources avant de copier un numéro.

Qu'est-ce qui a été retiré exactement, et qu'est-ce qui fonctionne encore ?

C'est le contrôleur communautaire ingress-nginx (kubernetes/ingress-nginx) qui a été retiré, pas l'API Ingress. Vos objets Ingress restent des ressources Kubernetes valides. Le contrôleur qui les transformait en configuration NGINX ne reçoit plus ni nouvelles versions, ni corrections de bugs, ni correctifs de sécurité.

Le calendrier officiel est court :

Date Événement Source
11 nov. 2025 Annonce du retrait : maintenance « au mieux » jusqu'en mars 2026 Blog Kubernetes
29 janv. 2026 Déclaration commune du Steering Committee et du Security Response Committee : commencer la migration « immédiatement » Blog Kubernetes
27 févr. 2026 Sortie de Gateway API 1.5 (ListenerSet et le filtre CORS de HTTPRoute passent en stable) Blog Kubernetes
19 mars 2026 Dernières versions : contrôleur v1.15.1, v1.14.5, v1.13.9 (chart Helm 4.15.1) GitHub
20 mars 2026 ingress2gateway 1.0 Blog Kubernetes
24 mars 2026 Dépôt archivé, en lecture seule GitHub
nov. 2026 Fin des correctifs critiques de Microsoft pour le NGINX de l'add-on « application routing » d'AKS Microsoft Learn

Trois points sont souvent confondus :

  • Les déploiements existants continuent de fonctionner. Le projet le dit explicitement, et les images comme les charts Helm restent téléchargeables. Rien ne casse à une date donnée. C'est justement pour cela que les comités ont prévenu que vous risquez de ne pas savoir que vous êtes concerné « avant d'avoir été compromis ».
  • Le NGINX Ingress Controller de F5 est un autre produit. Le blog Kubernetes le précise : Ingress-NGINX (communautaire, retiré) et NGINX Ingress (F5, nginx/kubernetes-ingress) utilisent tous deux NGINX mais n'ont rien d'autre en commun. Celui de F5 n'est pas concerné par ce retrait.
  • InGate, le successeur prévu, a lui aussi été abandonné. Il n'existe pas de remplaçant officiel « drop-in ». Tous les chemins passent par une migration.

Suis-je concerné ? Comment trouver ingress-nginx dans mes clusters ?

Lancez la commande fournie par le projet Kubernetes, avec des droits cluster-admin, dans chaque cluster :

kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx

Si un pod apparaît, vous utilisez le contrôleur retiré. Ce label couvre les installations Helm et les manifestes standard, mais pas les forks ni les installations avec des labels personnalisés. Regardez donc aussi les classes et ce que demandent les objets Ingress :

# Quels contrôleurs sont enregistrés ?
kubectl get ingressclass -o custom-columns=NAME:.metadata.name,CONTROLLER:.spec.controller

# Quels Ingress utilisent la classe nginx, et combien d'annotations portent-ils ?
kubectl get ingress -A -o json | jq -r '
  .items[] | select(.spec.ingressClassName=="nginx"
     or .metadata.annotations["kubernetes.io/ingress.class"]=="nginx")
  | "\(.metadata.namespace)/\(.metadata.name)\t\(.metadata.annotations // {} | keys | map(select(startswith("nginx.ingress"))) | length) annotations nginx"'

La valeur de contrôleur k8s.io/ingress-nginx correspond au projet retiré. Celui de F5 s'enregistre sous nginx.org/ingress-controller.

La seconde commande donne aussi une première idée de l'ampleur du chantier. Le nombre d'objets Ingress dit peu de choses. Le nombre d'annotations nginx.ingress.kubernetes.io/* différentes compte beaucoup plus, et configuration-snippet et server-snippet comptent le plus, car aucun outil ne les traduit automatiquement.

Est-ce vraiment risqué de rester quelque temps sur ingress-nginx ?

Oui, et le risque augmente chaque mois : le contrôleur est exposé à Internet et les prochaines CVE ne seront pas corrigées. Ce n'est pas théorique. En mars 2025, le Security Response Committee de Kubernetes décrivait CVE-2025-1974 (« IngressNightmare ») et les failles associées comme des vulnérabilités qui « pourraient permettre facilement à des attaquants de prendre le contrôle de votre cluster ». Elles ont été corrigées parce que le projet était encore maintenu. Les suivantes ne le seront pas.

Si vous ne pouvez pas migrer ce trimestre, réduisez l'exposition en attendant :

  • Assurez-vous d'utiliser la dernière version de votre branche (v1.15.1, v1.14.5 ou v1.13.9).
  • Gardez allow-snippet-annotations à false (la valeur par défaut des versions récentes) et supprimez les annotations snippet devenues inutiles.
  • N'exposez pas le webhook d'admission hors du cluster, et limitez par RBAC qui peut créer des objets Ingress.
  • Placez un WAF ou un load balancer cloud avec limitation de débit devant le contrôleur, pour qu'il ne soit pas votre seule ligne de défense.
  • Fixez une date de migration par écrit. Avec une couche d'entrée qui « marche encore », « plus tard » devient très vite « jamais ».

Certains éditeurs proposent un support étendu payant. Cela peut faire gagner du temps, mais ne change rien au fond : aucun correctif communautaire n'arrivera plus.

Faut-il passer à Gateway API ou simplement changer de contrôleur Ingress ?

Pour la plupart des équipes, Gateway API est la meilleure cible à long terme. Un autre contrôleur Ingress est la sortie la plus rapide à court terme. Le choix dépend du nombre d'annotations spécifiques dont vous dépendez et du temps dont vous disposez.

Gateway API (Envoy Gateway, Istio, Cilium, NGINX Gateway Fabric, kgateway, Traefik…) Autre contrôleur Ingress (Traefik, HAProxy, F5 NGINX…)
Avenir Là où SIG Network ajoute les nouvelles fonctionnalités ; Ingress est figé Fonctionne aujourd'hui ; l'API Ingress n'évolue plus
Effort Réécriture en Gateway + HTTPRoute (assistée par outil) Souvent moindre : on garde les Ingress, on change annotations ou classe
Portabilité Champs standard pour redirections, réécritures, en-têtes, poids, timeouts, CORS Annotations propres à chaque éditeur : même dépendance qu'avant
Organisation L'équipe plateforme gère la Gateway, les équipes applicatives gèrent les routes (compatible RBAC) Un seul objet mélange les deux
Idéal si Vous avez le temps d'une vraie migration et voulez arrêter de traduire des annotations Vous devez quitter ingress-nginx ce mois-ci, ou dépendez de fonctions qu'aucune implémentation Gateway ne propose encore

Un mot sur Traefik : Traefik v3 dispose d'un provider kubernetesIngressNGINX qui lit directement de nombreuses annotations d'ingress-nginx. Sa documentation liste celles qui sont implémentées et signale des comportements par défaut différents (la mise en tampon des requêtes, par exemple). C'est un pont pratique, mais pas une destination finale, puisque les annotations restent non portables.

Sur un cluster managé, regardez d'abord ce que propose le fournisseur. Sur AKS, l'add-on « application routing » de Microsoft repose sur le même contrôleur NGINX, et Microsoft ne fournit que des correctifs critiques jusqu'en novembre 2026. La voie documentée est l'implémentation Gateway API du même add-on, qui peut tourner en parallèle de l'ancienne pour une bascule par DNS.

Quelle implémentation de Gateway API choisir ?

Choisissez celle qui passe les tests de conformité pour les fonctionnalités que vous utilisez et que votre équipe sait exploiter. Connaître déjà le data plane (Envoy ou NGINX) est un critère tout à fait valable pour départager. Le projet Gateway API publie la liste des implémentations et leurs rapports de conformité. Fiez-vous à ces rapports plutôt qu'aux tableaux comparatifs des éditeurs.

Notre méthode pour réduire la liste :

  1. Vous avez déjà un service mesh ou un CNI compatible ? Istio et Cilium implémentent Gateway API. Utiliser ce qui tourne déjà évite un composant de plus.
  2. Vous voulez une passerelle autonome basée sur Envoy ? Envoy Gateway est un sous-projet d'Envoy. ingress2gateway a un « emitter » dédié qui conserve par exemple la taille maximale des requêtes.
  3. Votre équipe connaît bien NGINX ? NGINX Gateway Fabric (v2.8.0 au moment de l'écriture) garde NGINX comme data plane, derrière l'API standard.
  4. Vous êtes sur un cloud avec une implémentation native ? GKE Gateway, AKS application routing (Gateway API) ou AWS Load Balancer Controller sortent le data plane du cluster. ingress2gateway a même un emitter gce.

Pour le labo, nous avons pris Envoy Gateway pour une raison pratique : il s'installe en une commande Helm et apporte ses CRD Gateway API.

À quoi ressemble le modèle Gateway API par rapport à Ingress ?

Un objet Ingress devient (au minimum) une Gateway, qui porte les listeners, ports, noms d'hôte et TLS, plus une ou plusieurs HTTPRoute, qui portent les correspondances, filtres et backends. Une GatewayClass désigne le contrôleur, comme le faisait IngressClass.

Schéma : un objet Ingress correspond à une GatewayClass, une Gateway gérée par l'équipe plateforme et des HTTPRoute gérées par les équipes applicatives
Ingress mélange infrastructure et routage dans un seul objet ; Gateway API les sépare par rôle. Schéma : DevOpsCompass.

Cette séparation est le principal avantage. C'est aussi la principale source de surprises pendant la migration :

  • Le TLS sort de l'objet de l'équipe applicative. La référence au certificat est désormais sur un listener de la Gateway, donc celui qui gère la Gateway gère les certificats. cert-manager le prend en charge : ajoutez l'annotation cert-manager.io/cluster-issuer (ou issuer) sur la Gateway et activez le support Gateway API de cert-manager avec config.gatewayAPI.enabled=true.
  • Le routage entre namespaces devient explicite. Une HTTPRoute du namespace shop ne peut se rattacher à une Gateway du namespace infra que si le champ allowedRoutes du listener l'autorise. Une route qui vise un Service d'un autre namespace exige un ReferenceGrant.
  • Le statut est transparent. kubectl get httproute -o yaml montre les conditions Accepted et ResolvedRefs pour chaque Gateway parente, et vous allez beaucoup vous en servir.

Comment installer les CRD Gateway API et un contrôleur ?

Installez les CRD du canal standard avec un server-side apply (sauf si le chart de votre contrôleur les installe déjà), puis le contrôleur, puis une GatewayClass. La dernière version stable lors de notre vérification était la v1.6.3 (6 octobre 2026). La v1.7.0 en était à sa release candidate 3.

kubectl apply --server-side -f \
  https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.3/standard-install.yaml

Le canal expérimental (experimental-install.yaml) ajoute des ressources et des champs encore susceptibles de changer. La plupart des migrations n'en ont pas besoin.

Envoy Gateway, tel que nous l'avons installé dans le labo :

helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.9.2 \
  -n envoy-gateway-system --create-namespace --wait
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

Un seul composant doit « posséder » les CRD Gateway API. Si le chart de votre contrôleur les installe (c'est le cas d'Envoy Gateway) et que vous appliquez aussi standard-install.yaml d'une autre version, vous aurez deux propriétaires et un risque de décalage de versions. Choisissez un propriétaire par cluster et notez-le.

Comment convertir mes Ingress avec ingress2gateway ?

Lancez ingress2gateway print --providers=ingress-nginx sur un fichier ou un namespace, enregistrez le YAML et traitez les avertissements comme votre liste de tâches. L'outil est un assistant de migration : il ne remplace pas la relecture. La version 1.0 a ajouté la prise en charge de plus de 30 annotations courantes d'ingress-nginx, et la v1.2.0 (7 juillet 2026) est la version actuelle.

Installation avec Homebrew, avec go install ou depuis les binaires publiés (vérifiez toujours la somme de contrôle) :

brew install ingress2gateway
# ou
go install github.com/kubernetes-sigs/ingress2gateway@v1.2.0

Puis pointez-le vers vos manifestes ou votre cluster :

# Depuis des fichiers (notre recommandation : exporter, relire, commiter)
ingress2gateway print --input-file shop.yaml --providers=ingress-nginx > gwapi.yaml

# Depuis un namespace, ou tout le cluster
ingress2gateway print --namespace shop --providers=ingress-nginx > gwapi.yaml
ingress2gateway print --all-namespaces --providers=ingress-nginx > gwapi.yaml

# Ajouter les extensions propres à une implémentation (ex. taille du corps pour Envoy Gateway)
ingress2gateway print --input-file shop.yaml --providers=ingress-nginx --emitter envoy-gateway

Voici l'Ingress que nous lui avons donné. Le schéma est très courant : une API sous /api avec une réécriture à groupes de capture, le site sur /, plus une limite de taille et une limite de débit :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: shop
  namespace: shop
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "20m"
    nginx.ingress.kubernetes.io/limit-rps: "10"
spec:
  ingressClassName: nginx
  tls:
    - hosts: [shop.example.com]
      secretName: shop-tls
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /api(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service: {name: shop-api, port: {number: 8080}}
          - path: /
            pathType: Prefix
            backend:
              service: {name: shop-web, port: {number: 80}}

Et voici les avertissements affichés par ingress2gateway v1.2.0 (raccourcis, texte d'origine en anglais) :

Capture de terminal des avertissements d'ingress2gateway 1.2.0 : limit-rps non pris en charge, regex insensible à la casse, proxy-body-size non appliqué, réécriture avec groupes de capture non prise en charge, normalisation d'URL
Sortie réelle d'ingress2gateway v1.2.0 sur l'Ingress d'exemple (24 oct. 2026). Lignes en double retirées. Capture : DevOpsCompass.

Ce que l'outil a fait, et ce qu'il nous a laissé :

  • Il a créé une Gateway avec un listener HTTP et un listener HTTPS (TLS depuis shop-tls), une HTTPRoute pour le trafic HTTPS et une seconde HTTPRoute qui redirige HTTP vers HTTPS avec un code 308.
  • Il a transformé les deux chemins en expressions régulières insensibles à la casse : (?i)/api(/|$)(.*).* et, plus surprenant, (?i)/.* pour le simple préfixe /. Nous expliquons pourquoi dans la section suivante. Ce n'est pas un bug de l'outil.
  • Il n'a pas traduit la réécriture (Path rewrites with capture group references are not supported), la limite de débit (Unsupported annotation ... limit-rps) ni la taille du corps (Most Gateway API implementations have reasonable body size and buffering defaults).
  • Avec --emitter envoy-gateway, il a en plus généré une BackendTrafficPolicy avec requestBuffer.limit: 20Mi, ce qui conserve la limite de taille sur Envoy Gateway.

L'outil a donc produit la structure (Gateway, routes, redirection, TLS). Ce qu'il nous a laissé, ce sont justement les points qui provoquent des pannes quand personne ne les regarde.

Quels comportements d'ingress-nginx cassent après la migration ?

Quatre comportements piègent presque tout le monde. Les regex d'ingress-nginx sont des correspondances de préfixe insensibles à la casse. use-regex et rewrite-target font passer tous les chemins du même hôte en regex. rewrite-target s'applique aussi à tous les chemins de l'Ingress qui le porte. Et ingress-nginx ajoute des redirections que Gateway API n'ajoute jamais d'elle-même. Le blog Kubernetes documente les premiers (« Five surprising Ingress-NGINX behaviors »). Nous les avons reproduits dans le labo.

Nous avons envoyé les cinq mêmes requêtes à ingress-nginx v1.15.1 et à Envoy Gateway v1.9.2, avec une HTTPRoute nettoyée : PathPrefix /api avec une réécriture ReplacePrefixMatch vers /, et PathPrefix / pour le site. Le backend est go-httpbin, qui renvoie le chemin qu'il a reçu :

Chemin demandé ingress-nginx Envoy Gateway (HTTPRoute nettoyée) Pourquoi
/api/anything/orders 200, le backend reçoit /anything/orders 200, le backend reçoit /anything/orders Identique : la réécriture fonctionne des deux côtés
/API/anything/orders 200 404 Les regex d'ingress-nginx ignorent la casse
/apiv2/anything 200, le site reçoit / 404 renvoyé par le site Retombe sur /, voir ligne suivante
/anything/home 200, mais le site reçoit / 200, le site reçoit /anything/home rewrite-target: /$2 a aussi réécrit le chemin /
/Anything/home 200, le site reçoit / 404 renvoyé par le site Le backend lui-même est sensible à la casse

C'est la quatrième ligne qui nous a surpris. Avec le schéma courant « API + site dans un seul Ingress », ingress-nginx réécrivait toutes les requêtes du site en /, parce que rewrite-target s'applique à tous les chemins de l'Ingress qui porte l'annotation. Une application monopage qui gère ses routes côté client masque complètement le problème. Après la migration, le site reçoit les vrais chemins. C'est plus correct, mais c'est un changement de comportement qu'il faut tester.

Les pièges, et comment les traiter :

Les chemins regex sont des préfixes insensibles à la casse

ingress-nginx compile les chemins regex sans tenir compte de la casse et sans ancrage final : /[A-Z]{3} correspond aussi à /uuid. La plupart des implémentations basées sur Envoy font une correspondance complète et sensible à la casse. ingress2gateway conserve l'ancien comportement avec (?i) et un .* final. Décidez en connaissance de cause : gardez-le là où des clients en dépendent, sinon retirez (?i) et .*, ou mieux, remplacez la regex par PathPrefix ou Exact.

use-regex et rewrite-target s'appliquent à tout l'hôte

Si un seul Ingress de shop.example.com porte use-regex: "true" ou un rewrite-target, ingress-nginx traite tous les chemins de cet hôte, dans tous les Ingress, comme des regex. Un chemin Exact /Header sert alors aussi /headers. Gateway API ne réinterprète jamais Exact ni PathPrefix, donc une faute de frappe qui « marchait » depuis des années se met à renvoyer des 404. Cherchez les vrais chemins dans les logs d'accès avant de faire le ménage.

La barre oblique finale manquante donne un 301

Pour un chemin Prefix ou Exact comme /my-path/, ingress-nginx répond à /my-path par un 301 vers /my-path/. Les implémentations conformes de Gateway API n'ajoutent jamais de redirection. Si des clients en dépendent, ajoutez une règle RequestRedirect explicite.

La normalisation des URL diffère

ingress-nginx normalise //, /./ et /../ avant la correspondance. Gateway API ne standardise pas ce point. Istio, Envoy Gateway et kgateway normalisent . et .. par défaut, mais les détails varient. Si vos backends font des contrôles de sécurité sur les chemins, testez ce point explicitement.

Les snippets n'ont pas d'équivalent

configuration-snippet et server-snippet contiennent de la configuration NGINX brute : rien ne peut les traduire automatiquement. Listez ce que fait chaque snippet (en-têtes, authentification, tampons, more_set_headers) et faites-le correspondre à un filtre, à une politique de votre implémentation ou à l'application elle-même.

Comment réécrire les chemins, rediriger vers HTTPS et fixer des timeouts avec Gateway API ?

Utilisez les filtres standard de HTTPRoute : URLRewrite pour les réécritures, RequestRedirect pour les redirections, RequestHeaderModifier/ResponseHeaderModifier pour les en-têtes, et le champ timeouts pour les délais. Voici la version propre de la route que nous avons testée sur Envoy Gateway :

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: shop
  namespace: shop
spec:
  parentRefs:
    - name: shop-gw
  hostnames: [shop.example.com]
  rules:
    - matches:
        - path: {type: PathPrefix, value: /api}
      filters:
        - type: URLRewrite
          urlRewrite:
            path: {type: ReplacePrefixMatch, replacePrefixMatch: /}
      backendRefs:
        - {name: shop-api, port: 8080}
      timeouts:
        request: 10s
    - matches:
        - path: {type: PathPrefix, value: /}
      backendRefs:
        - {name: shop-web, port: 80}

PathPrefix /api correspond à /api et /api/..., mais pas à /apiv2, car la correspondance de préfixe de Gateway API se fait segment par segment. C'est le comportement que la plupart des gens attendaient en réalité de /api(/|$)(.*).

Les annotations courantes et leur équivalent :

Annotation ingress-nginx Gateway API Remarques
ssl-redirect, force-ssl-redirect Filtre RequestRedirect (scheme https) sur la route du listener HTTP ingress2gateway la génère (308)
rewrite-target (sans groupes de capture) Filtre URLRewrite Avec groupes de capture : réécrire à la main (ReplacePrefixMatch)
use-regex Correspondance RegularExpression Sémantique propre à chaque implémentation
enable-cors, cors-* Filtre CORS Standard depuis Gateway API 1.5
proxy-read-timeout, proxy-send-timeout timeouts.request / timeouts.backendRequest Pas équivalent : les timeouts d'ingress-nginx sont au niveau TCP
canary, canary-weight backendRefs avec weight Canary par en-tête : matches sur l'en-tête
backend-protocol: HTTPS BackendTLSPolicy Vérifier le support de l'implémentation
proxy-body-size Politique de l'implémentation (ex. BackendTrafficPolicy d'Envoy Gateway) Pas de champ standard
limit-rps, limit-connections Politique de l'implémentation Pas de champ standard
auth-url (authentification externe) Politique de l'implémentation (ex. SecurityPolicy d'Envoy Gateway) Pas de champ standard
configuration-snippet, server-snippet Aucun Repenser au cas par cas

Comment basculer le trafic sans interruption ?

Faites tourner la nouvelle Gateway à côté d'ingress-nginx, avec sa propre adresse. Testez-la avec les vrais noms d'hôte, puis déplacez le trafic progressivement par DNS pondéré ou via votre load balancer. Ne supprimez l'ancien contrôleur qu'après une période calme. Les deux contrôleurs cohabitent sans conflit : ingress-nginx ne lit que les Ingress, et le contrôleur Gateway ne lit que les ressources Gateway API.

Schéma d'une bascule sans coupure : ingress-nginx et la nouvelle Gateway tournent en parallèle pendant que le DNS pondéré déplace le trafic de 0 à 10, 50 puis 100 %
Faites tourner les deux contrôleurs en parallèle, puis déplacez le trafic par étapes réversibles. Schéma : DevOpsCompass.

Notre liste, dans l'ordre :

  1. Exportez et commitez les objets Ingress actuels et le ConfigMap d'ingress-nginx. Les réglages globaux du ConfigMap (timeouts, taille du corps, use-forwarded-headers, ssl-protocols) s'oublient facilement, car ils vivent hors des objets Ingress.
  2. Générez, relisez et commitez le YAML Gateway API. Gardez les avertissements d'ingress2gateway dans la description de la pull request, pour que les relecteurs voient ce qui n'a pas été traduit.
  3. Déployez la Gateway et vérifiez son statut : la Gateway doit afficher Programmed=True avec une adresse, et chaque HTTPRoute Accepted=True et ResolvedRefs=True.
kubectl -n shop get gateway shop-gw \
  -o jsonpath='{range .status.conditions[*]}{.type}={.status} ({.reason}){"\n"}{end}'
kubectl -n shop get httproute shop \
  -o jsonpath='{range .status.parents[0].conditions[*]}{.type}={.status} ({.reason}){"\n"}{end}'

Dans kind, notre Gateway affichait Accepted=True mais Programmed=False (AddressNotAssigned), car un cluster kind n'a pas d'implémentation de LoadBalancer. Le routage fonctionnait quand même via un port-forward. Sur un cluster cloud, cette condition doit être à True.

  1. Testez avec le vrai en-tête Host contre la nouvelle adresse, en rejouant les chemins les plus utilisés de vos logs d'accès, pas seulement le cas nominal :
NEW=203.0.113.50   # adresse de la nouvelle Gateway
curl -s -o /dev/null -w "%{http_code}\n" -H "Host: shop.example.com" "http://$NEW/api/health"
curl -sk -o /dev/null -w "%{http_code}\n" --resolve shop.example.com:443:$NEW https://shop.example.com/
  1. Déplacez le trafic progressivement : enregistrements DNS pondérés (baissez le TTL la veille) ou poids sur le load balancer externe. Surveillez les taux de 4xx/5xx, la latence et les logs des backends à chaque palier (10 %, 50 %, 100 %).
  2. Laissez ingress-nginx tourner à vide quelques jours, puis supprimez les objets Ingress et désinstallez le contrôleur et son webhook d'admission.

La bascule est un bon moment pour faire le ménage côté exposition. Une nouvelle Gateway signifie souvent une nouvelle IP publique. Fermez les règles de pare-feu de l'ancienne à la fin, et vérifiez que l'ancien webhook d'admission (ingress-nginx-controller-admission) part bien avec le chart.

Quelles sont les erreurs de migration les plus courantes ?

Faire confiance au YAML généré sans lire les avertissements, oublier le ConfigMap global, et ne tester que les chemins déclarés dans l'Ingress au lieu de ceux que les clients appellent vraiment. Quelques autres :

  • Une course avec le webhook d'admission. Dans notre labo, le kubectl apply de l'Ingress a échoué avec failed calling webhook "validate.nginx.ingress.kubernetes.io" ... connection refused : le contrôleur était « available » quelques secondes avant que son webhook n'écoute. Les pipelines qui installent le contrôleur et appliquent les Ingress d'un seul coup tombent aussi dessus. Réessayez, ou attendez explicitement le point de terminaison du webhook.
  • Deux propriétaires pour les CRD (voir l'avertissement plus haut).
  • Le listener HTTP laissé ouvert. ingress2gateway reproduit ingress-nginx et garde le port 80 avec une redirection. Si vous ne voulez jamais de HTTP en clair, supprimez ce listener et sa route.
  • Supposer que les valeurs par défaut sont identiques. Limites de taille du corps, tampons, timeouts, taille des en-têtes : ce sont des valeurs par défaut de l'implémentation. Notez vos anciennes valeurs et fixez les nouvelles délibérément.
  • Oublier les autres utilisateurs d'ingress-nginx. Les charts Helm d'applications tierces embarquent souvent leur propre Ingress avec des annotations nginx. Passez-les dans helm template et vérifiez.

Un assistant IA peut-il aider pendant la migration ?

Oui pour lire et relire, non pour appliquer. Un assistant est utile pour expliquer un Ingress à 40 annotations, comparer les HTTPRoute générées à l'original ou préparer des commandes curl de test à partir des logs d'accès. Il ne doit pas recevoir d'identifiants capables de modifier le cluster ou le DNS pendant une bascule. Nous détaillons nos garde-fous pour les outils d'IA qui touchent à l'infrastructure dans le guide du serveur MCP Terraform. Les mises à niveau du système des nœuds tombent souvent dans les mêmes fenêtres de maintenance : notre guide de mise à jour d'Ubuntu 24.04 vers 26.04 traite notamment de l'obligation de cgroup v2 pour les hôtes de conteneurs.

Photo de l'arrière d'une baie de serveurs au centre de données du NERSC, avec des serveurs 1U et des câbles Ethernet blancs
Chaque requête finit toujours sur un câble quelque part. Photo : Derrick Coetzee, Wikimedia Commons, CC0 1.0 (recadrée).

FAQ

Mon ingress-nginx va-t-il s'arrêter à une date précise ?

Non. Les déploiements existants continuent de tourner, et les images comme les charts restent disponibles. Ce qui s'est arrêté, c'est la maintenance : plus de versions, plus de corrections, plus de correctifs de sécurité après mars 2026.

L'API Ingress de Kubernetes est-elle dépréciée ?

Non. Ingress reste une API stable (GA), mais elle est figée. Les nouvelles fonctions de gestion du trafic arrivent dans Gateway API. Vous pouvez continuer à utiliser Ingress avec un contrôleur maintenu.

Le NGINX Ingress Controller de F5 est-il concerné ?

Non. C'est un projet distinct (nginx/kubernetes-ingress) avec ses propres mainteneurs. Ses annotations utilisent le préfixe nginx.org/, donc passer à ce contrôleur reste une migration.

Quelle est la dernière version d'ingress-nginx ?

Les dernières versions sont le contrôleur v1.15.1 (chart Helm 4.15.1), v1.14.5 et v1.13.9, toutes publiées le 19 mars 2026. Le dépôt a été archivé le 24 mars 2026.

ingress2gateway convertit-il tout automatiquement ?

Non. Les versions 1.x prennent en charge plus de 30 annotations courantes d'ingress-nginx et signalent les autres. Les snippets, les réécritures avec groupes de capture et les limites de débit demandent un travail manuel, et il faut vérifier la sémantique, comme les regex insensibles à la casse.

Ai-je besoin du canal expérimental de Gateway API ?

En général, non. Gateway, HTTPRoute, GRPCRoute, ReferenceGrant et les filtres courants sont dans le canal standard. N'installez le canal expérimental que pour une fonction précise dont vous avez besoin, en acceptant qu'elle puisse changer.

Comment obtenir des certificats Let's Encrypt avec Gateway API ?

Utilisez cert-manager avec le support Gateway API activé (config.gatewayAPI.enabled=true), puis annotez la Gateway avec cert-manager.io/cluster-issuer. cert-manager crée un Certificate pour chaque listener HTTPS qui a un nom d'hôte et une entrée certificateRefs.

Que doivent faire les utilisateurs d'AKS ?

Microsoft ne fournit pour le NGINX de l'add-on « application routing » que des correctifs de sécurité critiques, jusqu'en novembre 2026. La voie documentée est l'implémentation Gateway API du même add-on, qui peut tourner en parallèle pour une bascule par DNS. Application Gateway for Containers est une autre option.

Sources

Comment nous avons testé : kind v0.33.0 (Kubernetes v1.37.0) sur une VM arm64, contrôleur ingress-nginx v1.15.1 (manifeste officiel pour kind), Envoy Gateway v1.9.2 (Helm), go-httpbin 2.26.0 comme backend, ingress2gateway v1.2.0 (somme de contrôle vérifiée). Les requêtes passaient par kubectl port-forward : le comportement d'un vrai load balancer ne faisait pas partie du test.

Image d'en-tête : Illustration générée avec Google Gemini pour DevOpsCompass.

Commentaires