Kubernetes users have relied on the Ingress API for years as the standard way to route HTTP(S) traffic into a cluster. However, the Ingress API is starting to show its limitations—and that's exactly why the Gateway API has emerged as a more modern and flexible successor.
In this article, we'll explore why migrating makes sense, what changes conceptually, and how common Ingress features map to the Gateway API.
Why Migrate at All?
The Ingress API has three fundamental weaknesses that become apparent very quickly in real-world environments.
1. Limited Functionality
The Ingress API supports only TLS termination and basic content-based routing for HTTP traffic. Need TCP, UDP, or gRPC routing? You're out of luck.
To provide more advanced functionality, Ingress controllers rely heavily on annotations—proprietary extensions that exist outside the actual Kubernetes standard.
The problem is that each implementation (NGINX, Traefik, Envoy, and others) ships with its own set of annotations, which are not necessarily compatible with one another. If you want to switch Ingress controllers, you typically need to:
- Identify all annotations currently in use.
- Find equivalent functionality in the new controller.
- Rebuild the configuration manually.
This makes migrating between implementations difficult—and sometimes nearly impossible.
2. No Real Authorization Model
The classic Ingress model revolves around a single central resource. As a result, there is effectively only one primary role: the person creating the Ingress resource.
That role can simultaneously define routing rules, configure TLS, and in some cases even influence the underlying load-balancing infrastructure.
In small clusters operated by a single team, this isn't usually a problem. But consider the following scenario:
- Team A operates an online shop
- Team B operates an API
- Team C operates a customer portal
- All teams share the same load balancer or Ingress controller
The Ingress model provides no clean separation between infrastructure operators, application administrators, and developers. As a result, developers can potentially create configurations that affect shared infrastructure without any standardized role model governing those permissions.
3. An Unwieldy API Design
Annotations are simple key-value strings stored in the metadata section rather than as structured fields within the relevant part of the specification.
As the number of annotations grows, an Ingress resource quickly becomes difficult to read, maintain, and understand.
The Core Differences
Personas
One of the biggest conceptual improvements introduced by the Gateway API is its clearly defined role model.
Ingress API Personas
With the Ingress API, there is essentially only one explicit persona:
- User: Owner of the Ingress resources
Additionally, there are two implicit personas:
- Infrastructure Provider: Manages a provider-managed Ingress controller
- Cluster Operator/Admin: Manages self-hosted Ingress controllers
These personas only became formally recognized with the later introduction of the IngressClass resource.
Gateway API Personas
The Gateway API introduces a clear separation of responsibilities from the start:
- Application Developer: Defines routing rules for applications
- Application Admin: Defines entry points for external client traffic, including TLS termination
- Cluster Operator: Defines gateway entry points and TLS configuration
- Infrastructure Provider: Provides the GatewayClass and controller implementation
This model aligns much better with organizations where multiple teams share the same load-balancing infrastructure.
Importantly, adopting the Gateway API does not require abandoning self-service workflows. It remains perfectly possible to define a single RBAC role that combines the responsibilities of Developer, Admin, and Operator.
Functionality and Extensibility
The Gateway API covers all features available in Ingress—and adds many capabilities that previously required annotations. As a result, configurations become significantly more portable across implementations.
For features that cannot realistically be standardized—such as authentication, connection timeouts, or health checks—the Gateway API provides three official extension mechanisms.
External References
A Gateway API resource can reference an implementation-specific custom resource. This keeps the standard API lean while still allowing vendors such as Envoy Gateway or Istio to provide advanced features.
HTTPRoute
|
+--> Standard Gateway API fields
|
+--> Vendor-specific extension fields (Custom Resource)
For example, an HTTPRouteFilter can use an extensionRef to reference a vendor-specific JWT authentication resource that is not part of the standard:
filters:
- type: ExtensionRef
extensionRef:
group: gateway.envoyproxy.io
kind: JwtAuthentication
name: company-auth
Custom Implementations
Some features are intentionally left implementation-specific.
A good example is the RegularExpression type of HTTPPathMatch, where behavior depends on the controller implementation. These capabilities fall under the "implementation-specific" or "custom" conformance level.
Policies
For data-plane functionality such as authentication, authorization, rate limiting, WAF rules, or caching, vendors can define their own policy resources.
The Gateway API does not dictate how those resources should be designed, but it does standardize how policies are attached to Gateway API resources. This creates a more consistent user experience across vendors.
The key difference compared to External References is that the policy references the route, not the other way around.
Instead of:
kind: HTTPRoute
spec:
auth:
enabled: true
the Gateway API approach looks like this:
kind: HTTPRoute
metadata:
name: webshop
---
kind: AuthenticationPolicy
spec:
targetRef:
kind: HTTPRoute
name: webshop
Notably, annotations are not considered an official extension mechanism in the Gateway API and are strongly discouraged for implementations.
Feature Mapping: Ingress to Gateway API
| Ingress Concept | Gateway API Equivalent |
|---|---|
| Entry Points | Must be explicitly defined as listeners in a Gateway resource |
| TLS Termination | Defined on the Gateway listener; certificates still reside in Secrets |
| Routing Rules | Path matching maps directly to an HTTPRoute
|
| Default Backend | No direct equivalent; must be defined explicitly as a routing rule using a / prefix |
| IngressClass |
parentRef in the HTTPRoute points to the corresponding Gateway
|
Routing in Detail: Host-Specific vs. Global
A noteworthy difference is how routing rules are associated with hostnames.
With Ingress, each hostname has its own rule block:
spec:
rules:
- host: shop.example.com
http:
paths:
- path: /
backend: shop-service
- host: api.example.com
http:
paths:
- path: /
backend: api-service
With HTTPRoute, routing rules automatically apply to all specified hostnames:
spec:
hostnames:
- shop.example.com
- api.example.com
rules:
- matches:
- path:
value: /
backendRefs:
- name: app
Merging and Conflict Resolution
Ingress never standardized how configurations should be merged or how routing conflicts should be resolved. Each controller handles these situations differently.
The Gateway API, in contrast, explicitly defines rule-merging and conflict-resolution behavior, ensuring consistent behavior across conformant implementations.
What About Annotations?
Because annotations are inherently implementation-specific, their migration depends on both the old Ingress controller and the new Gateway implementation.
Let's take NGINX as an example:
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
These annotations are understood only by the NGINX Ingress Controller. Other controllers either ignore them or provide their own alternatives.
The good news is that many previously annotation-based features are now part of the official standard.
For example, this:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
becomes a standard Gateway API filter:
filters:
- type: RequestRedirect
For features that remain implementation-specific—such as JWT authentication, WAF rules, or advanced Envoy capabilities—you'll need to consult the documentation of the respective Gateway implementation to identify the appropriate extension mechanism.
Implementations and Conformance
The Gateway API defines two implementation profiles:
- Gateway: Designed for north-south traffic
- Mesh: Designed for east-west traffic within a cluster or across cluster sets
Each profile has its own conformance tests.
There are currently three conformance levels:
- Conformant: e.g., Traefik (Controller), Cilium (Controller & Mesh)
- Partially Conformant: e.g., Envoy Gateway (used, among others, by Giant Swarm)
- Stale: e.g., Azure Application Gateway for Containers (Controller)
Automated Migration
Fortunately, migrating doesn't have to start from scratch.
The Kubernetes SIGs project ingress2gateway automatically converts existing Ingress resources into Gateway API resources and can significantly reduce the amount of manual work involved:
https://github.com/kubernetes-sigs/ingress2gateway
Conclusion
The Gateway API addresses the three biggest shortcomings of the Ingress API at once: richer built-in functionality, a clear role model for multi-team Kubernetes environments, and a structured API design that replaces annotation sprawl with well-defined resources and extension mechanisms.
If you're currently struggling with large numbers of implementation-specific annotations or coordinating multiple teams on shared Ingress infrastructure, it's well worth taking a serious look at migrating to the Gateway API—ideally with ingress2gateway as a starting point for the transition.

Top comments (0)