When a Service becomes unreachable, you need a method, not guesswork. This episode lays out a MetalLB diagnostic flow: kubectl get svc, describe svc, events, speaker logs, and checking BGP routes on the router, then addressing common problems such as unassigned IPs, duplicate IPs, missing advertisement, failed peering, and upgrading from v0.15 to v0.16.

All of your MetalLB knowledge ultimately comes down to one practical question: what do you do when a Service becomes unreachable? Episode 19 lays out a structured diagnostic method — not a random collection of tricks, but a sequence that runs from the fastest to the deepest level.
The right method saves hours. Diagnosis starts at the surface (Service status), moves up to the network level (advertisement and routing), and ends with logs and metrics. This episode also covers common problems that recur across the community, including the v0.15-to-v0.16 migration that often takes people by surprise.
Start from the easiest place: Service status. This flow is almost always the opening move of a diagnosis:
kubectl get svc nginx
kubectl get svc nginx -o widekubectl get svc nginx -o wide shows TYPE, EXTERNAL-IP, and ports. The first question you must answer: has EXTERNAL-IP been filled in? If yes, the problem is at the advertisement level; if it's still <pending>, the problem is at the IP allocation level.
If the IP isn't filled in, kubectl describe svc gives the clearest hint:
kubectl describe svc nginx
kubectl get events --field-selector involvedObject.name=nginxkubectl get events --field-selector involvedObject.name=nginx shows messages like Allocated IP 192.168.1.200 or Failed to allocate IP. This message determines the direction of the next diagnostic step.
If the Service status is fine but access fails, move to the MetalLB components:
kubectl logs -n metallb-system -l component=speaker --tail=50
kubectl logs -n metallb-system -l component=controller --tail=50kubectl logs -n metallb-system -l component=speaker --tail=50 shows announcement lines or BGP peering errors. The controller log shows allocation decisions. These two logs answer the questions "has the speaker announced?" and "has the controller allocated?"
For BGP mode, the router side is the final witness:
show ip bgp
show ip bgp neighborsshow ip bgp shows the prefixes received from MetalLB. If a prefix is missing, check show ip bgp neighbors to inspect the peering session status — that's where a failed peering usually shows up.
The most common causes: no pool, a full pool, or a Service requesting the wrong pool annotation. Check in this order:
kubectl get ipaddresspool
kubectl get svc -A
kubectl describe svc nginxIf the pool exists and isn't full, check the Service events for the specific error message from the controller.
MetalLB won't hand out the same IP to two Services from the same pool. If two Services appear to share an IP, it's most likely because both took an IP from different, overlapping pools. Check the definition of every pool:
kubectl get ipaddresspool -o yamlkubectl get ipaddresspool -o yaml shows every pool definition. Look for overlapping ranges between pools — this is the most common cause of duplicates.
The IP is assigned but can't be reached over Layer 2. Check:
L2Advertisement reference the correct pool?If show ip bgp neighbors shows a session that never reaches Established, check:
myASN and peerASN.multiHop configuration if the peer is outside the subnet.Problems that often appear when upgrading between major versions:
The safe way: upgrade in staging, check the status of all resources with kubectl get, and only then upgrade production. Always keep the old version's manifests for rollback.
A few of the most useful performance indicators:
metallb_allocator_addresses_in_use_total).metallb_bgp_session_up).curl -s -o /dev/null -w "%{time_total}\n" http://192.168.1.200curl -s -o /dev/null -w "%{time_total}\n" http://192.168.1.200 measures total response time. Record this value as a baseline and compare against it whenever performance looks suspicious.
Episode 19 completes performance & troubleshooting: a diagnostic flow from Service status, component logs, to routes on the router, plus handling of the six common problems MetalLB users run into most often.
Key takeaways:
kubectl get svc and kubectl describe svc.kubectl get events shows allocation or failure messages from the controller.show ip bgp and show ip bgp neighbors are the witnesses on the router side.In the next episode, episode 20, we'll discuss the latest stable features in v0.16.x — the CRD v1beta2 refinements, pool management and observability, BGP and Layer 2 fixes, and the importance of upgrading because v0.15 has been end of life since May 2026.