KubernetesCXI · Kubernetes Networking Advanced TopicsAdvanced networking
Gateway API — the modern Ingress replacement
What you'll learn
- Use Gateway API resources (GatewayClass, Gateway, HTTPRoute)
- Reason about the advantages over Ingress
- Choose a Gateway API implementation (Cilium, Istio, NGINX)
- Apply the operational discipline of adopting Gateway API for new deployments
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
Gateway API is the modern replacement for Ingress. This lesson walks the resources, the advantages over Ingress, the implementations, and the discipline.
The Ingress limitations
flowchart LR
A[Ingress] --> B["One resource, multiple annotations"]
B --> C[Provider-specific annotations]
C --> D[Cloud lock-in]
A --> E[HTTP only]
A --> F[Limited traffic splitting]
The Ingress limitations:
- One resource. Ingress is a single object with annotations; the same object has TLS, hosts, paths, and backend configuration.
- Provider-specific annotations. Each implementation (nginx, ALB) has its own annotations; portability is limited.
- HTTP only. Ingress is HTTP/HTTPS; TCP, TLS, and gRPC are not first-class.
- Limited traffic splitting. Ingress supports basic routing; weighted traffic splitting requires service mesh.
Gateway API resources
flowchart LR
A["GatewayClass: infrastructure provider"] --> B["Gateway: cluster operator"]
B --> C["HTTPRoute: application developer"]
B --> D["TCPRoute: application developer"]
B --> E["TLSRoute: application developer"]
B --> F["GRPCRoute: application developer"]
The Gateway API resources:
- GatewayClass. Defined by the infrastructure
provider (e.g.,
cilium,istio,nginx). The template for Gateways. - Gateway. Defined by the cluster operator. A deployed instance of a GatewayClass; listens on ports.
- HTTPRoute. Defined by the application developer. Routes HTTP traffic to Services.
- TCPRoute, TLSRoute, GRPCRoute. Routing for non-HTTP protocols.
The role-oriented design: each role defines its own resource; the manifest is portable.
An example
# GatewayClass (infra provider)
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: cilium
spec:
controllerName: io.cilium.gateway-controller
---
# Gateway (cluster operator)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
namespace: gateway-system
spec:
gatewayClassName: cilium
listeners:
- name: http
protocol: HTTP
port: 80
---
# HTTPRoute (application developer)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: myapp-route
namespace: prod-app
spec:
parentRefs:
- name: prod-gateway
namespace: gateway-system
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: myapp
port: 80
Three resources, three roles:
- The infra provider defines the GatewayClass.
- The cluster operator deploys the Gateway.
- The application developer defines the HTTPRoute.
The advantages over Ingress
flowchart LR
A[Gateway API] --> B[+ Role-oriented]
A --> C[+ Portable across implementations]
A --> D["+ HTTP, TCP, TLS, gRPC"]
A --> E[+ Traffic splitting]
A --> F[+ Multi-tenant Gateway]
A --> G[+ Header-based routing]
The advantages:
- Role-oriented. Infra, cluster, application roles each define their own resource.
- Portable. Manifests work across implementations.
- Multi-protocol. HTTP, TCP, TLS, gRPC.
- Traffic splitting. Weighted routing for canary, blue-green.
- Multi-tenant Gateway. A Gateway can host routes from multiple namespaces.
- Header-based routing. Match on headers, not just paths.
The implementations
| Implementation | Notes |
|---|---|
| Cilium | eBPF-based; high performance; L7 with Envoy |
| Istio | service mesh; full L7; complex |
| NGINX Gateway Fabric | nginx-based; familiar config |
| Traefik | dynamic config; popular alternative |
| HAProxy | high performance; complex |
Each implementation has its own GatewayClass; the HTTPRoute is portable across them.
Migration from Ingress
flowchart LR
A["Ingress: existing"] --> B[Run Ingress and Gateway API in parallel]
B --> C[Migrate routes one at a time]
C --> D[Verify traffic on Gateway]
D --> E[Remove Ingress]
The migration:
- Install a Gateway API implementation alongside the existing Ingress controller.
- Create a Gateway and migrate routes one at a time.
- Verify traffic on the Gateway; remove from Ingress.
- Repeat until all routes are migrated.
- Remove the Ingress controller.
The migration is incremental; both can run in parallel during the transition.
Quiz
Knowledge check · 4 questions
Q1. What problem in the Ingress API does Gateway API's role separation address?
Q2. Gateway API supports protocols beyond HTTP without vendor-specific annotations.
Q3. Explain why an HTTPRoute is not being attached to its Gateway and make the cross-namespace binding work.
A Gateway named prod-gateway lives in namespace gateway-system with an HTTP listener on port 80. An application team creates an HTTPRoute in namespace prod-app whose parentRefs point at prod-gateway in gateway-system. `kubectl describe httproute myapp-route -n prod-app` shows the parent condition Accepted=False with reason NotAllowedByListeners, and requests for the host return 404 from the Gateway.
Q4. Name the three core Gateway API resources, say which role owns each, and state which resource carries the controller name.
Passing score: 75%. Answers are checked in this browser.
The operational discipline
Gateway API in production rests on five non-negotiable elements:
- Choose an implementation. Cilium for performance; Istio for L7; NGINX for familiarity.
- Role-oriented manifests. Each role defines its own resource.
- Test in staging. Different implementations have different behaviours.
- Monitor traffic. Hubble (Cilium), Kiali (Istio), or the controller’s metrics.
- Migrate incrementally. Both Ingress and Gateway API can run in parallel.
Gateway API is the future of Kubernetes ingress. The discipline is to adopt it for new deployments and migrate existing Ingress deployments incrementally.