Use Case: Kubernetes Gateway API¶
Use the modern Kubernetes Gateway API instead of legacy Ingress resources. NovaEdge implements the Gateway API specification, supporting GatewayClass, Gateway, HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute.
Problem Statement¶
"I want to use the Kubernetes Gateway API for my service routing. It gives me better role separation (infra vs. app teams), native support for traffic splitting, header-based routing, and protocol-specific route types. I need a Gateway API implementation that also handles VIP management and L4/L7 policies."
The Gateway API is the successor to the Ingress API. It provides:
- Role-oriented design: Infrastructure providers manage GatewayClass and Gateway. Application developers manage Routes.
- Expressive routing: Header matching, query parameter matching, method matching, traffic splitting, request mirroring.
- Protocol-specific routes: HTTPRoute, GRPCRoute, TCPRoute, TLSRoute instead of a single Ingress spec for everything.
- Portable: Standardized API across implementations (NovaEdge, Envoy Gateway, Istio, Cilium).
NovaEdge implements Gateway API and extends it with VIP management, advanced policies, and L4/L7 load balancing that other implementations lack.
Architecture¶
graph TB
subgraph Infrastructure Team
GC["GatewayClass<br/>novaedge"]
GW["Gateway<br/>api-gateway<br/>(ports 80, 443)"]
end
subgraph Application Team A
HR1["HTTPRoute<br/>store.example.com"]
HR2["HTTPRoute<br/>store.example.com/api/*"]
end
subgraph Application Team B
GR["GRPCRoute<br/>grpc.example.com"]
end
subgraph Platform Team
TR["TCPRoute<br/>port 5432 -> postgres"]
TLSR["TLSRoute<br/>port 6379 -> redis (TLS passthrough)"]
end
subgraph NovaEdge Data Plane
VIP["ProxyVIP<br/>10.200.0.100"]
Agent["NovaEdge Agent<br/>(DaemonSet)"]
end
subgraph Backend Services
StoreFE["store-frontend<br/>pods"]
StoreAPI["store-api<br/>pods"]
GRPC_SVC["grpc-service<br/>pods"]
PG["postgresql<br/>pods"]
Redis["redis<br/>pods"]
end
GC --> GW
GW --> HR1
GW --> HR2
GW --> GR
GW --> TR
GW --> TLSR
VIP --> Agent
Agent --> GW
HR1 --> StoreFE
HR2 --> StoreAPI
GR --> GRPC_SVC
TR --> PG
TLSR --> Redis
style GC fill:#90EE90,stroke:#333,color:#000
style GW fill:#90EE90,stroke:#333,color:#000
style VIP fill:#90EE90,stroke:#333,color:#000
style Agent fill:#90EE90,stroke:#333,color:#000
style HR1 fill:#90EE90,stroke:#333,color:#000
style HR2 fill:#90EE90,stroke:#333,color:#000
style GR fill:#90EE90,stroke:#333,color:#000
style TR fill:#90EE90,stroke:#333,color:#000
style TLSR fill:#90EE90,stroke:#333,color:#000
style StoreFE fill:#FFE4B5,stroke:#333,color:#000
style StoreAPI fill:#FFE4B5,stroke:#333,color:#000
style GRPC_SVC fill:#FFE4B5,stroke:#333,color:#000
style PG fill:#FFE4B5,stroke:#333,color:#000
style Redis fill:#FFE4B5,stroke:#333,color:#000
Prerequisites¶
Install the Gateway API CRDs (these are separate from the NovaEdge CRDs):
# Install Gateway API standard CRDs (v1.2.x)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
# Install experimental CRDs (required for GRPCRoute, TCPRoute, TLSRoute)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/experimental-install.yaml
Configuration¶
Step 1: GatewayClass (Infrastructure Team)¶
The GatewayClass tells Kubernetes which controller implements the Gateway API. This is a cluster-scoped resource.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: novaedge
spec:
controllerName: novaedge.io/gateway-controller
description: "NovaEdge Gateway API implementation with integrated VIP, LB, and policy support"
Step 2: NovaEdge VIP (Infrastructure Team)¶
The Gateway API Gateway resource maps to the NovaEdge VIP for external IP allocation:
apiVersion: novaedge.io/v1alpha1
kind: ProxyVIP
metadata:
name: gateway-api-vip
spec:
address: "10.200.0.100/32"
mode: BGP
addressFamily: ipv4
ports:
- 80
- 443
- 5432
- 6379
bgpConfig:
localAS: 64501
routerID: "10.0.0.1"
peers:
- address: "10.0.0.254"
as: 64500
bfd:
enabled: true
detectMultiplier: 3
desiredMinTxInterval: "300ms"
requiredMinRxInterval: "300ms"
Step 3: Gateway (Infrastructure Team)¶
The Gateway defines listeners (ports, protocols, TLS) and references the NovaEdge VIP via an annotation or the infrastructure field.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: api-gateway
namespace: gateway-system
annotations:
novaedge.io/vip-ref: "gateway-api-vip"
spec:
gatewayClassName: novaedge
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard-tls
namespace: gateway-system
allowedRoutes:
namespaces:
from: All
- name: tcp-postgres
protocol: TCP
port: 5432
allowedRoutes:
namespaces:
from: Same
kinds:
- kind: TCPRoute
- name: tls-redis
protocol: TLS
port: 6379
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: Same
kinds:
- kind: TLSRoute
Step 4: HTTPRoute (Application Team)¶
HTTPRoute provides expressive L7 routing with path matching, header matching, traffic splitting, and request/response manipulation.
Basic Path-Based Routing¶
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-frontend
namespace: store
spec:
parentRefs:
- name: api-gateway
namespace: gateway-system
sectionName: https
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: store-frontend-svc
port: 80
weight: 1
Path + Header Matching with Traffic Splitting (Canary)¶
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-api
namespace: store
spec:
parentRefs:
- name: api-gateway
namespace: gateway-system
sectionName: https
hostnames:
- "store.example.com"
rules:
# Canary: route 10% of /api traffic to v2
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: store-api-v1
port: 8080
weight: 90
- name: store-api-v2
port: 8080
weight: 10
# Header-based routing: beta users go to v2
- matches:
- path:
type: PathPrefix
value: /api
headers:
- name: X-Beta-User
value: "true"
backendRefs:
- name: store-api-v2
port: 8080
URL Rewrite and Redirect¶
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-redirects
namespace: store
spec:
parentRefs:
- name: api-gateway
namespace: gateway-system
sectionName: https
hostnames:
- "store.example.com"
rules:
# Rewrite /shop/* to /store/*
- matches:
- path:
type: PathPrefix
value: /shop
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /store
backendRefs:
- name: store-frontend-svc
port: 80
# Redirect old domain
- matches:
- path:
type: PathPrefix
value: /old-path
filters:
- type: RequestRedirect
requestRedirect:
hostname: store.example.com
path:
type: ReplacePrefixMatch
replacePrefixMatch: /new-path
statusCode: 301
Request/Response Header Modification¶
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store-api-headers
namespace: store
spec:
parentRefs:
- name: api-gateway
namespace: gateway-system
sectionName: https
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-Proto
value: https
- name: X-Gateway
value: novaedge
remove:
- X-Debug-Header
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: X-Served-By
value: novaedge
backendRefs:
- name: store-api-v1
port: 8080
Step 5: GRPCRoute (Application Team)¶
GRPCRoute provides native gRPC routing by service and method name.
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
name: grpc-services
namespace: store
spec:
parentRefs:
- name: api-gateway
namespace: gateway-system
sectionName: https
hostnames:
- "grpc.example.com"
rules:
# Route by gRPC service name
- matches:
- method:
service: store.ProductService
backendRefs:
- name: product-grpc-svc
port: 9090
- matches:
- method:
service: store.OrderService
backendRefs:
- name: order-grpc-svc
port: 9090
# Route specific method to a different backend
- matches:
- method:
service: store.OrderService
method: StreamUpdates
backendRefs:
- name: order-streaming-svc
port: 9090
Step 6: TCPRoute (Platform Team)¶
TCPRoute provides L4 TCP proxying for non-HTTP protocols.
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: postgres-route
namespace: gateway-system
spec:
parentRefs:
- name: api-gateway
sectionName: tcp-postgres
rules:
- backendRefs:
- name: postgresql
port: 5432
Step 7: TLSRoute (Platform Team)¶
TLSRoute provides TLS passthrough routing based on SNI, without terminating TLS.
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: redis-tls-route
namespace: gateway-system
spec:
parentRefs:
- name: api-gateway
sectionName: tls-redis
hostnames:
- "redis.internal.example.com"
rules:
- backendRefs:
- name: redis-cluster
port: 6379
Applying NovaEdge Policies to Gateway API Routes¶
NovaEdge ProxyPolicy resources can target Gateway API resources. The controller translates between the two systems.
# Rate limit on the Gateway (applies to all routes)
apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
name: gateway-rate-limit
namespace: gateway-system
spec:
type: RateLimit
targetRef:
kind: ProxyGateway
name: api-gateway
rateLimit:
requestsPerSecond: 1000
burst: 2000
key: "source-ip"
---
# JWT auth on a specific route
apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
name: store-api-jwt
namespace: store
spec:
type: JWT
targetRef:
kind: ProxyRoute
name: store-api
jwt:
issuer: "https://auth.example.com"
audience:
- "store.example.com"
jwksUri: "https://auth.example.com/.well-known/jwks.json"
---
# WAF protection on the gateway
apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
name: gateway-waf
namespace: gateway-system
spec:
type: WAF
targetRef:
kind: ProxyGateway
name: api-gateway
waf:
enabled: true
mode: prevention
paranoiaLevel: 2
anomalyThreshold: 5
Ingress vs Gateway API Comparison¶
| Feature | Kubernetes Ingress | Gateway API |
|---|---|---|
| API stability | Stable (v1) | Stable (v1) for core; alpha for TCP/gRPC |
| Role separation | Single resource, one owner | GatewayClass/Gateway (infra) + Routes (app) |
| Path matching | Prefix, Exact | Prefix, Exact, RegularExpression |
| Header matching | No | Yes |
| Query parameter matching | No | Yes |
| Method matching | No | Yes |
| Traffic splitting (canary) | No | Yes (weighted backendRefs) |
| Request mirroring | No | Yes |
| URL rewrite | No (annotation hack) | Yes (native filter) |
| Request/response header mod | No (annotation hack) | Yes (native filter) |
| Redirect | Annotation-based | Yes (native filter) |
| gRPC routing | Annotation-based | GRPCRoute (native service/method) |
| TCP routing | Not supported | TCPRoute |
| TLS passthrough | Annotation-based | TLSRoute |
| Cross-namespace routing | No | Yes (with ReferenceGrant) |
| Multiple implementations | One controller per class | Multiple GatewayClasses |
| Extensibility | Annotations (non-portable) | Policy attachment (portable) |
| NovaEdge VIP integration | Via ProxyGateway ingressClassName | Via annotation on Gateway |
| NovaEdge policy attachment | Via ProxyPolicy targetRef | Via ProxyPolicy targetRef |
When to Use Which¶
| Scenario | Recommendation |
|---|---|
| Existing Ingress resources, need quick migration | Ingress with ingressClassName: novaedge |
| New project, want future-proof routing | Gateway API |
| Need gRPC-native routing by service/method | Gateway API (GRPCRoute) |
| Need L4 TCP/TLS passthrough | Gateway API (TCPRoute/TLSRoute) |
| Need traffic splitting for canary deployments | Gateway API (HTTPRoute weighted backends) |
| Need cross-namespace route sharing | Gateway API |
| Simple host+path routing, minimal config | Either works |
Verification¶
# Check GatewayClass is accepted
kubectl get gatewayclass novaedge
# Expected: ACCEPTED=True
# Check Gateway status
kubectl get gateway -n gateway-system api-gateway
# Expected: PROGRAMMED=True, addresses assigned
# Check Gateway listeners
kubectl describe gateway -n gateway-system api-gateway
# Look for: Listener status, attached routes count
# Check HTTPRoutes
kubectl get httproute -A
# Expected: Routes listed with parent refs resolved
# Check GRPCRoute
kubectl get grpcroute -A
# Check TCPRoute and TLSRoute
kubectl get tcproute -A
kubectl get tlsroute -A
# Check NovaEdge VIP backs the Gateway
kubectl get proxyvip gateway-api-vip
# Expected: Address assigned, BGP announcing nodes listed
# Test HTTP routing
curl -v https://store.example.com/ \
--resolve "store.example.com:443:10.200.0.100"
# Test canary traffic split (run multiple times, observe v1 vs v2 responses)
for i in $(seq 1 20); do
curl -s https://store.example.com/api/version \
--resolve "store.example.com:443:10.200.0.100"
done
# Test header-based routing
curl -v https://store.example.com/api/version \
-H "X-Beta-User: true" \
--resolve "store.example.com:443:10.200.0.100"
# Test gRPC routing
grpcurl -d '{}' -authority grpc.example.com \
10.200.0.100:443 store.ProductService/ListProducts
# Test TCP route (PostgreSQL)
psql -h 10.200.0.100 -p 5432 -U myuser -d mydb