As the cluster grows, IPs become a scarce resource. This episode covers Service capacity against the number of IPs, the ARP and BGP limits, large pool strategies, and how to avoid IP exhaustion and allocation fragmentation that complicates operations.

External IPs are the scarcest resource on a bare-metal cluster. Every LoadBalancer Service borrows one IP from a pool, and when the pool is empty, new Services will never get an IP — the symptom: an EXTERNAL-IP that never fills in. Episode 17 covers IP planning & network scale: calculating requirements, understanding the ARP and BGP limits, designing large pool strategies, and avoiding IP exhaustion and allocation fragmentation.
Good IP planning is done once and saves years of operations. Bad planning forces you to rebuild pools in the middle of production — an unpleasant experience. Let's do it right from the start.
Every LoadBalancer Service uses one IP from the pool. The basic requirement formula is simple:
Example: the pool 192.168.20.200-192.168.20.240 provides 41 IPs, enough for about 41 simultaneous Services. If you're planning 100 Services, you need more than 100 IPs — because maintenance and experiments also use IPs.
Don't guess when a pool is near full — monitor with the metrics from episode 11:
kubectl get svc -A -o wide | wc -l
kubectl get ipaddresspoolkubectl get svc -A -o wide | wc -l gives a sense of the number of Services; compare it with the pool's total capacity. For precise numbers, use the Prometheus metrics metallb_allocator_addresses_in_use_total versus metallb_allocator_addresses_total per pool.
In Layer 2 mode, a single leader node handles all traffic for an IP. The more Services whose leader lands on the same node, the heavier that node's load. Also, every IP is announced via ARP — the more IPs, the more ARP broadcast traffic on the network. At a certain scale, the limit isn't MetalLB but the capability of the node and the switches.
In BGP mode, every non-aggregated IP is advertised as a /32 route. A thousand Services means a thousand routes in the router's routing table. This is still considered reasonable for modern routers, but it carries two risks:
The solution is prefix aggregation (aggregationLength from episodes 8 and 16): with aggregation, hundreds of IPs are advertised as one prefix.
show ip bgp | wc -lshow ip bgp | wc -l on the router shows the number of received route lines. If this number bloats as Services increase, consider more aggressive aggregation or pool separation.
Two approaches for large scale:
For production, many small pools are almost always better. Per-Service pool selection uses the annotation we covered in episode 9.
apiVersion: metallb.io/v1beta2
kind: IPAddressPool
metadata:
name: apps-pool
namespace: metallb-system
spec:
addresses:
- 10.0.20.0/24
---
apiVersion: metallb.io/v1beta2
kind: IPAddressPool
metadata:
name: infra-pool
namespace: metallb-system
spec:
addresses:
- 10.0.30.0/24apps-pool and infra-pool separate application IPs from infrastructure IPs. Function-to-subnet mappings like this make IP allocation easy to predict just by looking at the address — very helpful when troubleshooting.
Released IPs (after a Service is deleted) can leave holes in the pool. If the controller always allocates the first free IP, a pool with many allocations and de-allocations can become fragmented — making patterns hard to recognize or efficient aggregation hard to apply.
Mitigation: assign IP blocks per function with discipline, avoid mixing many functions in one pool, and periodically monitor usage to spot strange patterns.
IP exhaustion isn't a sudden crisis — it's usually predictable. Ways to prevent it:
metallb_allocator_addresses_in_use_total per pool with alerts at a certain threshold, for example 80 percent.externalTrafficPolicy and Ingress (episode 12) to reduce per-application IP usage.Warning
Adding IPs to a pool already running in production is legitimate, but make sure the new subnet can be announced from the same nodes. For Layer 2, the new subnet must be ARP-reachable from the nodes; for BGP, make sure the router accepts the new prefix.
As a starting guideline: prepare a pool with a buffer of at least 20 percent above current needs, and plan additional subnets before the main pool hits 80 percent usage. These numbers give you time to plan without waiting for a crisis.
Episode 17 completes IP planning & network scale: calculating capacity, understanding the ARP and BGP limits, designing a many-pool strategy, and preventing IP exhaustion and allocation fragmentation.
Key takeaways:
metallb_allocator_addresses_in_use_total regularly.In the next episode, episode 18, we'll discuss GitOps & config as code — managing IPAddressPool, advertisements, and BGPPeer as code in a repository, applying them with Argo CD and Flux, configuration versioning, review flows, and rolling changes out gradually.