NGINX Ingress Retirement - Don't Panic, We've Got You Covered
At KubeCon NA 2025, the Kubernetes community faced a significant announcement: the ingress-nginx controller officially entered retirement by March 2026. Adding to the uncertainty, its designated successor, inGate, also announced its retirement. What's been brewing in the Kubernetes ecosystem has now become reality: migrations are inevitable. The good news? There's a pragmatic, well-supported path forward.
No, Ingress Isn’t Dead — Just the Old Default Controller
First things first: how bad is it? What's being retired is ingress-nginx, the widely-adopted Ingress controller implementation. What's not deprecated? The Ingress resource itself. If you're already running an alternative Ingress controller, you're not under immediate pressure to migrate. However, the modernization path outlined here still applies and offers benefits worth considering.
Traefik 3.6: Your Zero-Drama Drop-In Replacement
Since the release of Traefik Proxy v3.5, it includes a game-changing capability: an nginx provider that understands traditional Ingress resources and their annotations. This achieves a simple but powerful goal - providing a drop-in replacement for most scenarios while enabling you to progressively migrate to modern standards like Gateway API at your own pace. We demystified the Kubernetes Gateway API last year, so if you need a refresher, you can check it out here.
To deploy Traefik with the necessary capabilities, we need to enable two key features:
- a) Kubernetes Ingress NGINX compatibility
- b) Gateway API support
To do so, we can easily leverage helm if Traefik is not already installed. Be aware, insecure and debug settings are not suited for production.
helm upgrade --install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
--version ~v37.3.0 \
--set providers.kubernetesGateway.enabled=true \
--set 'additionalArguments[0]=--providers.kubernetesingressnginx' \
--set 'additionalArguments[1]=--log.level=DEBUG' \
--set 'additionalArguments[2]=--api.insecure=true' \
--set 'additionalArguments[3]=--experimental.KubernetesIngressNGINX=true' \
--wait
To verify everything is running correctly, check the Traefik pods and gateway:
kubectl get pods -n traefik
kubectl get gateways -n traefik
NAME READY STATUS RESTARTS AGE
traefik-c4845cb54-rk9w8 1/1 Running 0 82m
NAME CLASS ADDRESS PROGRAMMED AGE
traefik-gateway traefik 3.64.6.226 True 82m
Stopgap: Keep Using Annotations for Most Use Cases
With Traefik's nginx provider capability, you can use it as a stopgap solution to quickly replace nginx-ingress. Traefik supports the most common nginx annotations out of the box, allowing for minimal changes to your existing configurations. Consider this example Ingress resource with basic authentication:
1apiVersion: networking.k8s.io/v1 2kind: Ingress 3metadata: 4 name: ingress-nginx 5 namespace: default 6 annotations: 7 # BASIC Authentication 8 nginx.ingress.kubernetes.io/auth-type: "basic" 9 nginx.ingress.kubernetes.io/auth-secret-type: "auth-file" 10 nginx.ingress.kubernetes.io/auth-secret: "default/basic-auth" 11 nginx.ingress.kubernetes.io/auth-realm: "Authentication Required" 12spec: 13 ingressClassName: traefik 14 rules: 15 - host: whoami.localhost 16 http: 17 paths: 18 - path: / 19 pathType: Prefix 20 backend: 21 service: 22 name: whoami 23 port: 24 number: 80 25--- 26kind: Secret 27apiVersion: v1 28metadata: 29 name: basic-auth 30 namespace: default 31type: Opaque 32data: 33 # user:password 34 auth: dXNlcjp7U0hBfVc2cGg1TW01UHo4R2dpVUxiUGd6RzM3bWo5Zz0=
Traefik's nginx provider automatically interprets these nginx annotations and translates them into its internal structure of routers, services, and middlewares - no manual conversion required.
Step 2: Move to Gateway API, On Your Timeline
While Traefik’s compatibility layer buys you time in the most common cases, the industry’s future is already clear: Gateway API. When you're need or are ready to migrate, TAG Network has your back with a tool built for exactly this transition
https://github.com/kubernetes-sigs/ingress2gateway.
It scans your cluster (or files) and converts Ingress resources into Gateway API–native HTTPRoute objects:
./ingress2gateway print --providers=ingress-nginx
You instantly get clean, standards-based config without no guesswork. Some annotations (like basic auth) don’t yet exist in Gateway API core, but Traefik fills the gap through ExtensionRef, letting you plug in Traefik middlewares seamlessly.
Adding Basic Authentication
What's missing from this generated HTTPRoute is basic authentication, since it's not yet part of the Gateway API core specification. Fortunately, Traefik fills the gap through ExtensionRef, letting you plug in Traefik middlewares seamlessly.
First, create a Middleware resource that references your existing secret:
1apiVersion: traefik.io/v1alpha1 2kind: Middleware 3metadata: 4 name: test-auth 5 namespace: traefik 6spec: 7 basicAuth: 8 secret: basic-auth
Then, attach it to your HTTPRoute using an extension filter:
1filters: 2- type: ExtensionRef 3 extensionRef: 4 group: traefik.io 5 kind: Middleware 6 name: test-auth
Finalizing the HTTPRoute
To complete the migration, make three adjustments to the generated HTTPRoute:
- Change the
parentRefto reference the Traefik Gateway: - Hook in the created Middleware
- Deploy the HTTPRoute in the Traefik namespace
Here's the final HTTPRoute configuration:
1apiVersion: gateway.networking.k8s.io/v1 2kind: HTTPRoute 3metadata: 4 annotations: 5 gateway.networking.k8s.io/generator: ingress2gateway-0.4.0 6 name: ingress-nginx-whoami-localhost 7 namespace: traefik 8spec: 9 hostnames: 10 - whoami.localhost 11 parentRefs: 12 - name: traefik-gateway 13 rules: 14 - matches: 15 - path: 16 type: PathPrefix 17 value: / 18 filters: 19 - type: ExtensionRef 20 extensionRef: 21 group: traefik.io 22 kind: Middleware 23 name: test-auth 24 backendRefs: 25 - name: whoami 26 port: 80
If all went well, a simple curl can be used to validate functionality
curl -H "Host: whoami.localhost" http://3.64.6.226:8008
401 Unauthorized
curl -H "Host: whoami.localhost" -u user:password http://3.64.6.226
Hostname: whoami-5fd778ccbc-v6wqn
IP: 127.0.0.1
IP: ::1
IP: 10.200.0.218
IP: fe80::78e8:77ff:fe5f:1f4b
RemoteAddr: 10.200.1.190:56594
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
Authorization: Basic dXNlcjpwYXNzd29yZA==
X-Forwarded-For: 10.200.0.177
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-c4845cb54-rk9w8
X-Real-Ip: 10.200.0.177
Conclussion
The two-step migration path: from nginx-ingress to Traefik's nginx provider, then progressively to Gateway API provides a pragmatic approach that balances immediate needs with long-term sustainability. You can migrate at your own pace, testing and validating each step before moving forward, all while maintaining production stability.
With Gateway API now established as your foundation, you can leverage its powerful filter capabilities for advanced use cases such as HTTP request/response modification, header manipulation, and URL rewriting. More importantly, you're now aligned with the Kubernetes community's long-term vision for ingress traffic management - a vendor-neutral, expressive, and extensible API that will continue to evolve and improve.
More articles
fromManuel Zapf
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Blog author
Manuel Zapf
Solution Architect
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.