Ingress NGINX retirement turns controller choice into migration work
Maintenance of Ingress NGINX is scheduled to end in March 2026. Migration requires identifying controller-specific behavior as well as choosing another implementation or Gateway API.
A controller can keep forwarding traffic after its maintenance model has become unsustainable. That creates a difficult transition for users because there may be no immediate symptom that forces a change. The process remains available while the source of future fixes is scheduled to disappear.
The November 11 retirement announcement establishes that boundary for Ingress NGINX. Kubernetes SIG Network and the Security Response Committee say best-effort maintenance will continue until March 2026. After that, the project will receive no further releases, bug fixes or security updates. They recommend that users begin migration immediately.
Existing installations are expected to keep functioning, and published charts and images will remain available. The announcement is therefore about maintenance and future response to defects. It does not describe a timed shutdown of running controllers. Those two facts need to remain together when deciding how urgently to schedule a migration.
I value Kubernetes for making workload state independent of any one controller process. That resilience does not make a controller's maintainership replaceable by its continued runtime health. A working routing process still needs people capable of diagnosing and fixing the next problem in its implementation.
Popularity did not provide enough maintainers
The announcement traces Ingress NGINX to an early example implementation that became widely adopted. Its independence from a particular cloud and its broad set of options helped make it useful in many environments. The same breadth increased the implementation and maintenance burden.
SIG Network and the Security Response Committee describe years in which only one or two people performed development in their spare time. They say attempts to find additional support did not make the project sustainable. This is a specific account of maintainership capacity, not an inference that the controller became irrelevant or unused.
The report also identifies changing expectations about security. Snippet annotations that permit arbitrary NGINX configuration once appeared to be useful flexibility. They now create a difficult security obligation because configuration supplied through Kubernetes objects can affect a program with substantial privileges and responsibilities.
That tension is harder to resolve than deleting an optional field. Existing users may depend on the behavior the option provides. Preserving compatibility continues the maintenance burden, while removing the behavior requires users to redesign their configuration. The retirement announcement describes that accumulated technical debt as part of why continuing the project is no longer feasible.
The maintainers had already proposed winding down Ingress NGINX and building InGate with the Gateway API community. The November announcement says InGate did not mature into a replacement and will also be retired. It should therefore not be presented as an available successor that makes migration automatic.
The API and its implementation are separate choices
Ingress is the Kubernetes object through which a user describes routing requirements. An ingress controller interprets those requirements and configures the actual traffic-handling system. Ingress NGINX is one such implementation. Retiring it does not mean every implementation of Ingress is being retired.
The announcement offers two broad directions. Users can move to Gateway API, or they can continue using Ingress through another controller. These paths change different things. Replacing the controller can preserve the basic object kind, while adopting Gateway API changes the configuration model as well.
Preserving the object kind does not prove behavior is portable. The original ingress2gateway introduction explains that Ingress exposes a limited common set of HTTP routing capabilities. Features outside that set often use provider-specific annotations, which are not transferable merely because the surrounding object is still an Ingress.
That makes the existing annotation set part of the migration scope. A replacement may interpret an annotation differently, provide another API for the same purpose, or require an application change. The meaningful inventory is the routing behavior that the controller supplies, including its extensions, rather than a count of Ingress objects alone.
Gateway API separates responsibilities in configuration
Gateway API provides a more explicit separation between infrastructure and application routing. The ingress2gateway introduction describes GatewayClass as the infrastructure-level choice, Gateway as the requested traffic-handling configuration, and route objects as the application's protocol-specific routing rules.
This lets application owners configure how requests reach their Services without necessarily editing the same object used to define the shared gateway. The separation also provides places for extension without putting every behavior into an annotation on one resource.
The migration introduction gives header-based matching and weighted traffic splitting as examples of behavior Gateway API can describe directly. With an Ingress controller, those capabilities often depend on annotations outside the common Ingress contract. Converting such a configuration means identifying the routing intent first, then expressing it through a supported route rule. Copying the annotation text into a new object's metadata would not establish equivalent forwarding behavior. A split also needs to preserve the intended backend identities and proportions, which are application requirements independent of the old annotation's spelling.
The Gateway API 1.0 announcement graduated GatewayClass, Gateway and HTTPRoute to v1. Its stability statement applies to those APIs in the Standard channel. It explicitly keeps an Experimental channel for additional capabilities. A stable Gateway API core does not mean every feature exposed by every gateway implementation has the same compatibility guarantee.
Choosing a gateway therefore still requires matching the implementation to the required behavior. Installing the API objects supplies a configuration vocabulary. A controller must reconcile them into a working traffic path, and its supported capabilities determine which parts of that vocabulary a deployment can use.
I prefer this separation of roles to accumulating more controller-specific annotation conventions. It makes ownership and intended behavior easier to state. It also makes the migration work more visible, since an application route and the infrastructure serving it can be reviewed as separate resources.
Conversion starts a migration without completing it
Ingress2gateway provides tooling to convert Ingress resources into Gateway API resources. Its original announcement describes producing Gateways and HTTPRoutes from the input, then reviewing and validating the generated configuration. This is a way to reduce transcription work, not evidence that all provider-specific behavior has an equivalent translation.
The documented migration sequence keeps the old traffic path while bringing up the new one. Requests against the new gateway establish whether it handles the intended behavior before DNS directs ordinary clients there. The old Ingress configuration is removed after traffic no longer depends on it.
That separation is useful because generating an object and observing traffic through it answer different questions. A syntactically valid route can still select the wrong backend or omit a behavior that the old controller supplied. The data path needs to demonstrate the behavior being migrated, including the controller-specific requirements identified earlier.
DNS cutover is also separate from creating the new resources. Publishing a Gateway object does not move existing clients to its address. The migration needs an explicit change to the entry point clients actually use, followed by evidence that the old entry point no longer carries required traffic.
For an existing deployment, discovery begins by finding the affected implementation. The announcement supplies a label-based Pod query. An explicit context keeps that inspection scoped to the intended cluster.
kubectl --context YOUR_CONTEXT get pods --all-namespaces \
--selector app.kubernetes.io/name=ingress-nginx
The query is a starting point for inventory. A controller installed through a distribution or managed platform may also have an owner responsible for its upgrade path. Identifying that ownership matters because moving application routes and replacing the cluster's controller may be controlled by different parties.
Retained artifacts preserve access without extending support
The project says its repositories will become read-only and remain available for reference. Existing container images and Helm charts will also remain accessible. This preserves the ability to inspect and reproduce an installation, but it does not create a process for publishing a repair after maintenance ends.
That is why the absence of an immediate outage should not postpone the migration decision until a defect appears. The announced deadline concerns the ability to obtain a maintained implementation when a future problem needs one. Starting now allows the behavior of the existing controller to be documented while a supported transition can still be organized.
The choice between another Ingress controller and Gateway API depends on the required configuration and its ownership. In both cases, the concrete deliverable is a replacement traffic path with understood behavior and a maintained controller. Keeping the old artifacts available helps reproduce the previous system, while the new path supplies the implementation that will receive future fixes.