Load Balancers

Load Balancers allow you to expose your Kubernetes services to external traffic. This guide covers creating and configuring LoadBalancer services in Krutrim Kubernetes Service using OpenStack Cloud Controller Manager (OCCM).

What is a LoadBalancer Service?

A LoadBalancer service automatically provisions a cloud load balancer that routes external traffic to your application pods.

Benefits:

  • External Access: Expose services to the internet

  • Automatic Provisioning: Load balancer created automatically

  • Health Checking: Built-in health monitoring

  • High Availability: Traffic distributed across pods

Important: For Layer 7 (L7) features like HTTP path-based routing, host-based routing, SSL/TLS termination, and HTTP header manipulation, always use Kubernetes Ingress controllers (like HAProxy, Kong, NGINX, or Traefik) behind a LoadBalancer service. Do not rely on the LoadBalancer for L7 functionality — use it as a simple Layer 4 entry point to your Ingress controller.

How LoadBalancers Work in KKS

Krutrim Kubernetes Service uses OpenStack Cloud Controller Manager (OCCM) to manage LoadBalancer services:

┌─────────────────────────────────────────────────────────┐
│              Kubernetes LoadBalancer Service            │
└─────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│         OpenStack Cloud Controller Manager (OCCM)       │
│         (Managed by Krutrim platform)                   │
└─────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│          OpenStack Load Balancer (Octavia)              │
│          Created in your specified subnet               │
└─────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│   External LoadBalancer: Floating IP (public internet)  │
│   Internal LoadBalancer: Subnet IP (private only)       │
└─────────────────────────────────────────────────────────┘

IP Address Allocation

External LoadBalancers (Default):

  • Receive a VIP (Virtual IP) from the cluster subnet

  • Also get a Floating IP from the public IP pool (mapped to the VIP)

  • Accessible from the internet via the floating IP

  • Consume 1 IP from the cluster subnet

Internal LoadBalancers:

  • Receive a VIP (Virtual IP) from the cluster subnet

  • Only accessible within your VPC/private network

  • Consume 1 IP from the cluster subnet

Example: Your cluster subnet: 10.0.1.0/24 (for nodes, pods, and LoadBalancers)

  • 10 nodes use: 10 IPs

  • 5 external LoadBalancers: 5 IPs (each also gets a floating IP)

  • 3 internal LoadBalancers: 3 IPs

  • Total used: 18 IPs from cluster subnet

Floating IPs (for external LoadBalancers only):

  • Allocated from public IP pool

  • Mapped to LoadBalancer VIPs

  • 5 floating IPs for the 5 external LoadBalancers

Key Points:

  • LoadBalancers use IPs from your cluster subnet

  • Each LoadBalancer consumes 1 IP from the cluster subnet (for both internal and external)

  • External LoadBalancers get an additional floating IP for internet access (from public IP pool)

  • Plan your cluster subnet size to accommodate nodes, pods, and LoadBalancers

Layer 4 (L4) vs Layer 7 (L7) Load Balancing

Important: For any Layer 7 (L7) features, always use a Kubernetes Ingress controller - do not rely on the LoadBalancer for L7 functionality.

Layer 4 (L4) - Use LoadBalancer:

  • Use LoadBalancer as a simple entry point - based on IP address and TCP/UDP port only

  • Keep it simple: port forwarding to your Ingress controller or service

  • Fast and efficient for TCP/UDP traffic

  • Suitable for any TCP/UDP protocol (HTTP, HTTPS, database connections, etc.)

Layer 7 (L7) - Use Ingress Controllers:

  • Do not rely on LoadBalancer for L7 features

  • Use Ingress controllers for HTTP-based routing (URLs, headers, cookies)

  • Advanced routing: path-based, host-based, header-based

  • SSL/TLS termination at the Ingress controller level

  • HTTP features: redirects, rewrites, authentication

  • Full control over L7 behavior

Why Use Ingress Controllers for L7

Even though the underlying infrastructure may have L7 capabilities, always use Ingress controllers for L7 functionality.

Recommended Ingress Controllers:

  • NGINX Ingress Controller: Most popular, feature-rich

  • HAProxy Ingress: High performance, enterprise features

  • Kong Ingress: API gateway with plugins

  • Traefik: Modern, cloud-native, automatic service discovery

Architecture Pattern:

