
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Running Kubernetes on bare metal with MetalLB solves the most common on-premises networking gap: the lack of native LoadBalancer support. Without it, Services of type LoadBalancer remain stuck in a pending state indefinitely because there is no cloud controller manager to provision external IPs. MetalLB fills this void by implementing a network load balancer that integrates directly with your physical network infrastructure.
Why Do You Need MetalLB for Kubernetes on Bare Metal?
In managed environments like EKS or GKE, creating a Service with type: LoadBalancer triggers an API call to the cloud provider, which provisions a proprietary load balancer and assigns an external IP. On self-managed infrastructure, whether in a Kathmandu data center or a home lab, this automation does not exist. The Kubernetes control plane has no mechanism to allocate IPs from your physical router's DHCP range or static assignments.
MetalLB acts as a network-aware controller that watches for these pending Services and assigns IPs from a pre-defined pool. It then advertises those IPs to the network so traffic reaches the correct nodes. For teams building production clusters with Kubespray or kubeadm, MetalLB is typically the first networking component installed after the CNI. Without it, you are forced to use NodePort services, which expose non-standard ports and create unnecessary security surface area, or rely on manual Ingress controller configurations that bypass standard Service abstractions.
How Do You Install and Configure MetalLB?
Installation requires two distinct steps: deploying the MetalLB components and defining the IP address pools. Never skip the configuration step; without an IPAddressPool, the controller runs but cannot assign addresses.
Deploy MetalLB Components
The recommended method in 2026 is Helm, which handles CRDs and version compatibility automatically. If you prefer raw manifests for audit compliance or air-gapped environments, the official YAML works identically.
# Add the MetalLB Helm repository
helm repo add metallb https://metallb.github.io/metallb
helm repo update
# Install MetalLB into its own namespace
helm install metallb metallb/metallb \
--namespace metallb-system \
--create-namespace \
--version 0.14.9
# Verify all pods reach Ready state
kubectl get pods -n metallb-system -w Wait until both the controller pod and all speaker daemonset pods show Running. The speakers must run on every node that should participate in load balancing; they handle the actual protocol advertisement.
Define IP Address Pools and Advertisement Methods
Create a manifest that specifies which IPs MetalLB can allocate and how to advertise them. This example reserves a block outside your DHCP scope:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: production-pool
namespace: metallb-system
spec:
addresses:
- 192.168.10.200-192.168.10.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2-advert
namespace: metallb-system
spec:
ipAddressPools:
- production-pool Apply this with kubectl apply -f metallb-config.yaml. Within seconds, any existing pending LoadBalancer Services will receive an IP from this range. For teams managing secrets and configuration securely, store this manifest in GitOps rather than applying manually.
Should You Use Layer 2 or BGP Mode?
This is the most consequential architectural decision when deploying Kubernetes on bare metal with MetalLB. The wrong choice causes silent failures under load or during node maintenance.
| Criteria | Layer 2 Mode | BGP Mode |
|---|---|---|
| Traffic Path | All traffic routes through single elected node | ECMP across all advertising nodes |
| Bandwidth Limit | Capped at one node's NIC capacity | Aggregated across all nodes |
| Failover Speed | ~10-30 seconds (ARP reannouncement) | Sub-second (BGP convergence) |
| Router Requirements | None (works with any switch) | BGP-capable router (Ubiquiti, MikroTik, Cisco) |
| Configuration Complexity | Minimal | Requires AS numbers, peer config |
| Best For | Dev/staging, low-traffic apps | Production, high-throughput workloads |
In practice, I default to BGP for any environment handling real user traffic. Layer 2 creates a bottleneck that defeats the purpose of having multiple nodes. However, if your routers do not support BGP or you lack administrative access to configure peering, Layer 2 remains functional for smaller deployments.
Configuring BGP Mode
BGP requires coordination between MetalLB and your router. Replace the L2Advertisement with a BGPAdvertisement and define peers:
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: router-peer
namespace: metallb-system
spec:
myASN: 64500
peerASN: 64501
peerAddress: 192.168.10.1
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: bgp-advert
namespace: metallb-system
spec:
ipAddressPools:
- production-pool Your router must be configured to accept BGP sessions from each node's IP using ASN 64500. Consult your router vendor's documentation for exact commands; MikroTik, Ubiquiti EdgeRouter, and VyOS all support this natively.
How Do You Troubleshoot Pending LoadBalancer Services?
When Services stay pending despite MetalLB running, the issue is almost always one of three things: exhausted IP pools, misconfigured advertisements, or speaker pod failures.
- Check IP allocation events: Run
kubectl describe svc <service-name>and look for MetalLB-related events. Messages like "no available IPs" indicate pool exhaustion. - Verify speaker health: Execute
kubectl get pods -n metallb-system. If any speaker pod is CrashLoopBackOff, check logs withkubectl logs -n metallb-system <speaker-pod>. Common causes include missing kernel modules (ip_vs) or firewall rules blocking ARP/BGP. - Validate pool configuration: Ensure the CIDR or range in
IPAddressPooldoes not overlap with DHCP scopes or other static assignments. Usekubectl get ipaddresspools -n metallb-system -o yamlto inspect. - Test connectivity: From a machine on the same VLAN, ping the assigned external IP. If unreachable in L2 mode, verify that the leader node's interface is up and that no host firewall blocks ICMP or the service port.
A frequent mistake in Nepal-based deployments involves VLAN tagging mismatches. If your bare metal nodes connect via tagged trunks but MetalLB expects untagged traffic, ARP announcements never reach clients. Always confirm the physical switch port configuration matches your CNI and MetalLB assumptions. For deeper diagnostics, integrate with your monitoring stack to track MetalLB metrics like metallb_allocator_addresses_in_use_total.
What Are the Production Best Practices for MetalLB?
Running MetalLB in production demands more than a working installation. These practices prevent outages during scaling and maintenance:
- Reserve IPs outside DHCP: Document your MetalLB ranges in IPAM tools or spreadsheets. Overlapping with DHCP causes intermittent connectivity loss when leases renew.
- Use separate pools per environment: Create distinct
IPAddressPoolresources for staging, production, and internal services. Apply namespace selectors to prevent accidental cross-environment allocation. - Enable strict ARP validation: In L2 mode, set
spec.nodeSelectoron speakers to exclude nodes without direct LAN access. This prevents virtualized or edge nodes from winning leader elections incorrectly. - Monitor speaker readiness: Alert on speaker pod restarts and BGP session flaps. A downed speaker in BGP mode withdraws routes immediately; in L2 mode, failover delays impact users.
- Version pinning: Always specify exact Helm chart versions in GitOps. MetalLB CRDs change between minor releases; unpinned installs can break during automated upgrades.
Final Steps for Reliable Bare Metal Load Balancing
Deploying Kubernetes on bare metal with MetalLB transforms self-managed clusters into platforms that match cloud-native ergonomics. Start with Layer 2 for validation, migrate to BGP before production traffic, and enforce IP reservation discipline from day one. Automate the configuration through GitOps to maintain audit trails and enable rapid recovery. If your team needs assistance designing compliant, observable bare metal infrastructure, reach out to discuss your specific requirements.