Skip to main content
KubeLB provides support for Kubernetes Ingress resources, allowing you to expose HTTP and HTTPS applications. When you create an Ingress in your tenant cluster, KubeLB CCM automatically propagates it to the management cluster and configures the necessary routing.

How It Works

  1. Ingress Creation: You create an Ingress resource in your tenant cluster
  2. Service Creation: KubeLB CCM creates NodePort services for backends (if they don’t exist)
  3. Route Propagation: A Route CRD is created in the management cluster
  4. Envoy Configuration: KubeLB configures Envoy Gateway with the routing rules
  5. Status Sync: The Ingress status (with load balancer IP) is synced back to your cluster
KubeLB uses Envoy Gateway behind the scenes. Your Ingress resources are translated into Gateway API resources (Gateway and HTTPRoute) for advanced Layer 7 routing.

Basic Ingress

1

Create a Backend Service

First, create a service and deployment:
apiVersion: v1
kind: Service
metadata:
  name: web-app
  namespace: default
spec:
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: nginx:latest
        ports:
        - containerPort: 8080
2

Create an Ingress

Create an Ingress to expose your service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  namespace: default
spec:
  ingressClassName: kubelb
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80
Apply the manifest:
kubectl apply -f ingress.yaml
3

Wait for Load Balancer IP

Check the Ingress status:
kubectl get ingress web-ingress
You should see output like:
NAME          CLASS     HOSTS             ADDRESS        PORTS   AGE
web-ingress   kubelb    www.example.com   203.0.113.10   80      1m
4

Test Connectivity

Test the ingress:
curl -H "Host: www.example.com" http://203.0.113.10

Using Ingress Class

Specify the KubeLB ingress class to use KubeLB for routing:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: default
spec:
  ingressClassName: kubelb  # Specify KubeLB as the ingress controller
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80
The ingressClassName field is required if your CCM is configured with --use-ingress-class=true.

Multiple Hosts

Route traffic to different services based on hostname:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
  namespace: default
spec:
  ingressClassName: kubelb
  rules:
  # Route api.example.com to api service
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
  # Route www.example.com to web service
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
Both hosts will use the same load balancer IP. Configure DNS to point both hostnames to the IP.

Path-Based Routing

Route requests to different services based on URL path:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
  namespace: default
spec:
  ingressClassName: kubelb
  rules:
  - host: example.com
    http:
      paths:
      # Route /api/* to api service
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
      # Route /web/* to web service
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
      # Default route
      - path: /
        pathType: Prefix
        backend:
          service:
            name: default-service
            port:
              number: 80

Path Types

KubeLB supports three path types:
Matches based on URL path prefix:
paths:
- path: /api
  pathType: Prefix  # Matches /api, /api/, /api/v1, etc.
  backend:
    service:
      name: api-service
      port:
        number: 8080

TLS/HTTPS

Enable HTTPS for your Ingress:
1

Create TLS Secret

First, create a secret with your TLS certificate:
kubectl create secret tls my-tls-secret \\
  --cert=path/to/tls.crt \\
  --key=path/to/tls.key
Or create from a manifest:
apiVersion: v1
kind: Secret
metadata:
  name: my-tls-secret
  namespace: default
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-cert>
  tls.key: <base64-encoded-key>
2

Reference Secret in Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
  namespace: default
spec:
  ingressClassName: kubelb
  tls:
  - hosts:
    - secure.example.com
    secretName: my-tls-secret
  rules:
  - host: secure.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: secure-service
            port:
              number: 443
3

Test HTTPS

curl https://secure.example.com

Multiple TLS Certificates

Use different certificates for different hosts:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-tls-ingress
  namespace: default
spec:
  ingressClassName: kubelb
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-secret
  - hosts:
    - www.example.com
    secretName: www-tls-secret
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Annotations

Custom Annotations

Add custom annotations for advanced features:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: annotated-ingress
  namespace: default
  annotations:
    # External DNS integration
    external-dns.alpha.kubernetes.io/hostname: myapp.example.com
    external-dns.alpha.kubernetes.io/ttl: "300"
    
    # Cert-manager integration
    cert-manager.io/cluster-issuer: letsencrypt-prod
    cert-manager.io/common-name: myapp.example.com