Example Use Cases:

  • Use LoadBalancer only (simple L4) when:

    • Exposing single service directly to the internet

    • Non-HTTP protocols (databases, custom TCP/UDP services)

    • Simple port-based forwarding

    • Maximum simplicity needed

  • Use LoadBalancer + Ingress (L4 + L7) when:

    • Any HTTP/HTTPS application requiring L7 features

    • Multiple services behind single IP

    • Path-based routing: /api/* → api-service, /web/* → web-service

    • Host-based routing: api.example.com → api-service, www.example.com → web-service

    • SSL/TLS termination needed

    • HTTP redirects, rewrites, authentication

    • Cost optimization (one LoadBalancer for many services)

    • This is the recommended pattern for HTTP services

Quick Start with Ingress:

Benefits of Using Ingress Controllers for L7:

  • Proper L7 Handling: Full HTTP protocol support with proper routing logic

  • Cost Savings: One LoadBalancer for many services instead of one per service

  • L7 Features: Path routing, host routing, SSL termination, rewrites, redirects

  • Flexibility: Easy to add/remove services without new LoadBalancers

  • Control: Full control over L7 behavior instead of relying on platform defaults

  • Standard: Kubernetes-native API with wide ecosystem support

Creating a LoadBalancer Service

Basic LoadBalancer Service

Create a simple LoadBalancer service:

Apply the service:

Check LoadBalancer status:

Timeline: 2-5 minutes for LoadBalancer to be provisioned

For internal LoadBalancer:

Understanding Service Ports

Port Mapping Flow:

LoadBalancer Annotations

OCCM supports extensive configuration through annotations. Below are commonly used annotations for Krutrim Cloud.

Note: Annotations that require OpenStack resource IDs (like floating-network-id, subnet-id, network-id, port-id, member-subnet-id) are managed by the Krutrim platform and should not be specified by users. The platform automatically configures the appropriate network resources.

Basic Annotations

Internal vs External LoadBalancer

External LoadBalancer (default):

  • Gets a VIP from the cluster subnet

  • Also gets a Floating IP from public IP pool (mapped to the VIP)

  • Accessible from the internet via floating IP

  • Consumes 1 IP from cluster subnet

Internal LoadBalancer (private network only):

  • Gets a VIP from the cluster subnet

  • Only accessible within your VPC

  • Consumes 1 IP from cluster subnet

Connection and Timeout Settings

Connection Limits

Max connections per LoadBalancer:

Default: -1 (unlimited)

Timeout Configuration

Member connection timeout (backend connection timeout):

Member data timeout (backend read timeout):

Client data timeout (idle connection timeout):

TCP inspection timeout:

Values: Milliseconds (e.g., 5000 = 5 seconds)

Load Balancing Algorithm

Choose how traffic is distributed:

1

ROUND_ROBIN (default)

  • Distributes requests evenly

  • Simple and effective

  • Good for most use cases

2

LEAST_CONNECTIONS

  • Sends to pod with fewest connections

  • Good for long-lived connections

  • Better for uneven request loads

3

SOURCE_IP

  • Same client → same backend

  • Session persistence

  • Good for stateful applications

4

SOURCE_IP_PORT

  • Same client IP and port → same backend

  • Enhanced session persistence

Example:

Health Check Configuration

Health monitors check backend pod health and automatically remove unhealthy pods from the load balancer pool.

Enable Health Monitor:

Default: If not specified, platform default behavior applies

Important: Health monitors are required for services with externalTrafficPolicy: Local

Health Check Parameters:

Parameters:

  • enable-health-monitor: Enable/disable health monitoring (default: platform default)

  • health-monitor-delay: Seconds between health checks (default: 10)

  • health-monitor-timeout: Health check timeout in seconds (default: 5)

  • health-monitor-max-retries: Consecutive successes to mark member healthy (default: 3)

  • health-monitor-max-retries-down: Consecutive failures to mark member down (default: 3)

Important Constraint: health-monitor-timeout must be less than health-monitor-delay

Health Check Types

TCP Health Check (default for TCP services):

  • Simply checks if TCP connection can be established

  • Good for most TCP services

HTTP Health Check (automatic for HTTP listeners):

  • Performs HTTP GET request

  • Checks for HTTP 200 response

  • Automatically used when X-Forwarded-For is enabled

X-Forwarded-For Header

Inserts client IP into HTTP headers for HTTP services.

Effects:

  • Forces creation of HTTP listener (instead of TCP)

  • Adds X-Forwarded-For header with client IP

  • Backend can read original client IP from header

Restrict Access to Specific IP Ranges

Restrict which client IPs can access your LoadBalancer service using the loadBalancerSourceRanges field in the Service spec:

Format: List of CIDR blocks in the Service spec

Requirements:

  • OpenStack Octavia API version >= v2.12

  • Ignored if Octavia doesn't support this feature

This field supports updates - you can modify it after Service creation

Additional Advanced Annotations

Set Custom Hostname:

Use case: Enable PROXY protocol with custom DNS

Filter Target Nodes:

Format: Comma-separated key=value pairs

  • All specified labels must match

  • Can specify key without value to check only for key existence

  • If not specified, all nodes are eligible targets

Common LoadBalancer Configurations

Example 1: Public Web Application (External with Health Checks)

Example 2: Internal Microservice (Private Network)

Example 3: Session-based Application (Source IP Affinity)

Example 4: High-Performance API (Connection Limits)

Example 5: HTTP Service with X-Forwarded-For

Effect: Creates HTTP listener that adds X-Forwarded-For header with client IP

Complete Annotation Reference

User-Configurable Annotations

The following annotations can be used by users to configure LoadBalancer behavior:

Annotation
Description
Example Value

service.beta.kubernetes.io/openstack-internal-load-balancer

Create internal LB

"true"

loadbalancer.openstack.org/lb-method

Load balancing algorithm

"ROUND_ROBIN", "LEAST_CONNECTIONS", "SOURCE_IP", "SOURCE_IP_PORT"

loadbalancer.openstack.org/enable-health-monitor

Enable health monitoring

"true"

loadbalancer.openstack.org/health-monitor-delay

Health check interval (seconds)

"10"

loadbalancer.openstack.org/health-monitor-timeout

Health check timeout (seconds)

"5"

loadbalancer.openstack.org/health-monitor-max-retries

Successes to mark healthy

"3"

loadbalancer.openstack.org/health-monitor-max-retries-down

Failures to mark down

"3"

loadbalancer.openstack.org/timeout-client-data

Client idle timeout (ms)

"50000"

loadbalancer.openstack.org/timeout-member-connect

Backend connect timeout (ms)

"5000"

loadbalancer.openstack.org/timeout-member-data

Backend read timeout (ms)

"50000"

loadbalancer.openstack.org/timeout-tcp-inspect

TCP inspection timeout (ms)

"0"

loadbalancer.openstack.org/connection-limit

Max connections

"100000", "-1" (unlimited)

loadbalancer.openstack.org/x-forwarded-for

Add X-Forwarded-For header

"true"

loadbalancer.openstack.org/node-selector

Node label selectors

"env=prod,region=east"

loadbalancer.openstack.org/hostname

Custom hostname

"myapp.example.com"

Changing Service Types

Converting from LoadBalancer to NodePort or ClusterIP

When you change a Service from type: LoadBalancer to type: NodePort or type: ClusterIP, the underlying OpenStack load balancer will be automatically deleted.

Important: If you want to convert the Service back to type: LoadBalancer, you must delete the following annotations from the Service:

Why is this necessary?

  • These annotations are automatically added by OCCM when a LoadBalancer is created

  • They point to the old (now deleted) LoadBalancer

  • If present when converting back to LoadBalancer type, OCCM will try to reuse the non-existent LoadBalancer

  • This will cause the Service to fail provisioning

Correct Procedure:

1

1. Change to NodePort/ClusterIP (LoadBalancer will be deleted)

Example:

2

2. Remove the annotations before converting back

Example:

3

3. Change back to LoadBalancer (new LoadBalancer will be created)

Example:

Alternative: Delete and recreate the Service:

Note: A new LoadBalancer will be created with a new IP address. Update your DNS records and client configurations accordingly.

Troubleshooting LoadBalancers

LoadBalancer Stuck in Pending

Symptoms:

  • Service external IP shows

  • LoadBalancer not created after 5+ minutes

Diagnosis Steps:

1

Invalid annotations

  • Review Service YAML for typos in annotation names

  • Verify annotation values are correct format

  • Remove unsupported annotations

  • Check service events for validation errors

2

Network or platform configuration issues

  • Service events will show specific error details

  • Contact Krutrim support with the event messages for assistance

If LoadBalancer remains in pending state:

  • Capture the output of kubectl describe service

  • Note any error messages in the Events section

  • Contact Krutrim support with the service description and events

LoadBalancer Created but Not Accessible

Symptoms:

  • External IP assigned

  • Cannot access service from internet or internal network

Diagnosis Steps:

Services with externalTrafficPolicy: Local

Special Requirements:

  • Health monitors are required for externalTrafficPolicy: Local

  • Without health monitor, traffic routing will fail

Best Practices

✅ Do's

  1. Always Configure Health Checks:

    • Essential for production services

    • Required for externalTrafficPolicy: Local

    • Set realistic timeouts based on application behavior

  2. Set Appropriate Timeouts:

    • Configure client timeouts for long-running requests

    • Consider application response times

    • Plan for slow clients

  3. Use Internal LoadBalancers for Internal Services:

    • Reduce costs (no floating IP)

    • Better security (not exposed to internet)

    • Faster response times (no public network hop)

  4. Restrict Access with Source Ranges:

    • Limit who can access your services

    • Use specific CIDRs instead of 0.0.0.0/0

  5. Choose the Right Load Balancing Algorithm:

    • ROUND_ROBIN: Default, good for stateless apps

    • LEAST_CONNECTIONS: Better for uneven request loads

    • SOURCE_IP: Required for session affinity

  6. Monitor and Log:

    • Monitor LoadBalancer health and performance

    • Check OCCM logs for issues

    • Set up alerts for LoadBalancer failures

  7. Use Descriptive Names:

    • Name services clearly

    • Add labels for organization

    • Document LoadBalancer purpose

❌ Don'ts

  1. Don't Over-Provision LoadBalancers:

    • Each LoadBalancer has a cost and consumes resources

    • Use Kubernetes Ingress controllers (NGINX, HAProxy, Kong, Traefik) for L7/HTTP routing

    • Treat LoadBalancers as L4 (transport layer) - use Ingress for L7 (application layer) features

    • One Ingress controller with one LoadBalancer can route to many services

    • Avoid creating separate LoadBalancers for each HTTP service

  2. Don't Rely on LoadBalancers for L7 Features:

    • Always use Ingress controllers for L7 functionality

    • LoadBalancer should be a simple L4 entry point only

    • For path-based routing, host-based routing, SSL termination → use Ingress controllers

    • Don't depend on LoadBalancer for HTTP routing, header manipulation, or SSL termination

  3. Don't Ignore Health Check Configuration:

    • Default values may not suit your application

    • Test health check behavior before production

    • Monitor health check failures

    • Required for externalTrafficPolicy: Local

  4. Don't Use Unrealistic Timeouts:

    • Too short → healthy pods marked as down

    • Too long → slow failure detection

    • Consider network latency

    • Allow for application warmup time

  5. Don't Expose Everything Externally:

    • Use internal LoadBalancers for internal-only services

    • External exposure increases attack surface

    • Follow principle of least privilege

  6. Don't Modify Platform-Managed Annotations:

    • Don't manually edit load-balancer-id

    • Don't set OpenStack resource IDs (network-id, subnet-id, etc.)

    • Platform manages these automatically

    • Modifying can break LoadBalancer functionality

  7. Don't Forget About Costs:

    • Floating IPs may have costs

    • LoadBalancers have ongoing costs

    • Clean up unused LoadBalancers

    • Use Ingress controllers to consolidate services behind one LoadBalancer

  8. Don't Skip Testing:

    • Test LoadBalancer access before production

    • Verify health checks work correctly

    • Test failover behavior

    • Validate timeout settings under load

Additional Resources

  • Using Ingress Controllers for L7 Load Balancing:

    • Recommended for all HTTP/HTTPS services: Use Kubernetes Ingress with controllers like NGINX, HAProxy, Kong, or Traefik

    • Do not rely on LoadBalancer for L7 features - use it only as a simple L4 entry point

    • LoadBalancer (L4) forwards traffic → Ingress Controller (L7) handles routing logic

    • Ingress provides full Layer 7 (L7) control: path-based routing, host-based routing, SSL/TLS termination, rewrites, redirects

    • Cost-effective: One LoadBalancer + Ingress controller can serve multiple services

  • Service Mesh: For advanced traffic management, consider service mesh solutions like Istio or Linkerd, which can work alongside LoadBalancer services.

  • Network Policies: Combine LoadBalancer services with Kubernetes Network Policies for comprehensive network security.

Last updated

Was this helpful?