4.7 Gateway API: GatewayClass, Gateway, HTTPRoute & Traffic Splitting
Key Takeaways
- The Gateway API (gateway.networking.k8s.io) is the next-generation, role-oriented standard that replaces Ingress with an expressive, decoupled, multi-tenant architecture.
- The architecture separates operational responsibilities across three distinct personas: Infrastructure Provider (GatewayClass), Cluster Operator (Gateway), and Application Developer (HTTPRoute/GRPCRoute).
- Gateway listeners bind to network ports, hostnames, and TLS certificates, using allowedRoutes to govern which namespaces can attach routing resources.
- HTTPRoute rules natively support advanced traffic shaping—including weighted canary traffic splitting (backendRefs), header-based routing, query parameter matching, and URL rewrites—without vendor annotations.
- ReferenceGrant authorizes explicit cross-namespace object references: for example, a target namespace can permit HTTPRoutes in another namespace to reference its Services, or permit Gateways to reference its Secrets.
4.7 Gateway API: GatewayClass, Gateway, HTTPRoute & Traffic Splitting
While the original Kubernetes Ingress API successfully standardized basic HTTP routing, over a decade of production experience exposed fundamental architectural limitations:
- Monolithic Resource Model: A single Ingress manifest mixes infrastructure provisioning (ports, TLS certificates, IP addresses) with application routing rules, creating permission conflicts between cluster operators and application developers.
- Vendor Annotation Chaos: Advanced features (canary weighting, header rewrites, rate limiting, authentication) were never standardized, leading to hundreds of proprietary, incompatible annotations (e.g.,
nginx.ingress.kubernetes.io/...,traefik.ingress.kubernetes.io/...). - Single-Tenant Namespace Restrictions: Ingress cannot cleanly span across multiple namespaces or route traffic across organizational boundaries.
The Gateway API (gateway.networking.k8s.io) is a modern, expressive, role-oriented, and extensible standard graduated to General Availability (GA) in Kubernetes 1.29+. It provides a standardized framework for Layer 4 through Layer 7 routing across heterogeneous data planes (Envoy Gateway, Istio, Cilium, Traefik, HAProxy, and Cloud LBs).
1. Role-Oriented Architecture & Personas
The Gateway API decomposes network management into three distinct operational personas and corresponding API resources:
+-----------------------------------------------------------------------------------------+
| GATEWAY API ROLE-ORIENTED ARCHITECTURE |
| |
| PERSONA 1: INFRASTRUCTURE PROVIDER |
| Resource: GatewayClass (Cluster-Scoped) |
| Role: Defines controller implementation (e.g., cilium, envoy, cloud-lb). |
| |
| PERSONA 2: CLUSTER OPERATOR / PLATFORM ADMIN |
| Resource: Gateway (Namespace: infra-gateway) |
| Role: Provisions load balancer IPs, listening ports (80/443), TLS certificates, |
| and sets namespace attachment policies (allowedRoutes). |
| |
| PERSONA 3: APPLICATION DEVELOPER |
| Resources: HTTPRoute, GRPCRoute, TLSRoute, TCPRoute (Namespaces: team-a, team-b) |
| Role: Defines URL path matching, canary weights, header rewrites, and attaches |
| routes to the shared Gateway via parentRefs. |
+-----------------------------------------------------------------------------------------+
| Persona | API Resource | Scope | Core Responsibilities |
|---|---|---|---|
| Infrastructure Provider | GatewayClass | Cluster | Installed by CNI / Ingress controller vendors. Maps the controller binary (spec.controllerName). |
| Platform Administrator | Gateway | Namespace | Declares network entrypoints: IP addresses, listening ports (80, 443), TLS secrets, and which namespaces can attach routes. |
| Application Developer | HTTPRoute, GRPCRoute | Namespace | Defines application routing: URI paths, header matches, canary weighting, URL rewrites, and links to target Gateway via parentRefs. |
2. Gateway API Resource Hierarchy: GatewayClass, Gateway & HTTPRoute
1. GatewayClass (Cluster-Scoped)
Created by the platform or CNI vendor:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: envoy-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
2. Gateway (Namespace-Scoped: infra-gateway)
Created by the Platform Administrator to provision external load balancer listeners:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-external-gateway
namespace: infra-gateway
spec:
gatewayClassName: envoy-gateway
listeners:
- name: https-listener
protocol: HTTPS
port: 443
hostname: "*.mycompany.com"
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard-tls-secret
allowedRoutes:
namespaces:
from: All # Allows HTTPRoutes in ANY namespace to attach
- name: http-listener
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
env: production
3. HTTPRoute (Namespace-Scoped: team-checkout)
Created by the Application Developer to define path routing and attach to the Gateway:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: checkout-route
namespace: team-checkout
spec:
parentRefs:
- name: prod-external-gateway
namespace: infra-gateway
sectionName: https-listener
hostnames:
- "store.mycompany.com"
rules:
- matches:
- path:
type: PathPrefix
value: /checkout
backendRefs:
- name: checkout-service
port: 8080
3. Advanced Traffic Management: Weighted Canary Splitting & Header Matching
Unlike Ingress, the Gateway API provides first-class, standardized syntax for Weighted Traffic Splitting (Canaries) and Header-Based Routing without requiring proprietary annotations.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: payment-canary-route
namespace: payment
spec:
parentRefs:
- name: prod-external-gateway
namespace: infra-gateway
hostnames:
- "pay.mycompany.com"
rules:
# Rule 1: Beta Users Header-Based Routing
- matches:
- headers:
- name: X-Beta-Tester
value: "true"
path:
type: PathPrefix
value: /v2
backendRefs:
- name: payment-v2-experimental
port: 8080
weight: 100
# Rule 2: Production Weighted Canary Traffic Split (90% Stable / 10% Canary)
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: payment-v1-stable
port: 8080
weight: 90 # 90% of production traffic
- name: payment-v2-canary
port: 8080
weight: 10 # 10% of production traffic
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Routed-By
value: "GatewayAPI-Envoy"
4. Cross-Namespace References with ReferenceGrant
Two different mechanisms are easy to confuse. A Route attaching to a Gateway in another namespace is governed by the Gateway listener's allowedRoutes plus the Route's parentRefs. By contrast, an HTTPRoute whose backendRefs names a Service in another namespace needs a ReferenceGrant in the Service's target namespace.
In this example, checkout-route is in store-team and forwards to payment-backend in payment-team:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: checkout-route
namespace: store-team
spec:
parentRefs:
- name: prod-gateway
namespace: infra-gateway
rules:
- backendRefs:
- name: payment-backend
namespace: payment-team
port: 8080
---
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-store-routes
namespace: payment-team
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: store-team
to:
- group: ""
kind: Service
The grant's from kind is HTTPRoute because the Route contains the cross-namespace backend reference; it is not Gateway. A Gateway-to-Secret reference would instead grant from kind Gateway. Current Gateway API examples use gateway.networking.k8s.io/v1; in an exam cluster, confirm installed served versions with kubectl api-resources and kubectl explain referencegrant.
ReferenceGrant is additive and deliberately grants by group and kind rather than selecting individual source object names. Without the required grant, the backend reference is invalid and the Route status should report an unresolved or unaccepted reference without leaking unnecessary details about the target resource.
In the Kubernetes Gateway API architecture, which persona and resource combination is specifically responsible for provisioning listening ports, configuring TLS certificate secrets, and defining which namespaces can attach routes?
An HTTPRoute in namespace 'infra-system' has a backendRef to Service 'auth-svc' in namespace 'security-tier'. Why is the backend reference unresolved?
An application developer needs to implement a canary deployment where 80% of production traffic goes to 'web-v1' and 20% goes to 'web-v2'. How is this configured in a Gateway API 'HTTPRoute'?