Kubernetes Service type LoadBalancer provisions an external load balancer via the cloud provider’s integration. On AWS, this creates an NLB. On GCP, a Network Load Balancer. On Azure, an Azure Load Balancer. On bare metal, no provider - use MetalLB or Cilium’s BGP. The team that uses cloud has automatic provisioning. The team that runs on-prem needs MetalLB or a similar solution.
Table of contents
- Service types compared
- LoadBalancer on AWS
- LoadBalancer on GCP
- On-prem: MetalLB
- The cost
- Alternative: Ingress
- Alternative: Gateway API
- FAQ
Service types compared
K8s Services have four types:
- ClusterIP: internal-only. Default.
- NodePort: exposes on each node’s IP at a static port (30000-32767).
- LoadBalancer: cloud-provisioned external LB.
- ExternalName: CNAME to external service.
The team that needs external traffic uses LoadBalancer (cloud) or NodePort + external LB (on-prem). The team that needs internal-only uses ClusterIP.
LoadBalancer on AWS
On EKS:
apiVersion: v1
kind: Service
metadata:
name: myapp
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
The team that uses EKS gets an NLB provisioned automatically. Cost: ~$20/month per NLB + data.
LoadBalancer on GCP
On GKE:
apiVersion: v1
kind: Service
metadata:
name: myapp
annotations:
cloud.google.com/load-balancer-type: External
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
The team that uses GKE gets a Network Load Balancer.
On-prem: MetalLB
MetalLB provides LoadBalancer services on bare metal:
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
Configure MetalLB in Layer 2 (ARP/NDP) or BGP mode. The team that runs on-prem clusters without a cloud LB uses MetalLB.
The cost
Cloud LBs cost per-hour + per-GB. AWS NLB: ~$0.0225/hour + $0.006/GB processed. GCP: similar. Azure: $0.025/hour + $0.005/GB. The team that creates many LoadBalancer services sees significant LB bills.
Alternative: Ingress
For HTTP/HTTPS, use Ingress (NGINX, Traefik, AWS ALB Ingress Controller) instead of multiple LoadBalancer services. One LB routes many services by hostname/path. The team that has multiple HTTP services uses Ingress + one LB.
Alternative: Gateway API
The newer Gateway API replaces Ingress as the recommended approach:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
The team that starts new projects uses Gateway API; the team with existing Ingress stays on Ingress for now.
FAQ
How long does LoadBalancer provisioning take?
1-3 minutes typically. The team that monitors kubectl get svc waits for the EXTERNAL-IP to appear.
Can I use LoadBalancer without a cloud provider?
No - the cloud provider’s controller does the provisioning. Use MetalLB on bare metal.
What’s the difference between LoadBalancer and NodePort?
LoadBalancer provisions an external LB (cloud or MetalLB). NodePort exposes on a static port on every node’s IP. LoadBalancer is usually preferred; NodePort is for when LoadBalancer isn’t available.
Is the LoadBalancer service’s IP static?
Cloud LBs typically have static IPs (you can configure). MetalLB IPs can be static (assigned from a pool) or DHCP-assigned.
Can I have TLS on a LoadBalancer service?
Not directly - the LB just forwards TCP. For TLS termination, use Ingress with TLS configured, or use a cloud LB with managed certificates.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: