Advanced Ingress & Routing
Explore next-generation ingress with Gateway API (Envoy) and CRD-based routing with Traefik, including traffic splitting, middleware, and header routing.
Time: ~30 minutes Difficulty: Advanced
What You Will Learn
Section titled “What You Will Learn”Part 1 (Gateway API):
- GatewayClass, Gateway, HTTPRoute resource hierarchy
- Path-based routing, traffic splitting (canary), header-based routing (A/B testing)
- How Gateway API separates infrastructure and application concerns
Part 2 (Traefik):
- IngressRoute CRD vs standard Kubernetes Ingress
- Middleware for request manipulation (strip prefix, headers, rate limiting)
- Chaining middleware on a route and using the Traefik dashboard
Comparison:
- When to use Gateway API vs Traefik vs standard Ingress
Part 1: Kubernetes Gateway API (Envoy Gateway)
Section titled “Part 1: Kubernetes Gateway API (Envoy Gateway)”Gateway API is the successor to the Ingress resource. It provides role-oriented, expressive routing without vendor-specific annotations.
Install Envoy Gateway
Section titled “Install Envoy Gateway”Envoy Gateway’s Helm chart includes all required CRDs (both Gateway API and Envoy-specific). A single install is all you need:
helm install eg oci://docker.io/envoyproxy/gateway-helm \ --version v1.1.2 \ --namespace envoy-gateway-system \ --create-namespaceWait for the controller to be ready:
kubectl rollout status deployment/envoy-gateway -n envoy-gateway-systemVerify Gateway API CRDs are installed:
kubectl get crd | grep gatewayDeploy Gateway API Apps
Section titled “Deploy Gateway API Apps”Navigate to the demo directory:
cd demos/gateway-apiDeploy the resources:
kubectl apply -f manifests/namespace.yamlkubectl apply -f manifests/deployment-app-v1.yamlkubectl apply -f manifests/deployment-app-v2.yamlkubectl apply -f manifests/service-v1.yamlkubectl apply -f manifests/service-v2.yamlkubectl apply -f manifests/gateway-class.yamlkubectl apply -f manifests/gateway.yamlWait for the Gateway to be programmed:
kubectl get gateway -n gateway-demoThe Gateway creates a LoadBalancer Service. In minikube, run in a separate terminal:
minikube tunnelGet the Gateway IP:
GATEWAY_IP=$(kubectl get svc -n gateway-demo -o jsonpath='{.items[?(@.metadata.ownerReferences[0].name=="demo-gateway")].status.loadBalancer.ingress[0].ip}')echo $GATEWAY_IPTest 1: Simple Path Routing
Section titled “Test 1: Simple Path Routing”kubectl apply -f manifests/httproute-simple.yamlcurl http://$GATEWAY_IPYou should see the v1 page (light blue background).
Test 2: Traffic Splitting (Canary)
Section titled “Test 2: Traffic Splitting (Canary)”kubectl delete httproute simple-route -n gateway-demokubectl apply -f manifests/httproute-split.yaml
for i in {1..10}; do curl -s http://$GATEWAY_IP | grep -oP '<h1>\K[^<]+'done80% of requests go to v1, 20% go to v2.
Test 3: Header-Based Routing (A/B Testing)
Section titled “Test 3: Header-Based Routing (A/B Testing)”kubectl delete httproute traffic-split -n gateway-demokubectl apply -f manifests/httproute-headers.yaml
# Default goes to v1curl http://$GATEWAY_IP
# Header routes to v2curl -H "X-Version: v2" http://$GATEWAY_IPGateway API Hierarchy
Section titled “Gateway API Hierarchy”GatewayClass # Infrastructure (cluster admin) └─> Gateway # Deployment of proxy (platform team) └─> HTTPRoute # Application routing (dev team)Why Gateway API Over Ingress
Section titled “Why Gateway API Over Ingress”- Role-oriented: Separates infrastructure, operations, and dev concerns
- Expressive: Native traffic splitting, header matching, query params
- Multi-protocol: HTTP, HTTPS, gRPC, TCP, TLS, UDP
- Portable: Same manifests across Envoy, NGINX, Istio, Contour
- Strongly typed: No annotation hacks
Part 2: Traefik Ingress Controller
Section titled “Part 2: Traefik Ingress Controller”Traefik uses IngressRoute CRDs with first-class middleware support. Where Gateway API is standards-based and portable, Traefik provides a rich ecosystem of built-in middleware.
Install Traefik
Section titled “Install Traefik”helm repo add traefik https://traefik.github.io/chartshelm repo updatehelm install traefik traefik/traefik -n traefik --create-namespaceWait for Traefik:
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=traefik -n traefik --timeout=60sAccess the Traefik dashboard (leave running in background):
kubectl port-forward -n traefik svc/traefik 9000:9000Open http://localhost:9000/dashboard/ to watch routes appear as you deploy.
Deploy Traefik Apps
Section titled “Deploy Traefik Apps”kubectl apply -f manifests/namespace.yamlkubectl apply -f manifests/traefik-deployment-app1.yamlkubectl apply -f manifests/traefik-deployment-app2.yamlkubectl apply -f manifests/traefik-service-app1.yamlkubectl apply -f manifests/traefik-service-app2.yamlApply middleware and routes:
kubectl apply -f manifests/traefik-middleware-strip-prefix.yamlkubectl apply -f manifests/traefik-middleware-rate-limit.yamlkubectl apply -f manifests/traefik-middleware-headers.yamlkubectl apply -f manifests/traefik-ingressroute-basic.yamlkubectl apply -f manifests/traefik-ingressroute-paths.yamlkubectl apply -f manifests/traefik-ingressroute-with-middleware.yamlTest Host-Based Routing
Section titled “Test Host-Based Routing”kubectl port-forward -n traefik svc/traefik 8080:80curl -H "Host: whoami-1.local" http://localhost:8080Test Path-Based Routing with Prefix Stripping
Section titled “Test Path-Based Routing with Prefix Stripping”curl http://localhost:8080/app1curl http://localhost:8080/app2The prefix is stripped before forwarding, so the backend sees GET /, not GET /app1.
Test Middleware Chain (Rate Limiting + Headers)
Section titled “Test Middleware Chain (Rate Limiting + Headers)”curl -v -H "Host: whoami-1-middleware.local" http://localhost:8080Look for X-Custom-Header: traefik-demo in the response. Run many requests to trigger rate limiting:
for i in {1..15}; do curl -H "Host: whoami-1-middleware.local" http://localhost:8080; doneAfter 10-15 requests, you get 429 Too Many Requests.
Traefik Middleware Options
Section titled “Traefik Middleware Options”| Middleware | Purpose |
|---|---|
| stripPrefix | Remove path prefixes before forwarding |
| rateLimit | Limit requests per second |
| headers | Add or remove HTTP headers |
| basicAuth | HTTP basic authentication |
| redirectScheme | HTTP to HTTPS redirects |
| compress | gzip compression |
| circuitBreaker | Fail-fast on backend errors |
Middleware can be chained and executes in the order listed in the IngressRoute.
Comparison: Gateway API vs Traefik vs Ingress
Section titled “Comparison: Gateway API vs Traefik vs Ingress”| Feature | Standard Ingress | Gateway API | Traefik IngressRoute |
|---|---|---|---|
| Traffic splitting | No | Native (weights) | Native (weights) |
| Header routing | No | Native | Native |
| Middleware | Annotations | Filters | First-class CRDs |
| Rate limiting | Annotation | External filter | Built-in middleware |
| Dashboard | No | No (use provider tools) | Built-in |
| Portability | High (basic features) | High (standard API) | Traefik-only |
| Maturity | Stable | GA (v1.0+) | Stable |
Choose Gateway API when you need a portable, standards-based solution that works across multiple providers and separates roles cleanly.
Choose Traefik when you want rich built-in middleware, a visual dashboard, and don’t need multi-provider portability.
Choose standard Ingress for simple path/host routing that any ingress controller supports.
Cleanup
Section titled “Cleanup”# Gateway API cleanupkubectl delete namespace gateway-demokubectl delete gatewayclass envoyhelm uninstall eg -n envoy-gateway-systemkubectl delete namespace envoy-gateway-system
# Traefik cleanuphelm uninstall traefik -n traefikkubectl delete namespace traefikFurther Reading
Section titled “Further Reading”See docs/deep-dive.md for a detailed explanation of Gateway API design, Traefik architecture, routing patterns, and implementation comparisons.
Next Step
Section titled “Next Step”Move on to Reloader to learn how to automatically restart pods when their ConfigMaps or Secrets change.