Gateway API Shifts Cluster Networking: An Ownership Model for the Edge
Ingress put one object, and a pile of controller-specific annotations, between every team and the cluster edge. Gateway API splits that object into resources owned by different people, with explicit consent wherever a namespace boundary is crossed. This post is for the people designing the platform: what changes in ownership, which decisions you have to make up front, and how to avoid rebuilding the old free-for-all on a new API.
If you want the hands-on version (mapping Ingress fields to HTTPRoute, running ingress2gateway, shifting traffic and rolling back), read the companion post, Gateway API replaces Ingress: a migration playbook. This one stays at the architecture level.
Why this is on your roadmap now
Three facts have moved Gateway API from "interesting" to "planned work" for most platform teams.
- Ingress is frozen. The Kubernetes documentation now recommends Gateway instead of Ingress and states that the Ingress API "is no longer being developed, and will have no further changes or updates made to it". Ingress stays generally available and there are no plans to remove it [1].
- Ingress NGINX is retired. SIG Network and the Security Response Committee announced that maintenance would stop in March 2026, after which there would be no further releases, bug fixes or security patches [2]. The
kubernetes/ingress-nginxrepository is now archived on GitHub. Existing deployments keep running, which is exactly why unpatched controllers linger. - Gateway API has filled the gaps. Version 1.5 promoted ListenerSet, TLSRoute, ReferenceGrant, the HTTPRoute CORS filter and client certificate validation to the Standard (GA) channel [5]. Version 1.7.0, released on 29 October 2026, added HTTPRoute retries to Standard [6].
A correction: this is not about kube-proxy
The earlier version of this post framed Gateway API as the "end of kube-proxy". That was wrong. kube-proxy implements the virtual IP behind ClusterIP, NodePort and LoadBalancer Services, using iptables, IPVS or nftables rules on each node [8]. Gateway API describes L4 and L7 routing into and between services [3]. Replacing kube-proxy (for example with an eBPF datapath) is a separate decision with its own risks, and you can adopt Gateway API with or without it.
From one object to an ownership model
Ingress gives you one namespaced object that carries the hostname, the TLS certificate reference, the paths and the backends, plus whatever annotations your controller understands. The 2023 Kubernetes announcement of ingress2gateway put the problem plainly: Ingress "can only accommodate basic HTTP routing", which pushes traffic splitting, header matching and similar features into "provider-specific, non-transferable annotations" [9]. In practice, anyone who can create an Ingress can influence shared proxy behaviour.
Gateway API breaks that into layers, and the project's documentation describes them in terms of three personas [3]:
- Infrastructure provider ("Ian"): runs shared infrastructure for many tenants. Owns
GatewayClass, which names the controller that implements gateways. - Cluster operator ("Chihiro"): runs a cluster and its policies for many users. Owns
Gatewayobjects, which declare listeners: ports, protocols, hostnames and TLS. - Application developer ("Ana"): owns
HTTPRoute,GRPCRouteand other route types, which match requests and send them to Services.
Two design choices make this more than a diagram on a slide.
Attachment is a two-way handshake
A route names the Gateway it wants with parentRefs. That alone does nothing: the Gateway's listener must also allow routes from the route's namespace through allowedRoutes. The project's security model describes this as a deliberate "handshake between namespaces" whenever a boundary is crossed [4]. The default is Same, meaning only routes in the Gateway's own namespace can attach [10].
Cross-namespace references need a grant
When a Gateway in infra needs a certificate Secret stored in certs, or a route needs a Service in another namespace, the owner of the target namespace must publish a ReferenceGrant. In the security model's words, ReferenceGrant "allows resource owners to make their resources available to Gateway API resources in other namespaces" [4]. Ingress had no equivalent; it simply could not reference across namespaces.
# Owned by the cluster operator: a shared Gateway that admits
# routes only from namespaces labelled for it.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: shared-gw
namespace: infra
spec:
gatewayClassName: example-class
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard-example-com
namespace: certs
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access/shared-gw: "true"
---
# Owned by whoever owns the certs namespace: lets Gateways in
# infra read Secrets here. Without it the listener will not program.
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-infra-gateways
namespace: certs
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: infra
to:
- group: ""
kind: Secret
That namespace label is now a security control. Decide who may apply it, and enforce that with RBAC or admission policy, otherwise any team that can label its own namespace can attach to your shared edge.
What changes for platform teams
| Concern | With Ingress | With Gateway API |
|---|---|---|
| Who controls listeners and TLS | Whoever writes the Ingress (TLS block per object) | Gateway owner; TLS is a property of the listener |
| Advanced routing (weights, headers, mirroring) | Controller-specific annotations | Standard HTTPRoute fields [9] |
| Cross-namespace access | Not possible | Explicit: allowedRoutes plus ReferenceGrant [4] |
| RBAC granularity | One resource type for everyone | Separate resources per persona [4] |
| Feedback to app teams | Controller logs and events, varies by controller | Standard status conditions on Gateways and routes |
| API evolution | Frozen [1] | Release train with Standard and Experimental channels [5] |
The security model's simple three-tier RBAC split is a sensible starting point [4]:
| Persona | GatewayClass | Gateway | Routes |
|---|---|---|---|
| Infrastructure provider | Write | Write | Write |
| Cluster operator | No | Write | Write |
| Application developer | No | No | Write |
Status conditions deserve more attention than they usually get. A route reports Accepted and ResolvedRefs per parent Gateway, with reasons such as NotAllowedByListeners, NoMatchingListenerHostname, RefNotPermitted and BackendNotFound defined in the API itself [10]. That gives application teams a self-service answer to "why is my route not live?" without access to the controller's logs. Build your developer documentation and alerts around those conditions.
Choosing a gateway topology
Before v1.5, a shared Gateway forced every team that needed its own hostname or certificate to ask the platform team to edit the same object. ListenerSet removes that bottleneck. The v1.5 release notes say it lets listeners "be defined independently and then merged onto a target Gateway", and it also raises the practical ceiling beyond 64 listeners on one Gateway [5]. The Gateway owner still decides which namespaces may attach ListenerSets, through allowedListeners, which defaults to None in the API, so sharing is opt-in [10].
| Topology | Good fit | Watch out for |
|---|---|---|
| Shared Gateway | Many small services, one domain, a small platform team | The platform team becomes a queue for listener changes; one bad config affects everyone |
| Gateway per team or tier | Regulated or high-traffic workloads, separate change windows | Load balancer and certificate sprawl; inconsistent policies |
| Shared Gateway + ListenerSets | Many teams with their own hostnames on shared infrastructure | Your implementation must support ListenerSet; check its conformance report |
A platform decision playbook
These are the decisions to make, in order, before the first team migrates. Each one is cheaper to settle now than to retrofit.
- Name the CRD owner. Gateway API ships as CRDs, which are cluster-scoped and privileged. The project's guidance is that "either a cluster admin or cluster provider should be responsible for managing the CRDs" [7]. Pin a release (v1.7.0 is current [6]) and decide how you will upgrade it; the guide recommends one minor version at a time and warns against downgrades [7].
- Stay on the Standard channel by default. Experimental resources can change or disappear without deprecation, and upgrades may need the CRDs removing and reinstalling [7]. Allow Experimental features only per cluster, with a named owner.
- Choose implementations from conformance reports, not marketing. The implementations page separates conformant from partially conformant controllers and links each to a published conformance report [11]. Check the extended features you actually need, such as mirroring, retries or ListenerSet.
- Pick a topology per tier. Use the table above. Write down which workloads get dedicated Gateways and why.
- Define attachment policy. Decide the
allowedRoutesandallowedListenersrules for each Gateway, the namespace labels that grant access, and who may set them. - Map personas to RBAC. Start with the three-tier table. Application teams get write on routes in their namespaces and read on Gateways so they can see status.
- Set an extension policy. Implementations add their own policy resources for things the standard does not cover, such as rate limits or body size. Decide which ones you allow, because each one reduces portability.
- Make status observable. Alert when a route is not
Acceptedor notResolvedRefs, and when a Gateway is notProgrammed. - Only then migrate. Follow the step-by-step process in the migration playbook.
East-west traffic and service mesh
Gateway API is not only for the edge. Its GAMMA work, in the Standard channel since v1.1, lets mesh implementations use the same route types for service-to-service traffic: routes attach directly to a Service instead of to a Gateway [3]. If you run or plan a mesh, ask your mesh vendor whether it is conformant for GAMMA, so application teams learn one routing API for both directions.
Common mistakes
- Treating it as a syntax upgrade. Converting every Ingress one-to-one, with
allowedRoutes.namespaces.from: Allon a shared Gateway, recreates the old free-for-all with more objects. - Letting several tools install the CRDs. Two controllers that each bundle a different Gateway API version will fight. Implementations must never overwrite newer CRDs or CRDs from another channel [7]; make sure yours is configured not to manage them at all if the platform team does.
- Ignoring status in developer workflows. If developers cannot read route conditions, every misattached route becomes a ticket for the platform team.
- Leaning on implementation policies too early. Each custom policy is an annotation by another name. Check whether the standard covers it first.
- Leaving retired controllers in place. An archived Ingress NGINX will receive no security fixes [2]. Find every instance, including in clusters nobody thinks about.
Platform readiness checklist
- A named owner and pinned version for the Gateway API CRDs, Standard channel only.
- An approved implementation list, each with a conformance report you have read.
- Written topology decision per workload tier.
- Attachment policy: allowedRoutes and allowedListeners per Gateway, with controlled namespace labels.
- RBAC roles for each persona, including read access to Gateways for app teams.
- ReferenceGrant ownership rules for certificate and shared-service namespaces.
- Alerts on Gateway
Programmedand routeAccepted/ResolvedRefs. - An inventory of every Ingress controller, and a retirement date for each.
What to do this week
- Run
kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginxin every cluster, the check the Kubernetes project suggests [2], and list what you find. - Run
kubectl get crd | grep gateway.networking.k8s.ioto see whether Gateway API CRDs are already installed, and by whom. - Write a one-page decision record naming the CRD owner, the channel and the target version.
- Draft the RBAC roles for the three personas and review them with one application team.
- Pick one low-risk service and agree the topology it will use, ready for the migration playbook.
If you would like help designing the ownership model, or a team to run the edge for you once it is in place, our SysOps 24/7 service covers Kubernetes platform operations.
References
- Ingress (concept documentation, note on the frozen API), Kubernetes documentation.
- Ingress NGINX Retirement: What You Need to Know, Kubernetes blog, 11 November 2025.
- Gateway API overview: design principles, resource model and personas, Kubernetes SIG Network.
- Gateway API security model, Kubernetes SIG Network.
- Gateway API v1.5: Moving features to Stable, Kubernetes blog, 21 April 2026.
- Gateway API v1.7.0 release notes, GitHub, 29 October 2026.
- CRD management, Gateway API guides.
- Virtual IPs and service proxies, Kubernetes documentation.
- Introducing ingress2gateway; Simplifying Upgrades to Gateway API, Kubernetes blog, 25 October 2023.
- Gateway API v1 type definitions (gateway_types.go, shared_types.go), v1.7.0, GitHub.
- Gateway API implementations and conformance, Kubernetes SIG Network.