Kubernetes Prepares for Ingress-NGINX Retirement
Kubernetes has announced the retirement of Ingress-NGINX, effective March 2026. Given its popularity and extensive deployment, this move carries significant implications for many users. Ingress-NGINX isn’t just a simple routing tool; it operates with a host of unexpected defaults and side effects that might already exist within your Kubernetes clusters. The complexities of these configurations demand attention, particularly as users now face the challenge of migrating away from Ingress-NGINX while retaining necessary functionalities. A detailed examination of these behaviors aims to facilitate a conscious migration strategy, helping users understand and decide which features to maintain in their new environments. Notably, this blog compares Ingress-NGINX with the emerging Gateway API, providing insights on how to adapt existing Ingress-NGINX configurations to the Gateway API framework. It's crucial to be aware that a mapping from one to the other may appear straightforward but can inadvertently introduce outages if Ingress-NGINX's peculiarities aren't properly addressed. Here's the thing: if you're familiar with Ingress-NGINX and the Ingress API, you know that it's easy to overlook these nuances. Most code snippets you’ll find usehttpbin as a backend service for illustrative purposes. However, it's crucial to remember that Ingress-NGINX and NGINX Ingress are distinct entities. While both utilize NGINX in their operation, they differ in governance and purpose. Ingress-NGINX is maintained by the Kubernetes community and is on its way out in March 2026, whereas NGINX Ingress belongs to F5, which means future support for users may differ significantly depending on which controller they choose to employ.
Understanding Regex Behavior in Ingress-NGINX
Let’s explore one significant quirk—regex matching within Ingress-NGINX. Take the case where you need to direct all requests to a backend service likehttpbin based solely on paths that consist of three uppercase letters. You might think adding the annotation nginx.ingress.kubernetes.io/use-regex: "true" along with a regex pattern of /[A-Z]{3} would suffice. However, in practice, the regex matches are prefix-based and case-insensitive. What this means is that any incoming request whose path starts with three letters—uppercase or otherwise—will also be routed to httpbin.
Consider this command:
curl -sS -H "Host: regex-match.example.com" http://<your-ingress-ip>/uuid
type of RegularExpression for path matching. However, you must ensure your specific implementation adheres to the expected semantics, as some, like Envoy-based versions, generally perform case-sensitive matches. If you’re not aware of how Ingress-NGINX handles matching, you could inadvertently create an HTTP route that fails in Gateway API, resulting in a frustrating 404 error where Ingress-NGINX would have successfully routed to httpbin.
That said, there are ways to preserve the intended case-insensitive behavior, such as modifying the HTTP route to include either a case-insensitive flag or a revised regex pattern. For example, accommodating both lower and upper case would require a pattern like (?i)/[a-z]{3}.* to ensure compatibility.
In short, as you prepare for this transition away from Ingress-NGINX, be sure to understand these critical distinctions. The unexpected behavior patterns are a common pitfall that could lead to a service outage if not correctly managed in your migration strategy.When you set up the `regex-match-ingress` with the annotation `nginx.ingress.kubernetes.io/use-regex: "true"` for the host `regex-match.example.com`, you might expect strict adherence to casing conventions. Surprisingly, it's not that straightforward. The behavior of the Ingress-NGINX controller allows for regex patterns to operate as case-insensitive prefix matches, leading to surprising results. Consequently, a request made to `/headers` is matched to the existing pattern `/Header`, which can seem counterintuitive at first.
To illustrate, if you pass this request using the command:
curl -sS -H "Host: regex-match.example.com" http://<your-ingress-ip>/headers
You'll get a response containing the request headers, confirming that the routing has successfully hit the `httpbin` backend. This is more significant than it appears since it points to the flexibility—and potential pitfalls—of regex in ingress routing.
In contrast, the newer Gateway API does not take such liberties. Unlike the Ingress setup, it treats matching types like `Exact` and `Prefix` quite literally. If you attempted to mirror the behavior of the Ingress routes using the Gateway API but preserved the typo from earlier, any calls to `/headers` would result in a frustrating 404 Not Found error instead of the expected 200 OK.
Here's a short glimpse of how that misconfiguration might look in a Gateway API context:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: regex-match-route
spec:
hostnames:
- regex-match.example.com
rules:
...
- matches:
- path:
type: Exact
value: "/Header"
backendRefs:
- name: httpbin
port: 8000
Correcting the case sensitivity in your Gateway API routes ensures that the expected behavior mirrors what you’d achieve with Ingress configurations using regex. So, either switch to a regex type with something like `"(?i)/Header"`, or simply fix that typo by changing it to `/headers`. Ultimately, the impact of how these routing configurations are defined can heavily influence the behavior of your applications.