From Kubernetes resources to an entry point
Suppose an application team needs to publish shop.example.com without owning the cluster’s load balancer or TLS infrastructure. Gateway API splits that work across resources: a GatewayClass selects the implementation, a Gateway requests listeners and addresses, and an HTTPRoute attaches the application’s matching and backend rules. A controller turns those declarations into a proxy, cloud load balancer, routes, certificates, or other implementation-specific state. Gateway API introduction ↗
Gateway API separates infrastructure from application routes
The infrastructure provider supplies a class, the cluster operator opens listeners, and application teams attach routes within those limits.
Gateway API defines Kubernetes resources; it does not proxy packets by itself. A compatible controller must interpret those resources and program a data plane. Without that implementation, creating a Gateway or Route does not produce a working traffic path.
The resource ownership model
| Resource | Scope | Typical owner | Responsibility |
|---|---|---|---|
| GatewayClass | Cluster | Infrastructure provider | Names the controller and class-wide implementation parameters. |
| Gateway | Namespaced | Cluster operator | Requests addresses, listeners, protocols, TLS, and route attachment policy. |
| HTTPRoute / GRPCRoute | Namespaced | Application team | Matches requests and selects weighted or filtered backends. |
| ReferenceGrant | Namespaced with the referenced object | Resource owner | Permits supported cross-namespace references to that namespace. |
| Service | Namespaced | Application team | Supplies the backend abstraction and eligible endpoints. |
This split lets an infrastructure team offer shared or dedicated entry points while application teams manage their own routes. Kubernetes RBAC controls who may edit each resource, and attachment rules determine which Routes a listener will accept. An application team can therefore publish its route without gaining permission to change the listener, certificate, or another team’s route.
GatewayClass and controller acceptance
A GatewayClass contains a domain-prefixed controllerName. An implementation watches matching classes and reports whether it accepts them. A cluster can offer classes such as public, private, regional, or provider-specific, but the names have no portable meaning unless the operator documents their parameters and behavior. GatewayClass overview ↗
- 01Controller accepts classGatewayClass status identifies a responsible implementation.
- 02Gateway requests listenersAddress, port, protocol, hostname, and TLS intent are declared.
- 03Routes attachParent references and listener policy must agree.
- 04Controller programs data planeProgrammed status reports whether infrastructure is ready.
If no controller accepts the GatewayClass, no amount of Route debugging will produce traffic. Check GatewayClass Accepted first, then the Gateway’s Accepted and Programmed conditions, and only then inspect listener and Route status.
Listeners define the entry boundary
A Gateway listener binds a port and protocol and can constrain hostname, TLS configuration, and which Routes may attach. Multiple listeners can share a Gateway while maintaining separate policies—for example, HTTP redirect and HTTPS termination, or public and internal hostnames where the implementation supports the addresses.
allowedRoutes controls namespaces and Route kinds permitted to attach. Its default namespace behavior and explicit selectors matter. A Route that names the Gateway is not necessarily attached; the listener must also allow it.
Listener hostname and Route hostname intersect. A Route for shop.example.com cannot become effective on a listener that only admits api.example.com. Wildcards and implementation conformance should be validated through status, not inferred from object creation.
Route attachment is a handshake
A Route names its requested Gateway or other supported parent in parentRefs. The listener independently controls which namespaces and Route kinds it accepts. The controller evaluates both sides and writes status for each parent, so a Route in an application namespace cannot attach itself to shared infrastructure without the listener’s permission.
One does not imply the other. `allowedRoutes` governs attachment to the listener; `ReferenceGrant` governs a supported cross-namespace object reference.
| Condition or reason | Question it answers | Likely investigation |
|---|---|---|
| Accepted | Did the parent accept this Route? | parentRefs, allowedRoutes, hostname intersection, Route kind |
| ResolvedRefs | Do backend and certificate references resolve and have permission? | Names, namespaces, ports, ReferenceGrant |
| Programmed | Was usable data-plane configuration produced? | Controller, provider API, address, listener, implementation health |
| Conflicted | Does this listener or Route conflict with another declaration? | Ports, protocols, hostnames, precedence, implementation rules |
kubectl apply confirms that the API accepted the object. It does not confirm that a listener accepted the Route, its references resolved, or the controller programmed a usable data plane. Those results appear in status.
HTTPRoute matching and precedence
An HTTPRoute can match hostnames, paths, headers, query parameters, or methods and can apply filters such as redirects, rewrites, header modification, mirroring, or extension behavior. Support levels vary, so check the implementation’s conformance report.
More specific matching wins according to Gateway API precedence rules; ties have defined comparisons and ultimately deterministic conflict handling. Avoid relying on resource creation order. Keep routes non-overlapping where human operators would struggle to predict ownership.
- 01Listener accepts connectionAddress, port, protocol, hostname, and TLS must fit.
- 02Attached Routes competeHost and rule matches select the most specific accepted route.
- 03Filters transform behaviorRedirects, rewrites, headers, or mirroring may apply.
- 04BackendRef receives trafficWeight and backend health influence the selected destination.
Backend weights describe the intended proportion over time. They do not prescribe which backend receives the next individual request. Connection reuse, the controller’s algorithm, backend health, and a small sample can all make observed traffic differ from the configured ratio.
Backends and cross-namespace trust
An HTTPRoute commonly targets a Service by name and port. A same-namespace reference is straightforward. Cross-namespace backend references require a ReferenceGrant in the backend namespace, so the owner of the referenced resource explicitly grants trust. Gateway security model ↗
Route attachment across namespaces and backend references across namespaces are different relationships. allowedRoutes governs which Routes attach to a Gateway listener; ReferenceGrant governs supported references to resources in another namespace. Needing one does not imply that the other is satisfied.
Grant the narrowest useful combination of source group, kind, namespace, and destination kind/name. Broad grants can turn a shared Gateway into a path for unintended cross-team access.
TLS termination and passthrough
decryptsHTTPBackend
does not decryptTLSBackend
decrypts
decryptsTLS 2Backend
decrypts
Certificate Secrets are namespaced. Cross-namespace certificate references require supported reference semantics and explicit grants. Validate hostname coverage, chain, expiry, key type, protocol negotiation, and which component actually terminates TLS.
Ingress compared with Gateway API
Ingress is stable and widely implemented, but its API is frozen. Kubernetes recommends Gateway API for continued development. Ingress combines entry and routing concepts in a smaller model; implementation-specific annotations often supply features absent from the core API. Kubernetes Ingress ↗
| Concern | Ingress | Gateway API |
|---|---|---|
| Infrastructure ownership | IngressClass plus controller conventions | GatewayClass and Gateway are explicit layers |
| Application routing | Ingress rules | Protocol-specific Route resources |
| Shared gateways | Possible but controller-dependent | First-class attachment and namespace policy |
| Advanced matching | Often annotations or custom resources | Portable core/extended filters with declared support |
| Evolution | Stable but frozen | Actively developed with conformance profiles |
Before replacing an Ingress, list the behavior currently supplied by its annotations and controller: TLS, redirects, rewrites, timeouts, source addresses, health checks, load-balancer attributes, default backends, and DNS automation. Recreate and test those requirements explicitly. Running both entry paths on separate addresses or behind controlled DNS gives you a way to compare responses and telemetry before cutover.
The real packet path
The API diagram does not dictate hops. One implementation may provision a cloud load balancer targeting Nodes, another may target Pod addresses, and another may run an in-cluster proxy behind a LoadBalancer Service. Some combine these layers.
Map the deployed route explicitly: external DNS → advertised address → provider or on-prem load balancer → Node or Pod target → Gateway proxy → Service or endpoint → application. Record NAT, TLS termination, health checks, NetworkPolicy boundaries, and the return path at each transition.
Security boundaries
Gateway exposure increases the importance of namespace trust, RBAC, certificate access, controller credentials, allowed Route kinds, backend grants, and status visibility. Route authors should not be able to reference arbitrary Secrets or Services merely because a shared Gateway exists.
NetworkPolicy applies to Pod traffic where the installed implementation enforces it, but the source address visible at the backend can be a proxy Pod or Node rather than the original client. Layer 7 authorization belongs in the application, proxy, or an appropriate policy extension—not in standard NetworkPolicy.
Troubleshoot from status inward
Confirm the implementation and its supported Gateway API version, resources, features, and conformance profile.
Inspect kubectl get gatewayclass -o yaml. Verify controllerName and Accepted status before debugging a Gateway.
Inspect Gateway addresses, listeners, Accepted and Programmed conditions, certificate references, and controller events.
Inspect each Route parent’s status. Resolve attachment, hostname, kind, ReferenceGrant, and backend-port errors before sending traffic.
Test the backend Service and endpoints from inside the cluster. A Gateway cannot repair an empty EndpointSlice or wrong targetPort.
Send a request directly to the Gateway address with the intended SNI and HTTP Host header. This separates external DNS from listener and route matching.
Inspect controller logs, provisioned infrastructure, health checks, firewall policy, proxy metrics/logs, TLS details, and backend response.
Trace the return path and source address. A successful forward route can still fail through asymmetric routing or security policy.
What this means in practice
Make Accepted, ResolvedRefs, and Programmed part of deployment readiness. A rollout that checks only whether the Route object exists can report success before the controller has produced a usable path.
Document the boundary between portable Gateway API behavior and implementation extensions. Prefer standard fields where they meet the requirement; isolate provider-specific configuration so controller migrations do not require rediscovering hidden annotation behavior.