MetalLB v0.16.0: FRR-K8s Takes the Wheel and BGP Gets a Promotion

| |

5 min read

MetalLB logo

MetalLB, the load balancer that gives bare-metal Kubernetes clusters real IP addresses, just shipped version v0.16.0 with a major architectural shift under the hood.

If you have ever run Kubernetes on your own hardware, you know the feeling. You set up a LoadBalancer service, and nothing happens. Cloud providers hand you an IP automatically, but bare-metal clusters just sit there, waiting. MetalLB is the project that fixes that. It hands out IP addresses from a pool you define and advertises them to your network using either layer-2 ARP/NDP or BGP routing. Think of it as the bridge between your Kubernetes services and the actual network infrastructure sitting in your rack.

Platform engineers running on-premises clusters are the primary audience here. If your Kubernetes deployment lives in a data center rather than AWS or GCP, MetalLB is probably already in your Helm charts. And v0.16.0 is a release worth paying attention to, because the BGP backend you have been using is about to change.

FRR-K8s Is Now the Default BGP Backend

The biggest change in this release is architectural. FRR-K8s is now the default BGP mode, replacing the standalone FRR mode that MetalLB has used for years. The old FRR mode is officially deprecated and will be removed in a future release.

Why does this matter? The standalone FRR mode kept MetalLB’s BGP configuration in its own isolated world. You could not easily mix MetalLB’s routing with other FRR-based tools on the same cluster. FRR-K8s changes that by using a dedicated Kubernetes operator (PR #2965) to manage FRR, which means you can now merge additional FRR configuration and share BGP sessions with other actors on the node.

Think of it like moving from a private phone line to a shared office switchboard. Same conversations, but now everyone in the building can participate.

If you are currently using FRR mode, do not panic. It still works. But going forward, all new BGP features will land in FRR-K8s only. The native BGP implementation (no FRR dependency at all) remains available for deployments that need a smaller footprint.

# FRR-K8s is now the default, no config change needed for new installs
# Existing FRR mode users can continue with:
# METALLB_BGP_TYPE=frr
# (but start planning your migration)

Service Selectors for Advertisements

Before v0.16.0, when you created a BGPAdvertisement or L2Advertisement, it applied to all services in the selected IP address pools. There was no way to say "advertise these services but not those" within the same pool. That changes with the new ServiceSelector field on advertisement resources (PR #2917).

Now you can target specific services within a pool using label selectors. This is particularly useful in multi-tenant environments where different teams share an IP pool but have different advertisement requirements.

apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
  name: production-only
spec:
  ipAddressPools:
    - default-pool
  serviceSelector:
    matchLabels:
      environment: production

Services without the environment: production label will not be advertised by this rule, even if they draw from the same pool. Clean, predictable, and exactly what you needed.

Per-Peer Local ASN Override

BGP peering normally uses a single local ASN for all peers. But real networks are messy. Sometimes you need to present a different ASN to different peers, maybe because of a merger, a migration, or just a peculiar upstream requirement. The new localASN field on BGPPeer lets you override the local AS number on a per-peer basis (PR #2997).

Under the hood, this maps to FRR’s local-as <ASN> no-prepend replace-as command, which means the peer sees your overridden ASN as your actual AS number, not as a prepended path.

apiVersion: metallb.io/v1beta1
kind: BGPPeer
metadata:
  name: upstream-peer
spec:
  myASN: 64512
  localASN: 65500
  peerASN: 64513
  peerAddress: 10.0.0.1

Native TLS Replaces kube-rbac-proxy

The metrics endpoints that MetalLB exposes for Prometheus scraping have historically relied on kube-rbac-proxy for authentication and TLS termination. That external dependency is gone. MetalLB now implements native TLS and RBAC directly, with self-signed certificates generated automatically or custom certificates passed through configuration (PR #2979).

The old HTTP endpoints are no longer available. Everything is HTTPS now. If your Prometheus scrape configuration was pointing at plain HTTP, you will need to update it. This is a breaking change for monitoring setups that relied on the old unencrypted endpoints.

Configurable BGP Debounce Timeout

When BGP configuration changes, MetalLB does not reload FRR immediately. It waits a short debounce period to batch multiple changes into a single reload. Previously this timeout was hardcoded. Now you can tune it via the METALLB_BGP_DEBOUNCE_TIMEOUT environment variable or the bgp-debounce-timeout flag (PR #2952). The default remains 3000 milliseconds, which is sensible for most deployments. If you are running large clusters with rapid service churn, bumping this up can reduce FRR reload frequency.

Bug Fixes

  • L2 speaker election fix — L2 advertisements now correctly consider service selectors during speaker election, preventing wrong nodes from advertising services (PR #3014).
  • Kubernetes 1.36 CRD validation — ASN fields in CRD validation now use correct maximum values, fixing compatibility with Kubernetes v1.36.0 (PR #3035).
  • KubeVirt migration handling — The BGP controller now correctly handles endpoint health when IP addresses are reused during virtual machine migrations (PR #2908).
  • Allocation events — The AllocationFailed event now tells you when a pool has run out of IP addresses, instead of leaving you guessing (PR #2891).
  • BGP metrics — Session-down metrics in native BGP mode now correctly report peer addresses (PR #2879).
  • Speaker isolation — Speakers now only parse BGP resources that target them via node selectors, preventing one speaker’s misconfiguration from affecting others (PR #3026).

What This Means for You

If you are running MetalLB with the default FRR backend, v0.16.0 is the release where you start planning your migration to FRR-K8s. It is not urgent today, but the writing is on the wall. The FRR mode still works, but it will not receive new features. Upgrade at your own pace, but upgrade with intent.

The ServiceSelector and localASN features alone justify the upgrade for anyone running complex BGP topologies or multi-tenant clusters. And the native TLS change means your metrics endpoints are finally secure by default, even if it means updating your Prometheus config.

Learn More