Skip to main content
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:
  1. Resource Creation: You create an HTTPRoute or GRPCRoute in your tenant cluster
  2. CCM Propagation: KubeLB CCM watches the route and creates a corresponding Route CRD in the management cluster
  3. Envoy Configuration: KubeLB Manager configures Envoy Gateway in the management cluster
  4. Traffic Routing: Traffic flows through Envoy Gateway → KubeLB Envoy Proxy → tenant cluster nodes
  5. 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

1

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
2

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
3

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
4

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
5

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.

Header-Based Routing

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

Header Manipulation

Add Request Headers

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

Remove/Set Headers

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:
1

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
2

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
3

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
4

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-namespace>
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

Build docs developers (and LLMs) love