Skip to main content
RunBook Academy

KubernetesCXII · Load Balancing on Bare MetalLoad balancing on bare metal

MetalLB L2 mode — ARP/NDP-based load balancing

Advanced⏱ ~16 minkubectlmetallb

What you'll learn

  • Use MetalLB L2 mode for ARP/NDP-based load balancing
  • Configure IPAddressPool and L2Advertisement
  • Reason about the limitations of L2 mode
  • Apply the operational discipline of L2 mode for small clusters

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

MetalLB L2 mode uses ARP/NDP to advertise Service IPs. This lesson walks the mechanism, the configuration, the limitations, and the discipline.

How L2 mode works

flowchart LR
    A[Service LoadBalancer] --> B[MetalLB Controller]
    B --> C["IPAddressPool: allocate IP"]
    C --> D["Speaker: DaemonSet"]
    D -->|ARP reply| E[Network switch]
    E -->|routes to| F[Node with the IP]
    F -->|kube-proxy| G[Service backend]
    G --> H[Pod]

The L2 mechanism:

  1. The MetalLB controller allocates an IP from the IPAddressPool.
  2. The Speaker (DaemonSet on every node) determines which node will respond to ARP for the IP.
  3. One node (the “leader” for the IP) responds to ARP requests with its MAC address.
  4. External traffic flows to that node.
  5. kube-proxy on the node distributes traffic to the Service backends (Pods).
  6. If the leader fails, another Speaker takes over (after ARP cache timeout).

The configuration

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: prod-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.100.0/24
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: prod-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - prod-pool
  interfaces:
    - eth0  # the interface to send ARP on

The configuration:

  • IPAddressPool. The range of IPs that can be assigned to LoadBalancer Services.
  • L2Advertisement. Binds the pool to L2 mode; specifies which interface to send ARP on.
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 8080

The Service requests a LoadBalancer; MetalLB allocates an IP from the pool and advertises it via ARP.

The Speaker

kubectl get pods -n metallb-system -l app=metallb
NAME                          READY   STATUS    RESTARTS   AGE
metallb-controller-xxxxx       1/1     Running   0          5m
metallb-speaker-xxxxx          1/1     Running   0          5m
metallb-speaker-yyyyy          1/1     Running   0          5m
metallb-speaker-zzzzz          1/1     Running   0          5m

The Speaker is a DaemonSet — one Pod per node. Each Speaker can take over an IP if the current leader fails.

The limitations

flowchart LR
    A[Limitations] --> B[Single-node bottleneck]
    A --> C[Slow failover]
    A --> D[No ECMP]
    A --> E[ARP cache timeout]
    C --> F[30-60 seconds]
    E --> F

The limitations:

  • Single-node bottleneck. All external traffic goes through one node.
  • Slow failover. When the leader node fails, ARP cache must time out (30-60 seconds) before another node takes over.
  • No ECMP. Multiple nodes cannot share the load simultaneously (unlike BGP mode with ECMP).

For small clusters, the limitations are acceptable. For production at scale, BGP mode is preferred.

The failover

flowchart LR
    A[Leader node fails] --> B[Other Speakers detect]
    B --> C[Wait for ARP cache timeout]
    C --> D[New leader takes over]
    D --> E[ARP reply from new leader]
    E --> F[Traffic flows to new leader]

The failover:

  1. The leader node fails (network, power, etc.).
  2. Other Speakers detect the failure (via member discovery).
  3. ARP cache on external devices must time out (30-60 seconds).
  4. A new leader takes over and responds to ARP.
  5. Traffic flows to the new leader.

The 30-60 second failover is acceptable for many workloads but unacceptable for high-availability production. BGP mode with BFD (Bidirectional Forwarding Detection) can failover in < 1 second.

Quiz

Knowledge check · 4 questions

  1. Q1. In MetalLB L2 mode, how many nodes carry the traffic for one Service IP?

  2. Q2. MetalLB L2 failover is bounded by how quickly ARP caches on the network update.

  3. Q3. Account for a 45-second outage after a node failure in MetalLB L2 mode and decide what to change.

    MetalLB runs in L2 mode with pool 192.168.100.0/24 and an L2Advertisement on eth0. The ingress Service holds 192.168.100.20. During a planned power test, node-3 is switched off; external clients see connection timeouts for about 45 seconds before traffic resumes. Separately, throughput to the address plateaus at roughly 1 Gb/s even though six nodes are running.

  4. Q4. In MetalLB L2 mode, how many nodes answer ARP for a given Service address at any one time, and what determines how long failover takes?

Passing score: 75%. Answers are checked in this browser.

The operational discipline

MetalLB L2 in production rests on five non-negotiable elements:

  • Document the IP pool. Which IPs are available for LoadBalancer Services.
  • Document the interfaces. Which interface carries ARP traffic.
  • Test failover. Disconnect a node; verify traffic flows to the new leader.
  • Monitor the Speakers. Alert on Pods that are not Ready.
  • Plan the migration to BGP. L2 is good for small clusters; BGP is for production at scale.

MetalLB L2 is the simplest bare metal LB. The discipline is to test failover and plan the migration to BGP when throughput requires it.