Skip to content

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

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.

Envoy Gateway’s Helm chart includes all required CRDs (both Gateway API and Envoy-specific). A single install is all you need:

Terminal window
helm install eg oci://docker.io/envoyproxy/gateway-helm \
--version v1.1.2 \
--namespace envoy-gateway-system \
--create-namespace

Wait for the controller to be ready:

Terminal window
kubectl rollout status deployment/envoy-gateway -n envoy-gateway-system

Verify Gateway API CRDs are installed:

Terminal window
kubectl get crd | grep gateway

Navigate to the demo directory:

Terminal window
cd demos/gateway-api

Deploy the resources:

Terminal window
kubectl apply -f manifests/namespace.yaml
kubectl apply -f manifests/deployment-app-v1.yaml
kubectl apply -f manifests/deployment-app-v2.yaml
kubectl apply -f manifests/service-v1.yaml
kubectl apply -f manifests/service-v2.yaml
kubectl apply -f manifests/gateway-class.yaml
kubectl apply -f manifests/gateway.yaml

Wait for the Gateway to be programmed:

Terminal window
kubectl get gateway -n gateway-demo

The Gateway creates a LoadBalancer Service. In minikube, run in a separate terminal:

Terminal window
minikube tunnel

Get the Gateway IP:

Terminal window
GATEWAY_IP=$(kubectl get svc -n gateway-demo -o jsonpath='{.items[?(@.metadata.ownerReferences[0].name=="demo-gateway")].status.loadBalancer.ingress[0].ip}')
echo $GATEWAY_IP
Terminal window
kubectl apply -f manifests/httproute-simple.yaml
curl http://$GATEWAY_IP

You should see the v1 page (light blue background).

Terminal window
kubectl delete httproute simple-route -n gateway-demo
kubectl apply -f manifests/httproute-split.yaml
for i in {1..10}; do
curl -s http://$GATEWAY_IP | grep -oP '<h1>\K[^<]+'
done

80% 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)”
Terminal window
kubectl delete httproute traffic-split -n gateway-demo
kubectl apply -f manifests/httproute-headers.yaml
# Default goes to v1
curl http://$GATEWAY_IP
# Header routes to v2
curl -H "X-Version: v2" http://$GATEWAY_IP
GatewayClass # Infrastructure (cluster admin)
└─> Gateway # Deployment of proxy (platform team)
└─> HTTPRoute # Application routing (dev team)
  1. Role-oriented: Separates infrastructure, operations, and dev concerns
  2. Expressive: Native traffic splitting, header matching, query params
  3. Multi-protocol: HTTP, HTTPS, gRPC, TCP, TLS, UDP
  4. Portable: Same manifests across Envoy, NGINX, Istio, Contour
  5. Strongly typed: No annotation hacks

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.

Terminal window
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik -n traefik --create-namespace

Wait for Traefik:

Terminal window
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=traefik -n traefik --timeout=60s

Access the Traefik dashboard (leave running in background):

Terminal window
kubectl port-forward -n traefik svc/traefik 9000:9000

Open http://localhost:9000/dashboard/ to watch routes appear as you deploy.

Terminal window
kubectl apply -f manifests/namespace.yaml
kubectl apply -f manifests/traefik-deployment-app1.yaml
kubectl apply -f manifests/traefik-deployment-app2.yaml
kubectl apply -f manifests/traefik-service-app1.yaml
kubectl apply -f manifests/traefik-service-app2.yaml

Apply middleware and routes:

Terminal window
kubectl apply -f manifests/traefik-middleware-strip-prefix.yaml
kubectl apply -f manifests/traefik-middleware-rate-limit.yaml
kubectl apply -f manifests/traefik-middleware-headers.yaml
kubectl apply -f manifests/traefik-ingressroute-basic.yaml
kubectl apply -f manifests/traefik-ingressroute-paths.yaml
kubectl apply -f manifests/traefik-ingressroute-with-middleware.yaml
Terminal window
kubectl port-forward -n traefik svc/traefik 8080:80
curl -H "Host: whoami-1.local" http://localhost:8080

Test Path-Based Routing with Prefix Stripping

Section titled “Test Path-Based Routing with Prefix Stripping”
Terminal window
curl http://localhost:8080/app1
curl http://localhost:8080/app2

The 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)”
Terminal window
curl -v -H "Host: whoami-1-middleware.local" http://localhost:8080

Look for X-Custom-Header: traefik-demo in the response. Run many requests to trigger rate limiting:

Terminal window
for i in {1..15}; do curl -H "Host: whoami-1-middleware.local" http://localhost:8080; done

After 10-15 requests, you get 429 Too Many Requests.

MiddlewarePurpose
stripPrefixRemove path prefixes before forwarding
rateLimitLimit requests per second
headersAdd or remove HTTP headers
basicAuthHTTP basic authentication
redirectSchemeHTTP to HTTPS redirects
compressgzip compression
circuitBreakerFail-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”
FeatureStandard IngressGateway APITraefik IngressRoute
Traffic splittingNoNative (weights)Native (weights)
Header routingNoNativeNative
MiddlewareAnnotationsFiltersFirst-class CRDs
Rate limitingAnnotationExternal filterBuilt-in middleware
DashboardNoNo (use provider tools)Built-in
PortabilityHigh (basic features)High (standard API)Traefik-only
MaturityStableGA (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.

Terminal window
# Gateway API cleanup
kubectl delete namespace gateway-demo
kubectl delete gatewayclass envoy
helm uninstall eg -n envoy-gateway-system
kubectl delete namespace envoy-gateway-system
# Traefik cleanup
helm uninstall traefik -n traefik
kubectl delete namespace traefik

See docs/deep-dive.md for a detailed explanation of Gateway API design, Traefik architecture, routing patterns, and implementation comparisons.

Move on to Reloader to learn how to automatically restart pods when their ConfigMaps or Secrets change.