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
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
Understanding the Recommended Architecture
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
Key Recommendation: Always use LoadBalancer as a simple L4 entry point and let your Ingress controller handle all L7 functionality. Do not depend on the LoadBalancer for HTTP routing, SSL termination, or other L7 features.
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:
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:
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:
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:
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
Always Configure Health Checks:
Essential for production services
Required for externalTrafficPolicy: Local
Set realistic timeouts based on application behavior
Set Appropriate Timeouts:
Configure client timeouts for long-running requests
Consider application response times
Plan for slow clients
Use Internal LoadBalancers for Internal Services:
Reduce costs (no floating IP)
Better security (not exposed to internet)
Faster response times (no public network hop)
Restrict Access with Source Ranges:
Limit who can access your services
Use specific CIDRs instead of 0.0.0.0/0
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
Monitor and Log:
Monitor LoadBalancer health and performance
Check OCCM logs for issues
Set up alerts for LoadBalancer failures
Use Descriptive Names:
Name services clearly
Add labels for organization
Document LoadBalancer purpose
❌ Don'ts
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
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
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
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
Don't Expose Everything Externally:
Use internal LoadBalancers for internal-only services
External exposure increases attack surface
Follow principle of least privilege
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
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
Don't Skip Testing:
Test LoadBalancer access before production
Verify health checks work correctly
Test failover behavior
Validate timeout settings under load
Additional Resources
Related Topics
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?

