Post 5/10 — From Ingress to Gateway API: Safer, Smarter Traffic Control
The question of why traffic should be controlled using additional means when Kubernetes offers in-built traffic management capabilities. Many Cloud Service Providers also have offerings around the same but having a set of defined policies to execute traffic management is necessary. This helps the application distribute the load in the system strategically. It also ensures lower latency in fulfilling request. Moreover, these policies make application secure my allowing limited access of resources both in and out of the Kubernetes cluster.
1) Executive Summary
When I first learned Kubernetes networking, Ingress felt like the magic front-door. But as clusters, tenants, and compliance needs grew, that door started to creak. Enter Gateway API — the modern, role-aware evolution that finally decouples platform and app teams safely.
This post walks through what changes (and why), shows a Before → After migration, and ends with a mini-lab you can run on any cluster.
2) Prereqs
- A working cluster (minikube/kind/EKS/GKE).
-
kubectl ≥ 1.28+gateway-apiCRDs installed (kubectl apply k https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml). - Basic understanding of Ingress objects, Services, and TLS secrets.
3) Concepts
Ingress vs Gateway mental model
| Aspect | Ingress | Gateway API |
|---|---|---|
| Scope | Cluster-wide front door | Namespaced, multi-tenant gateways |
| Roles | One YAML = shared config | Split into Gateway (ops) + HTTPRoute (dev) |
| Extensibility | Annotations galore | Typed fields + policies |
| Status | Controller-specific | Standardized conditions |
Think of Ingress as a flat router file. Gateway API adds layers:
- GatewayClass – defines the implementation (e.g., Istio, NGINX).
- Gateway – deployed by platform teams (where traffic enters).
- HTTPRoute – attached by app teams (what traffic does).
Gateway + HTTPRoute basics
Gateway: specifies listeners, ports, and TLS termination.
HTTPRoute: defines matches (hosts, paths, headers) and forwards traffic to services.
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: web-gw
namespace: platform
spec:
gatewayClassName: nginx
listeners:
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: my-cert
allowedRoutes:
namespaces:
from: All
# route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: shop-route
namespace: shop
spec:
parentRefs:
- name: web-gw
namespace: platform
hostnames: ["shop.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: shop-svc
port: 80
TLS, Retries, Timeouts, Header Matching
Gateway API formalizes what used to be annotation chaos:
rules:
- matches:
- headers:
- name: x-region
value: eu
backendRefs:
- name: shop-svc-eu
port: 80
filters:
- type: RequestTimeout
requestTimeout:
duration: 5s
- type: Retry
retry:
count: 3
statusCodes: ["5xx"]
Canary / Mirroring / Multi-tenant Gateways
Weighted traffic splits and mirrored routes are first-class now:
backendRefs:
- name: shop-svc
port: 80
weight: 80
- name: shop-svc-canary
port: 80
weight: 20
Multiple HTTPRoutes can attach to one Gateway, safely namespaced.
Ops maintain TLS + exposure policies; devs just ship routes.
4) Mini-Lab — Replace Ingress with Gateway/HTTPRoute + Canary + TLS
Before (legacy Ingress):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts: [shop.example.com]
secretName: my-cert
rules:
- host: shop.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: shop-svc
port:
number: 80
After (Gateway API):
Apply gateway.yaml and route.yaml from above.
Verify:
kubectl get gateways -A
kubectl get httproutes -A
kubectl describe httproute shop-route
Add a canary service and observe:
kubectl get endpoints shop-svc-canary -o wide
curl -H "x-canary:true" https://shop.example.com
You’ll see controlled traffic flow, better observability, and cleaner ownership.
5) Cheatsheet
| Task | Command |
|---|---|
| List GatewayClasses | kubectl get gatewayclass |
| Inspect listeners | kubectl describe gateway <name> |
| List routes per gateway | kubectl get httproute -A --field-selector spec.parentRefs.name=<gw> |
| Apply TLS secret | kubectl create secret tls my-cert --cert cert.pem --key key.pem -n platform |
| Test connectivity | curl -k https://host |
Key fields:
-
listeners.protocol,tls.mode,allowedRoutes -
rules.matches,filters,backendRefs.weight
6) Pitfalls
- Policy attachment order: Gateway policies apply before Route policies → watch precedence.
- Overlapping routes: Multiple HTTPRoutes with same host/path → controller decides priority.
-
Cross-namespace refs: If
allowedRoutes.from=Same, dev teams can’t attach externally. -
Controller support: Check
status.conditionsfor accepted listeners.
7) Wrap-Up
With Gateway API, Kubernetes finally gives us policy-aware traffic control that scales across teams and environments — safer, cleaner, and built for automation.
Next up in the series: Helm Fundamentals (Post 6) — we’ll templatize these Gateway objects and parameterize routes the right way.