spec:
  ingressClassName: kubelb
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80
See the DNS and Certificates guide for more details on external-dns and cert-manager integration.

Propagated Annotations

By default, KubeLB propagates certain annotations from your Ingress to the underlying Gateway and HTTPRoute resources. You can control this behavior using the Tenant configuration.

Default Backend

Specify a default backend for requests that don’t match any rules:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-with-default
  namespace: default
spec:
  ingressClassName: kubelb
  defaultBackend:
    service:
      name: default-backend
      port:
        number: 80
  rules:
  - host: example.com
    http:
      paths:
      - path: /app
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 8080
Requests to example.com/other will be routed to default-backend.

Understanding Route CRD for Ingress

When you create an Ingress, KubeLB creates a Route CRD:
apiVersion: kubelb.k8c.io/v1alpha1
kind: Route
metadata:
  name: <ingress-uid>
  namespace: <tenant-name>
  labels:
    kubelb.k8c.io/origin-name: web-ingress
    kubelb.k8c.io/origin-ns: default
    kubelb.k8c.io/origin-resource-kind: Ingress.networking.k8s.io
spec:
  endpoints:
  - addressesReference:
      kind: Addresses
      name: default
  source:
    kubernetes:
      resource:
        # Original Ingress spec embedded here
      services:
        # Backend services with NodePort details
status:
  resources:
    route:
      # Generated HTTPRoute status
    services:
      # Generated service statuses

NodePort Services

KubeLB automatically creates NodePort services for your Ingress backends:
# List services created by KubeLB
kubectl get svc -l kubelb.k8c.io/managed-by=kubelb
These services follow the naming pattern: <service-name>-kubelb-<hash>
KubeLB manages these NodePort services automatically. You should not modify or delete them manually.

Cross-Namespace References

Reference services in different namespaces:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cross-ns-ingress
  namespace: frontend
spec:
  ingressClassName: kubelb
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            # Service is in the backend namespace
            # Note: Ingress spec doesn't support namespace field
            # Service must be in the same namespace as Ingress
            port:
              number: 8080
Kubernetes Ingress spec doesn’t support cross-namespace service references. All services must be in the same namespace as the Ingress. Use Gateway API (HTTPRoute) for cross-namespace routing.

Verifying Ingress Status

Check Ingress status:
# Get Ingress details
kubectl get ingress web-ingress -o yaml

# Check events
kubectl describe ingress web-ingress

# View load balancer IP
kubectl get ingress web-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
From the management cluster:
# Check Route CRD
kubectl get routes -n <tenant-namespace>

# Get Route details
kubectl describe route <route-name> -n <tenant-namespace>

# Check generated HTTPRoute
kubectl get httproutes -n <tenant-namespace>

Cleanup

Deleting the Ingress automatically cleans up all associated resources:
kubectl delete ingress web-ingress
KubeLB will:
  • Remove the Route CRD from the management cluster
  • Delete generated NodePort services
  • Clean up HTTPRoute and Gateway resources

Troubleshooting

Check CCM logs:
kubectl logs -n kubelb -l app.kubernetes.io/name=kubelb-ccm
Check Route CRD:
kubectl get routes -n <tenant-namespace>
Common causes:
  • Wrong ingress class
  • CCM not running
  • Gateway not ready
Verify backend service:
kubectl get svc <service-name>
kubectl get endpoints <service-name>
Check pods are running:
kubectl get pods -l app=<your-app>
Verify path matching:
  • Ensure pathType is correct (Prefix vs Exact)
  • Check for trailing slashes
Verify TLS secret exists:
kubectl get secret my-tls-secret -o yaml
Check certificate is valid:
kubectl get secret my-tls-secret -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout
Verify hostname matches:
  • Certificate CN/SAN must match the Ingress hostname

Migration to Gateway API

Consider migrating from Ingress to Gateway API for advanced features:
  • Better support for protocols (HTTP/2, gRPC, TCP, UDP)
  • More flexible routing rules
  • Native support for cross-namespace references
  • Better traffic splitting capabilities
See the Gateway API guide for migration details.

Next Steps

Build docs developers (and LLMs) love