Load Balancers
When you create a Kubernetes Ingress or Service, Spot automatically provisions a managed load balancer that distributes traffic to your pods. This provides an externally-accessible IP address that routes traffic to the correct ports on your cluster nodes. This doc talks about gen1 LB
which is applicable for Generation-1 Data-centers
and gen2 LB
which is applicable for Generation-2 Data-centers
.
Load Balancer Pricing:
$10 per month per load balancer. This includes:
- Simple pricing: Fixed cost regardless of traffic volume
- Managed infrastructure: Fully managed with no manual configuration required
- High availability: Built-in redundancy and automatic failover capabilities
- Standard protocols: Support for HTTP, HTTPS, TCP, and other standard protocols
Prerequisites:
Before you begin, ensure you have:
- A Rackspace Spot Kubernetes cluster (Cloudspace) running
kubectl
installed- Your cloudspace kubeconfig file downloaded and configured (Access your Cloudspace via kubectl)
Creating a Network Load Balancer Service:
Protocol Support
Rackspace Spot Load Balancers support multiple protocols. Choose the appropriate protocol based on your application needs:
- TCP: Default protocol for most applications (HTTP, HTTPS, database connections)
- UDP: For applications requiring UDP traffic (DNS, gaming, streaming, VoIP)
Basic HTTP/HTTPS LoadBalancer Service
To create an external load balancer for HTTP traffic, add type: LoadBalancer
to your Service manifest:
apiVersion v1
kind Service
metadata
name web-app-service
annotations
service.beta.kubernetes.io_load-balancer-source-ranges 0.0.0.0_0
spec
type LoadBalancer
selector
app web-app
ports
port80
targetPort8080
protocol TCP # TCP is used for HTTP traffic
port443
targetPort8443
protocol TCP # TCP is used for HTTPS traffic
UDP LoadBalancer Service
For applications that require UDP traffic (such as DNS servers, game servers, or streaming applications):
apiVersion v1
kind Service
metadata
name udp-app-service
annotations
service.beta.kubernetes.io_load-balancer-source-ranges 0.0.0.0_0
spec
type LoadBalancer
selector
app udp-app
ports
port53
targetPort5353
protocol UDP # Specify UDP for UDP-based applications
port1194
targetPort1194
protocol UDP # Example: OpenVPN UDP port
Creating via kubectl
You can alternatively create a LoadBalancer service using kubectl:
kubectl expose deployment my-app --port=80 --target-port=8080 \\
--name=my-app-service --type=LoadBalancer
Deploying Your Application:
Create a deployment to work with your LoadBalancer service:
apiVersion apps_v1
kind Deployment
metadata
name my-app
spec
replicas3
selector
matchLabels
app my-app
template
metadata
labels
app my-app
spec
containers
name my-app
image nginx latest
ports
containerPort8080
Finding Your Load Balancer IP:
Once your LoadBalancer Service is created, get the external IP address:
kubectl describe services my-app-service
Look for the LoadBalancer Ingress
field in the output, which contains your external IP address. It may take a few minutes for the load balancer to be provisioned and the IP address to be assigned.
You can also check the status with:
kubectl get services my-app-service
Configuration Options:
Traffic Policies
Control how traffic is distributed using externalTrafficPolicy
:
apiVersion v1
kind Service
metadata
name my-app-service
spec
type LoadBalancer
externalTrafficPolicy Local # or Cluster (default)
selector
app my-app
ports
port80
targetPort8080
- Cluster (default): Traffic may be routed to any healthy pod, potentially causing an extra network hop
- Local: Traffic is only routed to pods on the same node, preserving source IP but potentially causing uneven distribution
Generation 1 vs Generation 2 Load Balancers
Rackspace Spot offers two generations of load balancers depending on your data center region:
Feature | Gen1 Load Balancers | Gen2 Load Balancers |
---|---|---|
Protocols | HTTP, TCP, UDP | HTTP, TCP, UDP |
Source IP Preservation | X-Forwarded-For header only | X-Forwarded-For + PROXY protocol |
Access Lists (Source Ranges) | ✅ Supported | ✅ Supported |
HTTPS Support | ✅ Supported | ✅ Supported |
Regions | Gen1 data centers | Gen2 data centers (SJC-1, DFW-2) |
Source IP Preservation
By default, the original client source IP is obscured. To preserve client source IP, you have different options depending on your load balancer generation:
For Both Gen1 and Gen2 Load Balancers:
X-Forwarded-For Header Method:
apiVersion v1
kind Service
metadata
name my-app-service
annotations
loadbalancer.openstack.org/x-forwarded-for"true"
spec
type LoadBalancer
externalTrafficPolicy Local # Recommended for source IP preservation
selector
app my-app
ports
port80
targetPort8080
protocol TCP
⚠️ Note: X-Forwarded-For is limited to HTTP-based services only and does not work with HTTPS.
For Gen2 Load Balancers Only:
PROXY Protocol Method (Recommended):
apiVersion v1
kind Service
metadata
name my-app-service
annotations
loadbalancer.openstack.org/proxy-protocol"true"
spec
type LoadBalancer
externalTrafficPolicy Local
selector
app my-app
ports
port80
targetPort8080
protocol TCP
⚠️ Note: When enabling PROXY protocol, your application must be configured to handle PROXY protocol. See NGINX example configuration for reference.
Access Lists (Source Ranges)
Both Gen1 and Gen2 Load Balancers allow you to restrict external access by specifying allowed IP address ranges. This is useful for limiting access to internal networks or specific client IPs.
Method 1: Using loadBalancerSourceRanges (Recommended)
apiVersion v1
kind Service
metadata
name restricted-service
spec
type LoadBalancer
selector
app my-app
loadBalancerSourceRanges
# Allow internal network 192.168.0.0/24
# Allow specific IP 203.0.113.5/32
# Allow private network range 10.0.0.0/8
ports
port80
targetPort8080
protocol TCP
Method 2: Using annotations
apiVersion v1
kind Service
metadata
name restricted-service
annotations
service.beta.kubernetes.io/load-balancer-source-ranges"192.168.0.0/24,203.0.113.5/32"
spec
type LoadBalancer
selector
app my-app
ports
port80
targetPort8080
protocol TCP
Real-World Examples:
Example 1: Game Server (UDP)
For a multiplayer game server that uses UDP:
apiVersion v1
kind Service
metadata
name game-server-service
spec
type LoadBalancer
selector
app game-server
ports
name game-port
port7777
targetPort7777
protocol UDP
name query-port
port7778
targetPort7778
protocol UDP
Example 2: DNS Server (UDP)
For a custom DNS server:
apiVersion v1
kind Service
metadata
name dns-server-service
annotations
# Restrict access to specific networks
service.beta.kubernetes.io/load-balancer-source-ranges"10.0.0.0/8,172.16.0.0/12"
spec
type LoadBalancer
selector
app dns-server
ports
name dns-udp
port53
targetPort5353
protocol UDP
name dns-tcp
port53
targetPort5353
protocol TCP # DNS also supports TCP for large responses
Example 3: Mixed Protocol Service
For applications that need both TCP and UDP:
apiVersion v1
kind Service
metadata
name mixed-protocol-service
spec
type LoadBalancer
selector
app mixed-app
ports
name web-http
port80
targetPort8080
protocol TCP
name streaming
port8000
targetPort8000
protocol UDP
Clean Up:
To avoid charges, delete LoadBalancer services when no longer needed:
kubectl delete svc my-app-service
This removes the Kubernetes service and deprovisions the load balancer.
Monitoring and Troubleshooting:
Checking Service Status
Monitor your LoadBalancer service:
# Check service details
kubectl get svc my-app-service -o wide
# View service events
kubectl describe svc my-app-service
# Check endpoints
kubectl get endpoints my-app-service
Common Issues
- Pending External IP: If the external IP shows as
<pending>
, wait a few minutes for provisioning to complete - Connection timeouts: Verify your application is listening on the correct port and your Service
targetPort
matches the container port - 503 errors: Check that your pods are running and healthy
Best Practices
- Use health checks: Ensure your application responds to health check requests
- Monitor costs: Each LoadBalancer service costs $10/month, view pricing breakdown in the Cost Explorer
- Use meaningful names: Choose descriptive names for your services and load balancers