πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Networking intermediate ⏱ 20 minutes K8s 1.28+

MetalLB Bare Metal Load Balancer

Deploy MetalLB for LoadBalancer services on bare-metal Kubernetes. L2 mode, BGP mode, IP address pools, and integration with Cilium and Gateway API.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Install MetalLB and configure an IPAddressPool with your available IPs. Choose L2 mode for simple setups (ARP-based, single node handles traffic) or BGP mode for production (announces routes to your network router, true load distribution).

The Problem

On bare-metal Kubernetes, type: LoadBalancer Services stay in Pending forever β€” there’s no cloud provider to create a load balancer. MetalLB fills this gap, providing LoadBalancer IP allocation for bare-metal, on-premises, and homelab clusters.

The Solution

Install MetalLB

helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace

L2 Mode (Simple)

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: production-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.1.200-192.168.1.220
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: production
  namespace: metallb-system
spec:
  ipAddressPools:
    - production-pool

BGP Mode (Production)

apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: router
  namespace: metallb-system
spec:
  myASN: 64500
  peerASN: 64501
  peerAddress: 192.168.1.1
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: production
  namespace: metallb-system
spec:
  ipAddressPools:
    - production-pool
  peers:
    - router

Use LoadBalancer Service

apiVersion: v1
kind: Service
metadata:
  name: web-app
  annotations:
    metallb.universe.tf/address-pool: production-pool
spec:
  type: LoadBalancer
  selector:
    app: web-app
  ports:
    - port: 80
      targetPort: 8080
graph TD
    subgraph L2 Mode
        CLIENT1[Client] -->|ARP| LEADER[Leader Node<br/>handles all traffic]
        LEADER --> POD1[Pod 1]
        LEADER --> POD2[Pod 2]
    end
    subgraph BGP Mode
        CLIENT2[Client] -->|BGP routes| ROUTER[Network Router]
        ROUTER --> N1[Node 1 β†’ Pod A]
        ROUTER --> N2[Node 2 β†’ Pod B]
        ROUTER --> N3[Node 3 β†’ Pod C]
    end

Common Issues

Service still Pending after MetalLB install: Check IP pool has available addresses: kubectl get ipaddresspool -n metallb-system. Ensure the IP range is on the same subnet as your nodes (L2 mode).

L2 mode: all traffic goes to one node: Expected behavior. L2 mode uses ARP β€” one node handles all traffic. For true load distribution, use BGP mode.

Best Practices

  • L2 for homelab/dev β€” simple, no router config needed
  • BGP for production β€” true load distribution across nodes
  • Separate pools for different service tiers
  • Don’t overlap pools with DHCP range β€” causes IP conflicts
  • Cilium can replace MetalLB β€” if already using Cilium, use its LB IPAM

Key Takeaways

  • MetalLB provides LoadBalancer Services on bare-metal Kubernetes
  • L2 mode is simple (ARP) but sends all traffic through one node
  • BGP mode distributes traffic across nodes via router integration
  • IPAddressPool defines available IPs; Advertisement controls how they’re announced
  • Essential for on-premises, homelab, and edge Kubernetes deployments
#metallb #load-balancer #bare-metal #bgp #l2
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens