On this page 9 sections
If you’re running ingress-nginx in production, here is where things stand: the project reached end of life on March 26, 2026. Releases, bug fixes and CVE patches have stopped, and the repos are going read-only.
The Helm charts and images stay published, so your cluster won’t suddenly break. But the next time a serious vulnerability lands, nobody upstream is going to fix it.
SIG Network estimates this affects around 50% of cloud-native environments. If your team is one of them, the open questions are what to migrate to, how, and how fast.
This post covers why ingress-nginx was retired, what Gateway API fixes, how to use the new ingress2gateway 1.0 tool, which controller to pick, and the migration gotcha that has bitten several teams already.
Why ingress-nginx was retired
The official statement is worth reading in full. The short version is that ingress-nginx had one or two maintainers doing the work on nights and weekends, and the project’s flexibility had become a liability.
The clearest example is the nginx.ingress.kubernetes.io/configuration-snippet annotation, which let any user with permission to create an Ingress object inject arbitrary NGINX config into the data plane. That was useful in 2018. By 2024 it was the source of repeated CVEs that allowed attackers to read service-account tokens off the controller.
The Kubernetes Steering and Security Response Committees concluded that “it is no longer reasonable or even possible to continue maintaining the tool even if resources did materialize”.
Two things to keep straight:
- The Ingress API itself is still supported; only the ingress-nginx controller is retired. If you switch to a different Ingress controller (HAProxy, F5 NGINX, AWS Load Balancer Controller), your existing
Ingressresources still work. - Existing deployments will keep running. Fixes have stopped shipping, so you have time to plan, though not forever.
What Gateway API actually fixes
Gateway API has been GA since 2023 and is the official successor to the Ingress spec. If you’ve only ever lived in Ingress-land, the headline differences are worth understanding before you pick a controller.
First-class fields instead of annotation soup
The original Ingress spec under-specified almost every interesting feature: traffic splitting, header manipulation, timeouts, retries, rewrites. Vendors filled the gaps with controller-specific annotations, so switching from nginx to Traefik meant rewriting every annotation. Gateway API defines first-class fields for these things in the spec.
Role-oriented resources
Gateway API splits ingress into three resources:
GatewayClass: cluster-wide, owned by the platform team. Defines which controller implementation handles a class of gateways.Gateway: namespace-scoped, owned by network operators. Defines listeners, certs, and which routes can attach.HTTPRoute/TCPRoute/GRPCRoute: owned by app developers. Defines actual routing logic.
With Ingress, every developer with Ingress create permission could touch the listener config, the TLS cert and the load balancer. With Gateway API, the platform team owns the gateway, and developers attach routes to it through ReferenceGrant, so RBAC maps to how teams actually work.
Cross-namespace routing
A HTTPRoute in the frontend namespace can target a service in the backend namespace, gated by a ReferenceGrant. With Ingress, this required either putting Ingress objects in the wrong namespace or running an ExternalName shim.
Traffic splitting and weighted routing as first-class features
Canary deploys, blue-green and header-based splits use the weight and matches fields, without annotations or controller-specific CRDs.
ingress2gateway 1.0 makes the translation tractable
The Kubernetes networking team released ingress2gateway 1.0 on March 20, 2026, six days before the ingress-nginx EOL date. This is the tool you want.
It translates your existing Ingress manifests into Gateway API resources, preserving behavior where it can and warning you where it can’t. The 1.0 release expanded support from 3 to over 30 ingress-nginx annotations, including CORS, backend TLS, regex matching, path rewrite, body size limits, and timeouts.
It also added integration tests that spin up real ingress-nginx and Gateway API controllers, to verify the translated config behaves the same way at runtime as well as on paper.
Basic usage:
# Translate a manifest fileingress2gateway print --input-file my-ingress.yaml \ --providers=ingress-nginx > gwapi.yaml
# Translate everything in a namespaceingress2gateway print --namespace prod \ --providers=ingress-nginx > gwapi.yaml
# Translate the whole clusteringress2gateway print --providers=ingress-nginx \ --all-namespaces > gwapi.yamlThe most important step is the one nobody likes: review the output and the warnings carefully. ingress2gateway is a translator that flags what it can’t translate so you can decide what to do by hand. For complex setups (mTLS, custom Lua snippets, weird rewrite chains), expect real engineering work on top of the generated YAML.
Picking a controller
You have real choices here. This summary is based on the gateway-api-bench numbers and the migration tooling each project ships.
Traefik
Lightweight, great DX, a single binary, and compatibility shims for many ingress-nginx annotations. It’s strong for indie teams and small clusters. It loses some throughput at very high connection counts (over 32 concurrent), which is beyond where most teams live.
Envoy Gateway
CNCF, vendor-neutral, with strict Gateway API conformance and built-in OIDC, rate limiting, and OAuth2. It suits teams that want a standards-compliant gateway without service-mesh complexity.
kgateway (formerly Gloo Gateway)
An Envoy data plane with an optimized control plane, and its own fork of ingress2gateway with extra annotation coverage. It has AI-native routing primitives if you’re building LLM apps, and it’s best for high-churn CI/CD environments.
HAProxy Kubernetes Ingress Controller
This one stays on the Ingress spec rather than Gateway API. It’s a reasonable choice if you want to defer the Gateway API migration and just swap the controller.
F5 NGINX Ingress Controller
A different project from ingress-nginx, Apache 2.0, maintained by F5. It’s also Ingress-spec-based, with a familiar config model for teams that don’t want to learn a new resource model.
If your priority is the smallest possible diff to your current setup, F5 NGINX or HAProxy is the path of least resistance. If your priority is a maintained, standards-tracking stack three years from now, Gateway API on Traefik or Envoy Gateway is the better long-term call. Measure your own workload before you let benchmarks decide.
The migration gotcha most teams hit
The sneakiest bug in ingress-to-Gateway-API migrations is in request body handling rather than routing rules.
ingress-nginx buffers request bodies by default before forwarding upstream. Most modern Gateway API controllers (Traefik, Envoy-based) stream request bodies upstream with Transfer-Encoding: chunked, which is a performance win for most apps.
For WSGI apps running under uWSGI or Gunicorn, it’s a silent disaster. WSGI servers expect a Content-Length header and don’t reliably handle chunked transfer encoding, so file uploads arrive as zero-byte files. The controller logs and the app logs both look clean, and your users just can’t upload anything.
If you run any Python WSGI service, any Ruby Rack app on an older server, or any framework that predates ASGI, test file uploads on a staging cutover before you flip production traffic. The fix is usually a controller-side body buffer or a switch to ASGI/Uvicorn/Gunicorn-with-async, and you want to discover the problem on staging.
A learning path
If you want to go from “I read this blog” to “I can defend a Gateway API migration in a design review,” there’s a free 12-lesson hands-on course at devoriales.com that uses Traefik and a real bookstore app on a local k3d cluster.
It covers the resource model, TLS with mkcert and cert-manager, traffic splitting, ReferenceGrant, PDBs and HPAs for the gateway itself, and extending Traefik with custom Go plugins via Yaegi. It takes about 6 to 8 hours, self-paced. The content is open; only progress tracking needs an account.
It’s the most practical hands-on resource we’ve found, and it’s built around the migration story instead of treating Gateway API as a greenfield exercise.
When to stay on Ingress (for now)
A few honest cases where migrating today is the wrong call:
- You’re running F5 NGINX Ingress Controller, HAProxy, or a cloud-managed controller (AWS ALB, GKE Ingress). Your project isn’t being retired, so you can wait until Gateway API gives you a feature you actually want.
- You have one cluster, three services, and ingress-nginx works. Move to a maintained Ingress controller (F5 NGINX is the closest swap) and table the Gateway API migration for next quarter.
- You’re mid-migration on something else (cluster upgrade, mesh rollout, region split). Don’t stack two migrations.
If you’re running ingress-nginx in production with custom snippet annotations, multi-tenant clusters, or compliance requirements (SOC 2, PCI-DSS, HIPAA), the calculus is different. Unpatched CVEs in your data plane will become an audit finding fast.
Where Ownkube fits
A platform layer should absorb this kind of work. When we provision a cluster on your AWS account, ingress is set up on Gateway API from day one, with automatic HTTPS and a ready-to-share URL for every app. You skip configuring Route 53, picking a controller, wiring up cert-manager and translating annotations.
If ingress-nginx EOL is the second migration you’ve had to plan this year, consider handing off the parts of the stack where the answer is the same for everyone.
Related reading
- EKS vs a single-instance cluster on AWS: cost and when to choose
- Kubernetes events disappear after an hour
- Kubernetes cost optimization for startups
If you want a Heroku-style developer experience in your own cloud account, with the ingress and edge story already solved, deploy your first app. Starter is free forever on one AWS instance, and Production is $5 per vCPU plus $1 per GiB RAM per month when you scale. You pay AWS directly for the compute, we run the platform on top, and AWS Activate credits apply to your AWS bill.
Sources: