Homelab
MetalLB Migration
Updating MetalLB IP Pool for Lab VLAN Access
Overview
This article updates the MetalLB IP pool from the Network VLAN range to the Lab VLAN range. After the Talos migration, services have LoadBalancer IPs that local devices can't reach - L2 ARP doesn't cross VLANs. This update restores local access.
| Tip: | Having trouble? See v1.3.0 for what your setup should look like after completing this article. |
Before You Begin
Prerequisites
- Tailscale Migration completed
What We're Setting Up
| Component | Before | After |
|---|---|---|
| Static pool | (none) | 192.168.10.40-49 (autoAssign: false) |
| Default pool | 192.168.1.40-79 | 192.168.10.50-79 |
| Service IPs | Network VLAN | Lab VLAN |
Like DHCP reservations, the static pool requires explicit IP requests via annotation - MetalLB won't auto-assign from it1. Services needing stable IPs (Plex, game servers) use static; others get dynamic assignment.
When the pool changes, MetalLB detects that existing service IPs are no longer valid and reassigns them from the new pool.
Update MetalLB Configuration
IPAddressPools
k8s/core/metallb/config/config.yaml:
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: static-pool
namespace: metallb-system
spec:
addresses:
- 192.168.10.40-192.168.10.49
autoAssign: false
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- 192.168.10.50-192.168.10.79
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
spec:
ipAddressPools:
- static-pool
- default-pool Commit Changes
git add k8s/core/metallb/config/config.yaml
git commit -m "feat(metallb): migrate IP pool to Lab VLAN"
git push Delete Old Pool
MetalLB's webhook rejects overlapping ranges. Delete the old pool before applying the new config:
kubectl delete ipaddresspool -n metallb-system default-pool Reconcile Flux
flux reconcile source git flux-system
flux reconcile kustomization metallb-config Verify Migration
Check Pools Updated
kubectl get ipaddresspool -n metallb-system Expected: Shows both static-pool and default-pool.
Check Service IPs
Once the pool is updated, services will reassign automatically:
kubectl get svc -A | grep LoadBalancer Expected: Services show IPs in the 192.168.10.x range.
Test Local Access
From a device on a Trusted VLAN (with Tailscale disabled):
# Get Plex IP
kubectl get svc -n plex
# Test connectivity
nc -zv <plex-ip> 32400 Expected: Connection succeeded.
Test Plex Streaming
From Apple TV or another Trusted device, open Plex and verify content plays at full quality (not 480p relay).
Next Steps
With MetalLB on the Lab VLAN, services have new IPs. Plex requires additional configuration for cross-VLAN direct play.
Resources
Footnotes
MetalLB, "Configuration," metallb.io. Accessed: Feb. 26, 2026. [Online]. Available: https://metallb.io/configuration/ ↩