Working with Gateway API
1. Installing Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml
| Channel | Contents |
| standard | GA: Gateway, GatewayClass, HTTPRoute, ReferenceGrant |
| experimental | TCPRoute, TLSRoute, UDPRoute, GRPCRoute, BackendTLSPolicy |
2. Creating GatewayClass Resource
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata: { name: external }
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
| Field | Detail |
| controllerName | Implementation: Envoy Gateway, Istio, Contour, NGINX |
| parametersRef | Provider-specific config |
3. Creating Gateway Resource
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: { name: prod }
spec:
gatewayClassName: external
listeners:
- { name: http, port: 80, protocol: HTTP }
- name: https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- { kind: Secret, name: prod-tls }
4. Configuring HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: { name: api }
spec:
parentRefs:
- { name: prod, sectionName: https }
hostnames: ["api.example.com"]
rules:
- matches:
- { path: { type: PathPrefix, value: /v1 } }
backendRefs:
- { name: api-v1, port: 80, weight: 90 }
- { name: api-v2, port: 80, weight: 10 }
| Match Type | Field |
| Path | Exact / PathPrefix / RegularExpression |
| Header | name + value (Exact/Regex) |
| QueryParam | name + value |
| Method | GET, POST, ... |
5. Using TCPRoute
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata: { name: pg }
spec:
parentRefs: [{ name: prod, sectionName: pg }]
rules:
- backendRefs: [{ name: postgres, port: 5432 }]
| Use Case | Detail |
| Non-HTTP | Databases, message brokers |
| Listener protocol | TCP |
6. Using TLSRoute
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata: { name: passthrough }
spec:
parentRefs: [{ name: prod, sectionName: https-pt }]
hostnames: ["mqtt.example.com"]
rules: [{ backendRefs: [{ name: mqtt, port: 8883 }] }]
| TLS Mode | Detail |
| Passthrough | Gateway routes by SNI; client-to-pod TLS |
| Terminate | Gateway decrypts (use HTTPRoute) |
7. Setting Gateway Listeners
| Field | Detail |
| name | Unique listener identifier |
| port / protocol | HTTP, HTTPS, TCP, TLS, UDP |
| hostname | SNI / Host filter |
| allowedRoutes | Which Routes can attach (namespaces, kinds) |
8. Configuring Backend References
| Field | Use |
| name / port | Service reference |
| weight | Traffic split (integer, relative) |
| group / kind | Cross-namespace requires ReferenceGrant |
9. Using Request Matching
matches:
- headers:
- { name: x-canary, value: "true" }
path: { type: PathPrefix, value: /api }
filters:
- type: RequestHeaderModifier
requestHeaderModifier: { add: [{ name: x-forwarded-by, value: gw }] }
| Filter | Action |
| RequestHeaderModifier | add/set/remove request headers |
| ResponseHeaderModifier | Modify response headers |
| RequestRedirect | 3xx redirect |
| URLRewrite | Rewrite host/path |
| RequestMirror | Mirror to another backend |
10. Implementing Traffic Splitting
backendRefs:
- { name: web-stable, port: 80, weight: 90 }
- { name: web-canary, port: 80, weight: 10 }
| Pattern | Strategy |
| Canary | Small weight to new version |
| Blue/Green | Switch 100% by editing weight |
| A/B | Header match → specific backend |
11. Understanding Gateway API vs Ingress
Ingress
- Single resource per app
- Annotation-heavy for advanced features
- HTTP/HTTPS only
- Implementation-specific behavior
Gateway API
- Role-oriented: GatewayClass (infra), Gateway (cluster ops), Routes (app dev)
- Native L4/L7 (TCP, UDP, TLS, HTTP, gRPC)
- Typed filters/policies — fewer annotations
- Cross-namespace via ReferenceGrant