> For the complete documentation index, see [llms.txt](https://docs.cloud.olakrutrim.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/load-balancers.md).

# 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

{% hint style="info" %}
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.
{% endhint %}

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

```
Internet → LoadBalancer (L4 Entry Point) → Ingress Controller (L7 Logic) → Services → Pods
           └─ Simple port forwarding      └─ All L7 features here
```

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](http://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:

```yaml
# 1. Deploy ingress controller (e.g., NGINX) with LoadBalancer
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer  # Single LoadBalancer for all ingress traffic
  selector:
    app: ingress-nginx
  ports:
    - port: 80
      targetPort: 80
    - port: 443
      targetPort: 443

---

# 2. Create Ingress resources for L7 routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  ingressClassName: nginx
  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
```

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

{% hint style="warning" %}
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.
{% endhint %}

## Creating a LoadBalancer Service

### Basic LoadBalancer Service

Create a simple LoadBalancer service:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: my-web-app
  namespace: default
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
```

Apply the service:

```bash
kubectl apply -f loadbalancer-service.yaml
```

Check LoadBalancer status:

```bash
# Wait for external IP to be assigned
kubectl get service my-web-app -w

# Expected output for external LoadBalancer:
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
my-web-app   LoadBalancer   10.100.50.10   <pending>      80:32000/TCP   10s
my-web-app   LoadBalancer   10.100.50.10   203.0.113.45   80:32000/TCP   2m
                                           ↑
                                    Floating IP (public internet access)
```

Timeline: 2-5 minutes for LoadBalancer to be provisioned

For internal LoadBalancer:

```bash
# Internal LoadBalancer will show a private IP
NAME              TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
internal-service  LoadBalancer   10.100.50.20   10.200.5.10   80:32001/TCP   2m
                                                ↑
                                         VIP (private network only)
```

### Understanding Service Ports

```yaml
ports:
  - name: http
    protocol: TCP
    port: 80              # External port (LoadBalancer listens on)
    targetPort: 8080      # Pod port (application listens on)
    nodePort: 32000       # Node port (automatically assigned)
```

Port Mapping Flow:

```
External Request → LoadBalancer:80 → Node:32000 → Pod:8080
```

## 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):

```yaml
metadata:
  name: public-service
  # No annotation needed, external is 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):

```yaml
metadata:
  name: internal-service
  annotations:
    service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
```

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

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/connection-limit: "100000"
```

Default: -1 (unlimited)

Timeout Configuration

Member connection timeout (backend connection timeout):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-member-connect: "5000"
```

Member data timeout (backend read timeout):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-member-data: "50000"
```

Client data timeout (idle connection timeout):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-client-data: "50000"
```

TCP inspection timeout:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/timeout-tcp-inspect: "0"
```

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

### Load Balancing Algorithm

Choose how traffic is distributed:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
```

{% stepper %}
{% step %}

### ROUND\_ROBIN (default)

* Distributes requests evenly
* Simple and effective
* Good for most use cases
  {% endstep %}

{% step %}

### LEAST\_CONNECTIONS

* Sends to pod with fewest connections
* Good for long-lived connections
* Better for uneven request loads
  {% endstep %}

{% step %}

### SOURCE\_IP

* Same client → same backend
* Session persistence
* Good for stateful applications
  {% endstep %}

{% step %}

### SOURCE\_IP\_PORT

* Same client IP and port → same backend
* Enhanced session persistence
  {% endstep %}
  {% endstepper %}

Example:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: session-app
  annotations:
    loadbalancer.openstack.org/lb-method: "SOURCE_IP"
spec:
  type: LoadBalancer
  selector:
    app: session-app
  ports:
    - port: 80
      targetPort: 8080
```

### Health Check Configuration

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

Enable Health Monitor:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
```

Default: If not specified, platform default behavior applies

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

Health Check Parameters:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
    loadbalancer.openstack.org/health-monitor-max-retries-down: "3"
```

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

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "5"
    loadbalancer.openstack.org/health-monitor-timeout: "3"
```

* Simply checks if TCP connection can be established
* Good for most TCP services

HTTP Health Check (automatic for HTTP listeners):

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
```

* 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.

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/x-forwarded-for: "true"
```

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:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: internal-api
spec:
  type: LoadBalancer
  loadBalancerSourceRanges:
    - "10.0.0.0/8"
    - "192.168.0.0/16"
  selector:
    app: api
  ports:
    - port: 8080
      targetPort: 8080
```

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:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/hostname: "myapp.example.com"
```

Use case: Enable PROXY protocol with custom DNS

Filter Target Nodes:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/node-selector: "env=production,region=east"
```

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)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: public-web
  namespace: production
  annotations:
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
    loadbalancer.openstack.org/timeout-client-data: "300000"  # 5 minutes
spec:
  type: LoadBalancer
  selector:
    app: web
    tier: frontend
  ports:
    - name: http
      port: 80
      targetPort: 8080
      protocol: TCP
    - name: https
      port: 443
      targetPort: 8443
      protocol: TCP
```

### Example 2: Internal Microservice (Private Network)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: internal-api
  namespace: backend
  annotations:
    service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
    loadbalancer.openstack.org/lb-method: "LEAST_CONNECTIONS"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
spec:
  type: LoadBalancer
  loadBalancerSourceRanges:
    - "10.0.0.0/8"
  selector:
    app: api
    tier: backend
  ports:
    - name: api
      port: 8080
      targetPort: 8080
      protocol: TCP
```

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

```yaml
apiVersion: v1
kind: Service
metadata:
  name: session-app
  namespace: applications
  annotations:
    loadbalancer.openstack.org/lb-method: "SOURCE_IP"
    loadbalancer.openstack.org/timeout-client-data: "3600000"  # 1 hour
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
spec:
  type: LoadBalancer
  selector:
    app: session-app
  ports:
    - port: 80
      targetPort: 3000
```

### Example 4: High-Performance API (Connection Limits)

```yaml
apiVersion: v1
kind: Service
metadata:
  name: high-perf-api
  namespace: production
  annotations:
    loadbalancer.openstack.org/lb-method: "LEAST_CONNECTIONS"
    loadbalancer.openstack.org/connection-limit: "500000"
    loadbalancer.openstack.org/timeout-member-connect: "3000"
    loadbalancer.openstack.org/timeout-member-data: "30000"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "5"
    loadbalancer.openstack.org/health-monitor-timeout: "3"
    loadbalancer.openstack.org/health-monitor-max-retries: "3"
spec:
  type: LoadBalancer
  selector:
    app: api
    performance: high
  ports:
    - port: 443
      targetPort: 8443
      protocol: TCP
```

### Example 5: HTTP Service with X-Forwarded-For

```yaml
apiVersion: v1
kind: Service
metadata:
  name: web-app-xff
  namespace: production
  annotations:
    loadbalancer.openstack.org/x-forwarded-for: "true"
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
    loadbalancer.openstack.org/enable-health-monitor: "true"
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
```

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:

```yaml
metadata:
  annotations:
    loadbalancer.openstack.org/load-balancer-address: "10.230.159.141"
    loadbalancer.openstack.org/load-balancer-id: "c94b6e78-c7cc-4299-b68e-cbe9db80f51c"
```

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:

{% stepper %}
{% step %}

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

Example:

```bash
kubectl patch service my-service -p '{"spec":{"type":"NodePort"}}'
```

{% endstep %}

{% step %}

### 2. Remove the annotations before converting back

Example:

```bash
kubectl annotate service my-service \
  loadbalancer.openstack.org/load-balancer-address- \
  loadbalancer.openstack.org/load-balancer-id-
```

{% endstep %}

{% step %}

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

Example:

```bash
kubectl patch service my-service -p '{"spec":{"type":"LoadBalancer"}}'
```

{% endstep %}
{% endstepper %}

Alternative: Delete and recreate the Service:

```bash
# Export current service configuration
kubectl get service my-service -o yaml > service-backup.yaml

# Edit service-backup.yaml:
# - Change type to LoadBalancer
# - Remove load-balancer-address and load-balancer-id annotations

# Delete old service
kubectl delete service my-service

# Create new service
kubectl apply -f service-backup.yaml
```

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:

```bash
# Check the Service events for error messages
kubectl describe service <service-name>

# Look for Events section at the bottom of the output

# Events will show specific error messages about provisioning failures
```

{% stepper %}
{% step %}

### 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
  {% endstep %}

{% step %}

### Network or platform configuration issues

* Service events will show specific error details
* Contact Krutrim support with the event messages for assistance
  {% endstep %}
  {% endstepper %}

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:

```bash
# 1. Check pod status
kubectl get pods -l app=<your-app>

# 2. Check service endpoints
kubectl get endpoints <service-name>

# 3. Test from within cluster
kubectl run -it --rm debug --image=busybox --restart=Never -- sh
wget -O- http://<service-name>.<namespace>.svc.cluster.local

# 4. Check service configuration
kubectl get service <service-name> -o yaml
```

### Services with externalTrafficPolicy: Local

Special Requirements:

* Health monitors are required for externalTrafficPolicy: Local
* Without health monitor, traffic routing will fail

```yaml
apiVersion: v1
kind: Service
metadata:
  name: local-traffic-service
  annotations:
    loadbalancer.openstack.org/enable-health-monitor: "true"  # Required!
    loadbalancer.openstack.org/health-monitor-delay: "10"
    loadbalancer.openstack.org/health-monitor-timeout: "5"
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local  # Requires health monitor
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 8080
```

## Best Practices

### ✅ Do's

1. Always Configure Health Checks:

   * Essential for production services
   * Required for externalTrafficPolicy: Local
   * Set realistic timeouts based on application behavior

   ```yaml
   loadbalancer.openstack.org/enable-health-monitor: "true"
   loadbalancer.openstack.org/health-monitor-delay: "10"
   loadbalancer.openstack.org/health-monitor-timeout: "5"
   ```
2. Set Appropriate Timeouts:

   * Configure client timeouts for long-running requests
   * Consider application response times
   * Plan for slow clients

   ```yaml
   loadbalancer.openstack.org/timeout-client-data: "300000"  # 5 minutes
   loadbalancer.openstack.org/timeout-member-data: "60000"   # 1 minute
   ```
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)

   ```yaml
   service.beta.kubernetes.io/openstack-internal-load-balancer: "true"
   ```
4. Restrict Access with Source Ranges:

   * Limit who can access your services
   * Use specific CIDRs instead of 0.0.0.0/0

   ```yaml
   spec:
     type: LoadBalancer
     loadBalancerSourceRanges:
       - "10.0.0.0/8"
       - "203.0.113.0/24"
   ```
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

* Official OpenStack CCM Documentation:
  * <https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/openstack-cloud-controller-manager/expose-applications-using-loadbalancer-type-service.md#service-annotations>
* Kubernetes Documentation:
  * <https://kubernetes.io/docs/concepts/services-networking/service/>
  * <https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer>
  * <https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip>

## 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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cloud.olakrutrim.com/basics/core-infrastructure/krutrim-kubernetes-system/load-balancers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
