Kubernetes networking has long relied on the Ingress API as the de facto standard for exposing HTTP/HTTPS services. While Ingress served its purpose, it suffers from fundamental limitations: a single monolithic resource, heavy reliance on vendor-specific annotations, and weak support for multi-tenancy and non-HTTP protocols. The Kubernetes Gateway API emerges as a modern, expressive, and extensible replacement, offering a clear separation of concerns, richer routing capabilities, and first‑class support for L4/L7 traffic. This post dives deep into the architecture of Gateway API, contrasts it with Ingress, and equips you with practical examples to start using this production‑ready standard.
Architecture: A New Paradigm for Kubernetes Traffic Management
Gateway API introduces a family of resources that model the entire traffic management stack: GatewayClass, Gateway, and Route resources (HTTPRoute, TCPRoute, UDPRoute, TLSRoute, etc.). This design cleanly separates infrastructure provisioning (the dataplane) from traffic routing policies (the control plane).
- GatewayClass defines a class of Gateways backed by a specific controller (e.g., Kong, Istio, HAProxy) and its configuration parameters.
- Gateway provisions a physical or virtual listener (IP + port) based on a GatewayClass. It binds infrastructure to the cluster.
- Routes attach to a Gateway and define how to direct traffic to backend services. Routes are namespaced, enabling true multi‑tenant ownership.
This contrasts sharply with Ingress, where a single resource conflates listener configuration, routing rules, and implementation details through annotations. Gateway API’s model allows multiple independent teams to manage different parts of the traffic flow securely and without stepping on each other’s toes.
GatewayClasses and Listeners: Decoupling Infrastructure
A GatewayClass is cluster‑wide and acts as a template for Gateways. For example, a kong-gatewayclass might refer to the Kong Ingress Controller and its custom parameters. When a developer creates a Gateway in their namespace referencing that class, the controller provisions a listener (e.g., :80 for HTTP or :443 for HTTPS). TheGateway’s status reports the actual addresses (IPs or hostnames) allocated by the underlying infrastructure.
Listeners are defined directly in the Gateway spec and can include TLS settings, allowed routes, and even listener‑specific filters. This explicit handshake between the controller (via GatewayClass) and the user (via Gateway) prevents misconfiguration and clarifies ownership.
Ingress vs. Gateway API: A Head‑to‑Head Comparison
| Feature | Ingress | Gateway API |
|---|---|---|
| Resource Model | Single Ingress resource per host/path | Separate Gateway, GatewayClass, and Route resources |
| Multi‑tenancy | Limited; all rules share one controller instance | Strong isolation; routes are namespaced, gateways can be shared or dedicated |
| Protocol Support | HTTP/HTTPS only (with rare extensions for TCP/UDP) | Native L4 (TCP/UDP) and L7 (HTTP/HTTPS, gRPC, TLS) |
| Extensibility | Vendor annotations (non‑portable) | Standard CRDs, filters, and extensions via ExtensionRef |
| Weighted Routing | Basic (via annotations) | First‑class support in all Route types |
| Header/Query Matching | Limited (annotations) | Rich match criteria (headers, query params, methods, ports) |
| Status Conditions | Basic address field | Detailed conditions on Gateway, Route, and listener levels |
| Adoption | Mature, widely used | GA in Kubernetes 1.8+, supported by major controllers (Kong, Istio, NGINX, HAProxy) |
| Controller‑Specific | Tightly coupled; each controller interprets annotations differently | Well‑defined behaviors; controllers must comply with the spec |
Gateway API is not merely an incremental improvement—it rethinks how traffic management is expressed in Kubernetes, aligning with the platform’s declarative and collaborative ethos.
Practical Implementation: From Zero to Routing
Let’s see Gateway API in action. You’ll need a Gateway API‑compatible controller installed (e.g., Kong, Istio, or the built‑in implementation). The examples below use the standard gateway.networking.k8s.io/v1 API.
Step 1: Define a GatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
spec:
controllerName: konghq.com/gateway-controller
parametersRef:
group: configuration.konghq.com/v1beta1
kind: KongClusterPlugin
name: global-config
This declares that the kong controller should manage Gateways of this class. The parametersRef can hold optional configuration.
Step 2: Provision a Gateway (Listener)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
gatewayClassName: kong
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: All
- name: https
protocol: HTTPS
port: 443
allowedRoutes:
kinds:
- kind: HTTPRoute
- kind: TLSRoute
namespaces:
from: All
tls:
mode: Terminate
certificateRef:
name: my-tls-secret
kind: Secret
The Gateway defines two listeners: one for plain HTTP and another for HTTPS with TLS termination using a Kubernetes Secret. allowedRoutes restricts which Route resources can attach. Here we allow routes from all namespaces.
Step 3: Create Routes to Expose Services
Simple HTTP Route with Path Matching:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: webapp-route
namespace: app1
spec:
parentRefs:
- name: my-gateway
namespace: default
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
forwardTo:
- serviceName: api-service
port: 8080
- matches:
- path:
type: Exact
value: /
forwardTo:
- serviceName: webapp-service
port: 80
This route demonstrates two rules: requests to /api/* go to api-service:8080, and exact / goes to webapp-service:80. The parentRefs ties the route to the Gateway.
Advanced Weighted Routing with Header Matching:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-route
namespace: app2
spec:
parentRefs:
- name: my-gateway
namespace: default
hostnames:
- "v2.example.com"
rules:
- matches:
- headers:
- name: x-canary
type: Exact
value: "true"
forwardTo:
- serviceName: v2-service
port: 80
weight: 100
- matches: [] # default
forwardTo:
- serviceName: v1-service
port: 80
weight: 90
- serviceName: v2-service
port: 80
weight: 10
This route implements a canary deployment: requests with header x-canary: true go 100% to v2, while the rest split 90/10 between v1 and v2.
TCP Route for Non‑HTTP Traffic:
apiVersion: gateway.networking.k8s.io/v1
kind: TCPRoute
metadata:
name: tcp-game-server
namespace: games
spec:
parentRefs:
- name: my-game-gateway
namespace: infrastructure
rules:
- forwardTo:
- serviceName: game-server
port: 27015
This TCPRoute exposes a game server on a dedicated Gateway listening on a custom port.
Conclusion
The Kubernetes Gateway API represents a transformative leap from the constraints of Ingress. Its modular design, multi‑tenant safety, and first‑class support for all common protocols make it the clear choice for modern cluster traffic management. As the ecosystem continues to coalesce around this standard, adopting Gateway API future‑proofs your infrastructure and unlocks advanced use cases like canary rollouts, header‑based routing, and cross‑namespace collaboration. Start exploring today—your cluster’s networking stack will never be the same.
Author: James P Samuelkutty
Contact: LinkedIn | Email