Ingress vs Gateway API
Kubernetes Ingress has served many years but now K8s recommends using Gateway API over Ingress even though they solve the same problem. Well, Gateway API is the modern successor to Kubernetes Ingress, designed to fix Ingress’s limitations by offering better portability, extensibility, multi-protocol support, and role-based access. We will try to understand what’s the problem with the Ingress and how Gateway API solves them which will help using Gateway API for modern solution and migrating from Ingress to Gateway API for more simplicity and approach towards extensibility.
Ingress is Complex, Limited But Gateway API is Simple, Extensible
Ingress comes with basic features like path based routing, host based routing, TLS termination, etc. In an approach towards extensibility, Ingress provides annotations to support adavnced routing and load balancing features like weight based routing or canary deployment, etc. Annotation “works” but it is not great becasue it key-value string as opposed structured spec which is in every K8s object. Sometimes annotations require JSON string which is awkward. Annotations are applied at the top. What should have been a simple spec, annotations look like very complex structure which are not portable across Ingress Controllers giving more than enough reason to retire it because DevOps Engineer has to learn different annotation for the same task when a team decided to swith to different controller for whatever reason.
In a reply, what Gateway API says is “instead of using annotations use directly relevant part of spec”, yep problem solved just like that:
spec:
rules:
- backendRefs:
- name: svc-v1
port: 8080
weight: 90
- name: svc-v2
port: 8080
weight: 10No annotations, no key-value string, no complex JSON, just spec and it’s portable too. However, it doesn’t mean every feature is portable. Some features might vary across Gateway API controllers because Kubernetes always has been (and it should be like that) open to custom implementations.
In an approach towards extensibility, K8s supports external references (other than service) for Gateway, custom implementations, Gateway policies, etc. which can be read more here. K8s realized how awkward are annotations and says:
The extension points do not include annotations on Gateway API resources. This approach is strongly discouraged for implementations of the API.
Ingress — Unclear Responsibilities, Gateway API — Explicit Responsibilities
You Might Think Responsibility Problem Is Already Solved
To remove responsibility ambiguity in organizations where different roles exist, such as platform engineers, cluster admins, and DevOps engineers, Ingress introduced IngressClass. It provides a separation of responsibilities between the person managing the Ingress controller and the person defining application routing.
For example, consider a cluster where the platform team installs NGINX Ingress Controller and application teams create Ingress resources.
- Platform team: Installs and manages the controller, defines the available
IngressClassresources, and decides which class applications should use. - Application team / DevOps engineer: Creates
Ingressresources to define hostnames, paths, backend services, and sometimes TLS configuration.
That is already a workable division of responsibilities. However, IngressClass mainly identifies which controller should implement an Ingress. It does not, by itself, define a complete permission and ownership model for the traffic entry points.
What Does Gateway API Improve, Then?
The key difference is where the API draws the boundary between application routing and shared infrastructure configuration.
| Responsibility | Ingress API | Gateway API |
|---|---|---|
| Select controller implementation | IngressClass | GatewayClass |
| Define traffic entry points and listeners | Often configured through controller settings and Ingress resources | Gateway |
| Configure application routing | Ingress | HTTPRoute, GRPCRoute |
| Control which applications can use shared entry points | Mostly external policy/RBAC and controller-specific behavior | Built-in route attachment controls, including namespace and listener restrictions |
The distinction matters because IngressClass identifies the controller that handles an Ingress, but it doesn’t provide a standard resource for an administrator to define a shared entry point with listeners, TLS settings, and explicit rules governing which application routes can attach to it. Gateway API models those concerns through separate resources.
For example, a platform team can create a Gateway that owns HTTPS termination, while application teams create HTTPRoute resources that attach to it. The Gateway’s listeners can restrict which namespaces are allowed to attach routes, and RBAC can control who may modify each resource. For simplicity, K8s segregates role based responsibility as such in the following image but never assume to be similar across all teams:
