KubeLB provides Layer 7 load balancing using Kubernetes Gateway API resources. This enables advanced HTTP/gRPC routing features like hostname-based routing, path matching, header manipulation, and more.
How It Works
The Layer 7 routing flow works as follows:
Resource Creation : You create an HTTPRoute or GRPCRoute in your tenant cluster
CCM Propagation : KubeLB CCM watches the route and creates a corresponding Route CRD in the management cluster
Envoy Configuration : KubeLB Manager configures Envoy Gateway in the management cluster
Traffic Routing : Traffic flows through Envoy Gateway → KubeLB Envoy Proxy → tenant cluster nodes
Status Sync : Route status (with addresses) is synced back to your tenant cluster
KubeLB uses Envoy Gateway for Layer 7 routing. The Envoy Gateway is deployed in the management cluster and handles all HTTP/gRPC traffic.
Gateway API Resources
KubeLB supports the following Gateway API resources:
Gateway : Defines the load balancer configuration and listeners
HTTPRoute : Routes HTTP traffic based on hostname, path, headers, etc.
GRPCRoute : Routes gRPC traffic with method matching
See the Gateway API guide for detailed configuration.
HTTP Routing
Basic HTTPRoute
Create a Gateway
First, create a Gateway resource: apiVersion : gateway.networking.k8s.io/v1
kind : Gateway
metadata :
name : my-gateway
namespace : default
spec :
gatewayClassName : kubelb
listeners :
- name : http
protocol : HTTP
port : 80
allowedRoutes :
namespaces :
from : All
Deploy Backend Service
Create a backend service: apiVersion : v1
kind : Service
metadata :
name : api-backend
namespace : default
spec :
selector :
app : api
ports :
- port : 8080
targetPort : 8080
---
apiVersion : apps/v1
kind : Deployment
metadata :
name : api
namespace : default
spec :
replicas : 2
selector :
matchLabels :
app : api
template :
metadata :
labels :
app : api
spec :
containers :
- name : api
image : your-api:latest
ports :
- containerPort : 8080
Create HTTPRoute
Create an HTTPRoute to expose your service: apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : api-route
namespace : default
spec :
parentRefs :
- name : my-gateway
hostnames :
- "api.example.com"
rules :
- backendRefs :
- name : api-backend
port : 8080
Get Gateway Address
Wait for the Gateway to get an address: kubectl get gateway my-gateway
Output: NAME CLASS ADDRESS PROGRAMMED AGE
my-gateway kubelb 203.0.113.10 True 1m
Test Connectivity
Test the HTTP route: curl -H "Host: api.example.com" http://203.0.113.10
Path-Based Routing
Route traffic based on URL paths:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : path-routing
namespace : default
spec :
parentRefs :
- name : my-gateway
hostnames :
- "example.com"
rules :
# Route /api/* to api-backend
- matches :
- path :
type : PathPrefix
value : /api
backendRefs :
- name : api-backend
port : 8080
# Route /web/* to web-backend
- matches :
- path :
type : PathPrefix
value : /web
backendRefs :
- name : web-backend
port : 80
# Default route
- backendRefs :
- name : default-backend
port : 80
Path matches are evaluated in order. More specific paths should come first.
Route traffic based on HTTP headers:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : header-routing
namespace : default
spec :
parentRefs :
- name : my-gateway
hostnames :
- "api.example.com"
rules :
# Route traffic with "X-Version: v2" header to v2 backend
- matches :
- headers :
- name : X-Version
value : v2
backendRefs :
- name : api-v2
port : 8080
# Default to v1
- backendRefs :
- name : api-v1
port : 8080
Query Parameter Routing
Route based on query parameters:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : query-routing
namespace : default
spec :
parentRefs :
- name : my-gateway
rules :
- matches :
- queryParams :
- name : version
value : beta
backendRefs :
- name : beta-backend
port : 8080
- backendRefs :
- name : stable-backend
port : 8080
Method-Based Routing
Route based on HTTP method:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : method-routing
namespace : default
spec :
parentRefs :
- name : my-gateway
rules :
# Route POST/PUT/DELETE to write service
- matches :
- method : POST
- method : PUT
- method : DELETE
backendRefs :
- name : write-service
port : 8080
# Route GET to read service
- matches :
- method : GET
backendRefs :
- name : read-service
port : 8080
Traffic Splitting
Split traffic between multiple backends for canary deployments:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : canary-routing
namespace : default
spec :
parentRefs :
- name : my-gateway
hostnames :
- "api.example.com"
rules :
- backendRefs :
# 90% to stable version
- name : api-stable
port : 8080
weight : 90
# 10% to canary version
- name : api-canary
port : 8080
weight : 10
Add headers to requests:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : add-headers
namespace : default
spec :
parentRefs :
- name : my-gateway
rules :
- filters :
- type : RequestHeaderModifier
requestHeaderModifier :
add :
- name : X-Custom-Header
value : custom-value
- name : X-Request-ID
value : "%REQ(X-REQUEST-ID)%"
backendRefs :
- name : api-backend
port : 8080
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : modify-headers
namespace : default
spec :
parentRefs :
- name : my-gateway
rules :
- filters :
- type : RequestHeaderModifier
requestHeaderModifier :
set :
- name : X-Forwarded-Proto
value : https
remove :
- X-Internal-Header
- type : ResponseHeaderModifier
responseHeaderModifier :
add :
- name : X-Response-Time
value : "%RESPONSE_DURATION%"
backendRefs :
- name : api-backend
port : 8080
URL Rewriting
Rewrite request paths:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : rewrite-route
namespace : default
spec :
parentRefs :
- name : my-gateway
rules :
- matches :
- path :
type : PathPrefix
value : /api/v1
filters :
- type : URLRewrite
urlRewrite :
path :
type : ReplacePrefixMatch
replacePrefixMatch : /api/v2
backendRefs :
- name : api-v2
port : 8080
gRPC Routing
KubeLB supports native gRPC routing with GRPCRoute:
Create a Gateway with gRPC Support
apiVersion : gateway.networking.k8s.io/v1
kind : Gateway
metadata :
name : grpc-gateway
namespace : default
spec :
gatewayClassName : kubelb
listeners :
- name : grpc
protocol : HTTP
port : 80
allowedRoutes :
namespaces :
from : All
kinds :
- kind : GRPCRoute
Deploy gRPC Service
apiVersion : v1
kind : Service
metadata :
name : grpc-service
namespace : default
spec :
selector :
app : grpc-app
ports :
- port : 9000
targetPort : 9000
protocol : TCP
Create GRPCRoute
apiVersion : gateway.networking.k8s.io/v1
kind : GRPCRoute
metadata :
name : grpc-route
namespace : default
spec :
parentRefs :
- name : grpc-gateway
hostnames :
- "grpc.example.com"
rules :
- backendRefs :
- name : grpc-service
port : 9000
Test gRPC Connection
# Using grpcurl
grpcurl -plaintext -authority grpc.example.com \\ n 203.0.113.10:80 \\ n my.service.v1.MyService/MyMethod
Method-Based gRPC Routing
Route gRPC traffic based on service and method:
apiVersion : gateway.networking.k8s.io/v1
kind : GRPCRoute
metadata :
name : grpc-method-routing
namespace : default
spec :
parentRefs :
- name : grpc-gateway
rules :
# Route specific service to backend-v2
- matches :
- method :
service : my.service.v1.UserService
backendRefs :
- name : user-service-v2
port : 9000
# Route specific method
- matches :
- method :
service : my.service.v1.AuthService
method : Login
backendRefs :
- name : auth-service
port : 9000
# Default backend
- backendRefs :
- name : default-grpc
port : 9000
Understanding the Route CRD
When you create an HTTPRoute or GRPCRoute, KubeLB creates a Route CRD in the management cluster:
apiVersion : kubelb.k8c.io/v1alpha1
kind : Route
metadata :
name : <route-uid>
namespace : <tenant-name>
labels :
kubelb.k8c.io/origin-name : api-route
kubelb.k8c.io/origin-ns : default
kubelb.k8c.io/origin-resource-kind : HTTPRoute.gateway.networking.k8s.io
spec :
endpoints :
- addressesReference :
kind : Addresses
name : default
namespace : <tenant-name>
source :
kubernetes :
resource :
# The original HTTPRoute/GRPCRoute spec
services :
# Referenced backend services
status :
resources :
route :
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
name : api-route-generated
namespace : <tenant-name>
status :
# Status synced back to tenant cluster
Cross-Namespace Routing
Route to services in different namespaces:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : cross-ns-route
namespace : frontend
spec :
parentRefs :
- name : my-gateway
namespace : default
rules :
- backendRefs :
- name : api-service
namespace : backend # Different namespace
port : 8080
Ensure the Gateway’s allowedRoutes permits cross-namespace references: allowedRoutes :
namespaces :
from : All # or use selector
Timeouts
Configure request timeouts:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : timeout-route
namespace : default
spec :
parentRefs :
- name : my-gateway
rules :
- timeouts :
request : 30s
backendRequest : 25s
backendRefs :
- name : slow-backend
port : 8080
Retry Policy
Configure automatic retries:
apiVersion : gateway.networking.k8s.io/v1
kind : HTTPRoute
metadata :
name : retry-route
namespace : default
annotations :
# Envoy Gateway specific retry policy
gateway.envoyproxy.io/retry-on : "5xx,reset,connect-failure"
gateway.envoyproxy.io/num-retries : "3"
spec :
parentRefs :
- name : my-gateway
rules :
- backendRefs :
- name : api-backend
port : 8080
Troubleshooting
Check route status: kubectl get httproute api-route -o yaml
Look for conditions in status. Check Route CRD in management cluster: kubectl get routes -n < tenant-namespac e >
Check Gateway status: kubectl get gateway my-gateway -o yaml
Check Envoy Gateway service: kubectl get svc -n envoy-gateway-system
Check gateway events: kubectl describe gateway my-gateway
Verify backend service exists: kubectl get svc api-backend
Check backend pods are ready: kubectl get pods -l app=api
Check service endpoints: kubectl get endpoints api-backend
Next Steps