𝔩𝔢𝔩𝕠𝔭𝔢𝔷
Theme

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

What We're Setting Up

ComponentBeforeAfter
Static pool(none)192.168.10.40-49 (autoAssign: false)
Default pool192.168.1.40-79192.168.10.50-79
Service IPsNetwork VLANLab 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.

See: Plex LAN Configuration

Resources

Footnotes

  1. MetalLB, "Configuration," metallb.io. Accessed: Feb. 26, 2026. [Online]. Available: https://metallb.io/configuration/

Previous
Tailscale Migration