KubernetesCXII · Load Balancing on Bare MetalLoad balancing on bare metal
Integration with VyOS and BIRD — router-side BGP configuration
What you'll learn
- Configure BGP on a VyOS router for MetalLB
- Configure BGP on a BIRD-based Linux router for MetalLB
- Apply BFD for fast failover
- Apply the operational discipline of documenting the router configuration
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
The router side of MetalLB BGP requires careful configuration. This lesson walks VyOS and BIRD configuration, BFD, and the operational discipline.
VyOS BGP configuration
# /config/config.boot on the VyOS router
configure
# Define the BGP AS and router ID
set protocols bgp 64512 parameters router-id 192.168.1.1
# Define the MetalLB peer
set protocols bgp 64512 neighbor 192.168.100.10 remote-as 64513
set protocols bgp 64512 neighbor 192.168.100.11 remote-as 64513
set protocols bgp 64512 neighbor 192.168.100.12 remote-as 64513
# Prefix list: only accept MetalLB-originated routes
set policy prefix-list METALLB rule 10 action permit
set policy prefix-list METALLB rule 10 prefix 192.168.100.0/24
# Route map: set local-preference based on community
set policy route-map METALLB-IN rule 10 action permit
set policy route-map METALLB-IN rule 10 set local-preference 200
set policy route-map METALLB-IN rule 10 match community METALLB-COMM
# Community list
set policy community-list METALLB-COMM rule 10 action permit
set policy community-list METALLB-COMM rule 10 regex '64513:.*'
# Apply the route map to the MetalLB peers
set protocols bgp 64512 neighbor 192.168.100.10 route-map import METALLB-IN
set protocols bgp 64512 neighbor 192.168.100.11 route-map import METALLB-IN
set protocols bgp 64512 neighbor 192.168.100.12 route-map import METALLB-IN
# BFD for fast failover
set protocols bgp 64512 neighbor 192.168.100.10 bfd
set protocols bgp 64512 neighbor 192.168.100.11 bfd
set protocols bgp 64512 neighbor 192.168.100.12 bfd
commit
save
The VyOS configuration:
- BGP AS 64512. The router’s AS.
- Neighbors. Each MetalLB Speaker as a BGP neighbor.
- Prefix list. Only accept routes in the MetalLB pool.
- Route map. Set local-preference based on community.
- BFD. Sub-second failover.
BIRD BGP configuration
# /etc/bird/bird.conf on a BIRD-based router
router id 192.168.1.1;
protocol bgp metallb {
local as 64512;
neighbor 192.168.100.10 as 64513;
neighbor 192.168.100.11 as 64513;
neighbor 192.168.100.12 as 64513;
import filter {
if net ~ 192.168.100.0/24 then {
bgp_community.add((64513, 100));
bgp_local_pref = 200;
accept;
}
reject;
};
export filter {
if net ~ 192.168.0.0/16 then accept;
reject;
};
}
protocol bfd {
interface "eth0" {
min rx interval 50 ms;
min tx interval 50 ms;
multiplier 3;
};
}
BIRD configuration:
- protocol bgp metallb. The BGP protocol with the MetalLB peers.
- import filter. Accept only MetalLB-originated routes; set local-preference.
- export filter. Export local routes to the cluster.
- protocol bfd. BFD for fast failover.
Verification
# On the VyOS / BIRD router
show ip bgp summary
Neighbor V AS MsgRcvd MsgSent Up/Down State/PfxRcd
192.168.100.10 4 64513 124 118 00:30:21 5
192.168.100.11 4 64513 124 118 00:30:21 5
192.168.100.12 4 64513 124 118 00:30:21 5
All peers are up; 5 prefixes received from each.
show ip bgp
Network Next Hop Metric LocPrf Path
*> 192.168.100.0/24 192.168.100.10 0 200 64513 i
* 192.168.100.11 0 200 64513 i
* 192.168.100.12 0 200 64513 i
Three equal-cost paths (ECMP); traffic load-balances across all three nodes.
BFD verification
show bfd peers
OurAddr TheirAddr LU Detect Interval Multiplier
192.168.1.1 192.168.100.10 UP 150ms 50ms 3
192.168.1.1 192.168.100.11 UP 150ms 50ms 3
192.168.1.1 192.168.100.12 UP 150ms 50ms 3
BFD is up; detection interval is 150ms (3 × 50ms).
Quiz
Knowledge check · 4 questions
Q1. Why apply a prefix-list to the BGP session between routers and MetalLB speakers?
Q2. The router should accept only the prefixes agreed for the cluster's load-balancer pool.
Q3. Find why routes from a newly added MetalLB pool never appear on the router, and correct the inbound policy.
A second IPAddressPool, 192.168.101.0/24, is created for a new tenant. Services in that tenant receive addresses such as 192.168.101.5 and the metallb-system speaker logs show the prefix being advertised on all three sessions. On the VyOS router, `show ip bgp` lists nothing for 192.168.101.0/24 while the original 192.168.100.0/24 prefixes are present and installed. Clients outside the subnet cannot reach the new addresses.
Q4. On a VyOS router taking MetalLB routes, which two policy objects control what is accepted and what preference it gets, and which command verifies that BFD is up?
Passing score: 75%. Answers are checked in this browser.
The operational discipline
Router-side MetalLB BGP configuration rests on five non-negotiable elements:
- Prefix list. Only accept routes from the MetalLB pool.
- Route map. Apply local-preference based on community.
- BFD for fast failover. Sub-second failover with BFD.
- Verify BGP sessions.
show ip bgp summaryafter every change. - Document the configuration. In the runbook: ASNs, peers, prefix lists, communities, BFD.
The router configuration is the source of truth for traffic forwarding. Misconfigurations silently drop traffic; the discipline is to verify every change.