I added BGP to my homelab. There is no good operational reason to run an exterior gateway protocol across three machines in a cupboard, and I am at peace with that. But the bit that surprised me is that it actually solved a real problem, not just an imaginary one I invented to justify the fun.
The problem: I run a handful of services on Kubernetes and I wanted their LoadBalancer IPs reachable from the rest of the LAN without static routes I have to remember to update. MetalLB can speak BGP. My router runs FRR. So instead of pinning routes by hand every time a service moves, the cluster advertises the VIPs and the router learns them. When a node dies, the routes withdraw on their own. That is the whole pitch, and it is a good one.
Here is the FRR side on the router. Private ASNs, nothing routed to the outside world:
router bgp 64512
bgp router-id 10.0.0.1
neighbor 10.0.0.20 remote-as 64513
neighbor 10.0.0.20 description k8s-node-1
!
address-family ipv4 unicast
neighbor 10.0.0.20 activate
neighbor 10.0.0.20 soft-reconfiguration inbound
exit-address-family
MetalLB's BGP config is the mirror of that, advertising the service pool from ASN 64513 to the router's 64512. Once the session comes up you watch the VIPs appear:
vtysh -c 'show ip bgp summary'
vtysh -c 'show ip route bgp'
The first time a /32 for a LoadBalancer service showed up in the router's table, learned dynamically, having never typed it anywhere, I grinned like an idiot. It is the same feeling as the first time a CI pipeline went green without me babysitting it.
Is this overkill? Completely. For three hosts you could static-route the lot in five minutes and never think about it again. BGP brings its own failure modes: a misconfigured ASN and the session silently refuses to establish, a wrong prefix-list and you blackhole something. I spent a happy hour discovering that I had fat-fingered a neighbour address and the session was wedged in Active state, which in BGP terms means the opposite of active. Classic.
But the homelab is where I get to make professional mistakes cheaply. The thing I learned here, that withdrawn routes clean up after themselves and that Active means "trying and failing", I learned at home on Thursday night with nobody paged. That is worth more than the static routes ever cost me. And it does, genuinely, work better than what it replaced. Sometimes the silly option is also the correct one.