Project Lab 13: Layer 7 Traffic Orchestration & Gateway Migration
As clusters grow, the limitations of the legacy Ingress API (annotation bloat and lack of role-based control) become apparent. This lab demonstrates how to manage production traffic using the traditional Ingress model and how to modernize that infrastructure using the Gateway API.
Reference Material:
docs/12-ingress-gateway/1-Ingress.mddocs/12-ingress-gateway/2-Ingress-host-routing.mddocs/12-ingress-gateway/3-gateway-api.md
1. OBJECTIVE: EVOLVING THE EDGE
The goal is to manage traffic for an enterprise application suite:
- Legacy Phase: Use NGINX Ingress to route
api.example.comandapp.example.comwith TLS. - Modernization Phase: Deploy a Gateway API infrastructure.
- Traffic Engineering: Implement a 90/10 Canary Split between
v1andv2of the API using native Gateway API fields (no annotations).
2. PHASE 1: THE LEGACY INGRESS MODEL (NGINX)
We will start by deploying two applications and a single Ingress controller to route traffic based on the Host header.
2.1 Setup Workloads and TLS Secret
# 1. Deploy App V1
kubectl run app-v1 --image=hashicorp/http-echo --port=5678 --labels="app=web,version=v1" -- -text="Welcome to V1"
kubectl expose pod app-v1 --port=80 --target-port=5678 --name=web-v1-svc
# 2. Create self-signed TLS Secret for SNI testing
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=api.example.com"
kubectl create secret tls edge-tls-secret --key tls.key --cert tls.crt
2.2 The Host-Based Ingress (ingress-legacy.yaml)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: legacy-router
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts: ["api.example.com"]
secretName: edge-tls-secret
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-v1-svc
port:
number: 80
3. PHASE 2: THE MODERN GATEWAY API
Now, we will replicate and enhance this logic using the Gateway API. This separates the "Infrastructure" (Gateway) from the "Routing" (HTTPRoute).
3.1 Provision the Gateway (Infrastructure Layer)
The Gateway defines where the Load Balancer listens. This is typically managed by the Platform/SRE team.
# 01-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gateway
namespace: infra-system
spec:
gatewayClassName: nginx # Linked to the Nginx Gateway Fabric
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- name: edge-tls-secret
allowedRoutes:
namespaces:
from: All # Allows dev teams to attach routes
3.2 Define the Canary Route (Developer Layer)
The Developer team now creates an HTTPRoute to manage their own traffic logic, including a weighted split for a new version (v2).
# Deploy App V2
kubectl run app-v2 --image=hashicorp/http-echo --port=5678 --labels="app=web,version=v2" -- -text="Welcome to V2 (Canary)"
kubectl expose pod app-v2 --port=80 --target-port=5678 --name=web-v2-svc
Manifest: canary-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-service-route
namespace: default
spec:
parentRefs:
- name: prod-gateway
namespace: infra-system
hostnames: ["api.example.com"]
rules:
- backendRefs:
- name: web-v1-svc
port: 80
weight: 90 # 90% of production traffic
- name: web-v2-svc
port: 80
weight: 10 # 10% for the Canary test
4. VERIFICATION & TRAFFIC AUDIT
4.1 Test the Ingress SNI
# Verify the Legacy Ingress is presenting the correct cert
curl -kvH "Host: api.example.com" https://<INGRESS_IP>
4.2 Validate Gateway API Status
The Gateway API provides extensive feedback in the status field.
# Check if the Gateway is successfully programmed
kubectl get gateway prod-gateway -n infra-system -o jsonpath='{.status.conditions[?(@.type=="Programmed")]}'
# Check if the HTTPRoute successfully attached to the Gateway
kubectl describe httproute api-service-route
4.3 Verify the Canary Split
Run a loop to see the 90/10 distribution in action.
for i in {1..10}; do curl -sH "Host: api.example.com" http://localhost:31000; done
Expected Observation: Approximately 9 out of 10 requests will return "Welcome to V1", and 1 will return "Welcome to V2 (Canary)".
5. TROUBLESHOOTING & NINJA COMMANDS
5.1 The "Route Not Found" Debug
If your Gateway is Ready but your Route returns 404:
- Check the
parentRef: Does the name and namespace match the Gateway? - Check
allowedRouteson the Gateway: Is the developer namespace permitted to attach?
5.2 Audit Nginx Realization
If using an in-cluster Gateway (like Nginx Gateway Fabric), inspect the actual Nginx config generated by the Gateway API:
kubectl exec -it -n infra-system <ngf-pod-name> -- cat /etc/nginx/conf.d/api-service-route.conf
6. ARCHITECT'S KEY TAKEAWAYS
- Ingress is Monolithic, Gateway API is Modular: Gateway API allows the SRE team to manage IP/Certificates while Developers manage only the routing logic.
- Native Traffic Splitting: Gateway API eliminates the need for proprietary annotations (like
nginx.ingress.kubernetes.io/canary) by making weights a first-class citizen. - SNI is the standard for Multi-Tenancy: Always use Host-based routing and SNI to consolidate multiple apps onto a single entry point.
- ReferenceGrant (Review): Remember that if your Route is in a different namespace than your Service, you must use a
ReferenceGrant(Ref: Chapter 12 Notes).