The Ingress Nginx controller is retiring next month, in March 2026. What comes next? I think it should be the Kubernetes Gateway API - and in this post I will explain why.
The classic Ingress resource has served us well for years. Most Kubernetes users know it by heart as the third part of the trio of Deployment, Service and Ingress that is needed to expose an application. And Ingress Nginx is probably the most popular Ingress controller. It is battle tested, has a large community and a couple of additional features hidden in annotations.
The Gateway API offers these and many more features with an elegant architecture and a clear syntax directly in the manifests. This way, we can get direct first-class support for features like canary deployments and OAuth2 authentication.
The Gateway API Resource Model
The Gateway API introduces a clear separation of concerns through three main resource types:
Image source: Kubernetes Gateway API Documentation
- GatewayClass: Defines the type of gateway implementation (e.g., Nginx, Envoy, Istio).
- Gateway: The actual gateway instance that listens on specific ports and protocols.
- Routes (HTTPRoute, TCPRoute, etc.): Define how traffic is routed to services.
This separation means developers don’t need to worry about load balancer configuration, TLS certificates at the gateway level, or infrastructure details. And more importantly, the Routes have a much more powerful syntax than the old Ingress.
Ingress versus HTTPRoute: A Developer’s View
Let’s first look at the basic textbook example of exposing a web application. With the classic Ingress resource, it looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: my-namespace
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 8000
And here’s the equivalent with the Gateway API. One defines an HTTPRoute resource:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app
namespace: my-namespace
spec:
parentRefs:
- name: production-gateway
namespace: platform-team
hostnames:
- myapp.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-app
port: 8000
So far, they look similar. We get the same basic functionality with almost the same number of lines. However, experienced users know that they often needed additional pieces: for authentication, complex load balancing, and other advanced features, we usually needed annotations and sidecar containers. The next examples will show how to do this with the Gateway API.
Canary deployments and advanced routing
With Ingress Nginx, complex routing scenarios like traffic splitting or header-based routing require vendor-specific annotations or multiple Ingress resources. With HTTPRoute, these features are built into the spec.
A useful feature in high-traffic production environments is the ability to gradually roll out new versions. With the Gateway API, traffic splitting is a first-class feature:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-canary
namespace: my-namespace
spec:
parentRefs:
- name: production-gateway
hostnames:
- myapp.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
# Define two backend services with different weights
- name: my-app-v1
port: 8000
weight: 90
- name: my-app-v2
port: 8000
weight: 10
This sends 90% of traffic to version 1 and 10% to version 2. Because this is defined declaratively in a single HTTPRoute resource, it’s easy to manage and version-control. A common workaround in the past involved running 9 replicas of the old version and 1 of the new version behind the same service. This replica-based approach is far less transparent and may need a lot more cluster resources just to handle the traffic.
The traffic flow looks like this:
OAuth2 Authentication with Envoy Gateway
Different Gateway implementations can extend the base Gateway API with additional features.
Envoy Gateway, for example, provides some of its rich capabilities as a separate SecurityPolicy resource.
By adding it to the HTTPRoute, you can enforce OAuth2 authentication, here with claim-based authorization:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: oauth2-with-claims
namespace: my-namespace
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-app
oidc:
provider:
issuer: https://auth.example.com
authorizationEndpoint: https://auth.example.com/oauth2/authorize
tokenEndpoint: https://auth.example.com/oauth2/token
clientID: my-app-client-id
clientSecret:
name: oauth2-client-secret
redirectURL: https://myapp.example.com/oauth2/callback
authorization:
rules:
- action: ALLOW
principal:
jwt:
provider: default
claims:
- name: role
valueType: String
values:
- admin
- developer
This configuration ensures that only users with the role claim set to either admin or developer can access the application.
In the past we solved this in much more complex ways:
- by adding an Envoy sidecar with its complex configuration
- by using a full service mesh (e.g. Istio)
- by adding additional services and deployments (e.g. OAuth2 Proxy)
All of these solutions are solid and there are probably still valid use cases for them. But they are all much more complex and require more resources. And with good implementations, such as Envoy Gateway, you get it out of the box.
Summary
Moving from Ingress Nginx to the Gateway API might seem like extra work, but the benefits are substantial. With the comparison above, we have only scratched the surface of what the Gateway API can do:
- Standardization: The Gateway API is a Kubernetes standard, not a vendor-specific solution
- More expressive routing: Header matching, query parameter routing, traffic splitting, etc. are built-in
- No more annotations: Vendor-specific features are now proper resources, not magic strings
- Portable configurations: HTTPRoute works across different gateway implementations
- Additional protocols: Support for additional protocols such as TCPRoute, UDPRoute or GRPCRoute
- Modularity: The new configuration model enables easy extension via policies for external authentication and other advanced features.
All in all, we get a lot of features that previously required service mesh complexity. The Gateway API gives developers more power with less complexity, and it’s a standard that will be supported by all major vendors.
If you’re still using Ingress, now is the time to explore the Gateway API. Start with simple HTTPRoutes, experiment with traffic splitting, and discover how many of your previous workarounds can be replaced with standard syntax.
The next generation of Ingress is here, and Ingress Nginx can safely enjoy its retirement.
References
- Kubernetes Gateway API Official Documentation
- Ingress Nginx Controller Retirement Announcement
- Envoy Gateway Documentation
- Gateway API Implementations