The Gateway API
The Gateway API
Kubernetes Ingress was designed in 2015 for a narrow use case: route HTTP/HTTPS traffic to backend Services. Over the years it accumulated so many vendor-specific annotations — NGINX, AWS ALB, Traefik, Istio — that a single Ingress manifest was rarely portable between clusters. The Kubernetes Gateway API (GA in Kubernetes 1.28, June 2023) is the standards-body answer: a role-aware, expressive, extension-first API for managing traffic at every layer.
GatewayClass, Gateway, and HTTPRoute (plus TLSRoute, TCPRoute, GRPCRoute). This separation directly maps to how platform, network, and application teams own different layers of infra at big-tech companies.
The Three-Layer Role Model
Gateway API encodes an organisational model that mirrors real infrastructure ownership:
- GatewayClass — owned by the infrastructure provider (cloud team or cluster admin). Declares which controller implements the Gateway (e.g., Envoy Gateway, Cilium, AWS Load Balancer Controller). Think of it as the driver.
- Gateway — owned by the platform/network team. Binds to a GatewayClass and defines listeners (ports, protocols, TLS certificates). One Gateway can serve many applications.
- HTTPRoute / GRPCRoute / TLSRoute — owned by the application team. Attaches to a Gateway, defines fine-grained routing rules (path, header, query, method matching; traffic weighting; request modification).
Installing a Gateway Controller (Envoy Gateway)
Gateway API CRDs are not installed by default — you install the CRDs once, then a controller (implementation) separately. Envoy Gateway is the CNCF-maintained reference implementation backed by Envoy Proxy.
Defining a GatewayClass and Gateway
The platform team creates the GatewayClass and Gateway once. These are cluster-scoped or namespace-scoped resources that application teams attach routes to — they do not touch the Gateway manifest.
Writing an HTTPRoute (Application Team)
An HTTPRoute lives in the application namespace and attaches to the shared Gateway. It supports exact, prefix, and regex path matching; header/query matching; traffic weighting for canary; and request/response modification — all without annotations.
Traffic Weighting & Canary Without Annotations
The weight field in backendRefs replaces the sprawl of nginx.ingress.kubernetes.io/canary-weight annotations with a first-class, controller-agnostic construct. Big-tech progressive delivery pipelines (Flagger, Argo Rollouts) drive this field programmatically to shift traffic 5% at a time based on metric gates, then promote or roll back automatically.
ReferenceGrant when your HTTPRoute is in a different namespace from the Gateway. Without it the attachment silently fails and the route stays detached — check kubectl get httproute -n api-team -o yaml and look at .status.parents[].conditions for Accepted: False with reason NotAllowedByParent.
GRPCRoute and TLSRoute
The Gateway API is protocol-aware. For gRPC microservices, use a GRPCRoute which can match on service name and method name — critical for routing at the gRPC level without HTTP path hacks. For raw TLS passthrough (databases, MQTT brokers), TLSRoute routes by SNI without terminating the TLS session.
Production Failure Modes
- Route not attached: The most common issue. Check
kubectl get gateway prod-gateway -n infra -o yaml— the.status.listeners[].attachedRoutescount tells you how many routes are bound. Zero usually means a namespace selector mismatch or a missingReferenceGrant. - TLS certificate not found: If the Secret referenced in
certificateRefsis in a different namespace, Envoy Gateway needs aReferenceGrantin that namespace too — same cross-namespace trust model as routes. - Controller not reconciling: Gateway API controllers watch specific
GatewayClass.spec.controllerName. If you install two Gateway controllers (e.g., Nginx and Envoy), only the one matching the name reconciles the Gateway. The other ignores it. - CRD version skew: Running a v1.1 controller against v1.0 CRDs (or vice versa) causes silent reconciliation failures. Always match controller and CRD versions in CI before promoting to production.
app.example.com creates two external IPs fighting over the same DNS record, leading to intermittent 502s and unpredictable routing that is very hard to debug at 3am.
Observability: Reading Route Status
Every Gateway API resource exposes structured .status conditions. Automate health checks in your CD pipeline by reading these — a route that deploys without error but never attaches is a silent failure that Ingress would never surface.
Gateway API is the future of Kubernetes ingress — Ingress will not receive new features. If you are building a new cluster today, start with Gateway API. If you are migrating, most controllers (NGINX, Traefik, Istio) now ship Gateway API support alongside Ingress; you can run both during transition and switch DNS when stable.