Configure MetalLB BGP service network

This commit is contained in:
2026-09-03 02:19:46 +01:00
parent 4cb6bc9ec4
commit 502de4fdf0
11 changed files with 186 additions and 173 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ metadata:
# Must fall inside the range in
# apps/metallb/templates/ipaddresspool.yaml, or MetalLB will never
# satisfy the request.
metallb.universe.tf/loadBalancerIPs: "192.168.1.241" # EDIT ME
metallb.io/loadBalancerIPs: "10.10.60.11"
spec:
type: LoadBalancer
selector:
+5 -8
View File
@@ -1,12 +1,9 @@
# MetalLB, installed like any other app: an Application pointing at
# apps/metallb, a Helm chart (see apps/metallb/Chart.yaml) that both pulls
# in the upstream MetalLB chart AND carries our own IPAddressPool and
# L2Advertisement as extra templates (apps/metallb/templates/). Once this
# syncs, the cluster can hand out real IP addresses to Services of type
# LoadBalancer — something bare-metal Kubernetes doesn't do on its own
# (that's normally a cloud provider's job). See docs/05-metallb.md for the
# full explanation and the setup questions you'll need to answer before
# this is actually useful.
# apps/metallb, a Helm chart (see apps/metallb/Chart.yaml) that pulls in the
# upstream chart and carries this cluster's IPAddressPool, BGPPeer, and
# BGPAdvertisement templates. Together they let the MikroTik route dedicated
# 10.10.60.x addresses to LoadBalancer Services—something bare-metal
# Kubernetes does not provide on its own. See docs/05-metallb.md.
#
# Everything — MetalLB's own resources (including its CRDs) and our two
# custom resources that depend on them — comes from this one Application,
+3 -3
View File
@@ -1,7 +1,7 @@
# An "umbrella" chart: it declares a dependency on the upstream MetalLB
# chart below, AND carries two templates of its own
# (apps/metallb/templates/) — the IPAddressPool and L2Advertisement that
# configure it. Argo CD detects this as a Helm source because a Chart.yaml
# chart below, AND carries three templates of its own
# (apps/metallb/templates/) — the IPAddressPool, BGPPeer, and
# BGPAdvertisement that configure it. Argo CD detects this as a Helm source because a Chart.yaml
# exists at this path, resolves the dependency, and syncs the combined
# rendered output as one Application — exactly like any other app in
# apps/. This is the real, working example of the Helm-based app pattern
@@ -0,0 +1,23 @@
# BGPAdvertisement tells MetalLB to announce allocated Service addresses as
# routes to the MikroTik peer defined in bgppeer.yaml. Unlike Layer 2 mode,
# the workers do not need an interface inside 10.10.60.0/24: the router learns
# that each allocated address is reachable through the Kubernetes nodes.
#
# `aggregationLength: 32` advertises only addresses that a Service actually
# owns, as individual IPv4 host routes. Advertising the whole /24 would make
# the router send every address in the pool toward the cluster, including
# unallocated ones.
#
# Sync wave 1 defers this custom resource until the MetalLB chart's CRDs and
# controllers from wave 0 are available.
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: default
namespace: metallb-system
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
ipAddressPools:
- default-pool
aggregationLength: 32
+27
View File
@@ -0,0 +1,27 @@
# Establishes one external BGP session from each labelled worker to the
# MikroTik RB5009. BGP (Border Gateway Protocol) lets the workers advertise
# service IP routes from the dedicated 10.10.60.0/24 range even though their
# own interfaces remain in 10.10.10.0/24.
#
# The node selector deliberately excludes the Raspberry Pi control planes.
# Both workers share private ASN 64520 and peer with the router's private ASN
# 64512. The router supports ECMP, so it can retain equal-cost routes through
# both workers when both advertise the same Service address.
#
# No BGP password is used on this trusted internal network. Never add one in
# plaintext here: this repository is public, so authentication would require
# a separately managed Kubernetes Secret.
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: mikrotik
namespace: metallb-system
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
myASN: 64520
peerASN: 64512
peerAddress: 10.10.10.1
nodeSelectors:
- matchLabels:
node-role.kubernetes.io/worker: worker
+7 -11
View File
@@ -1,14 +1,10 @@
# Tells MetalLB which IP addresses it's allowed to hand out to Services.
# Pick a small range on your LAN that nothing else will ever assign —
# especially your router's DHCP server. MetalLB doesn't coordinate with
# your router or DHCP server at all; it just answers network requests for
# whatever address a Service claims from this range. If it overlaps your
# DHCP range, you'll eventually get two devices claiming the same IP.
# Tells MetalLB which IP addresses it may assign to LoadBalancer Services.
# This is a dedicated routed service range, not the nodes' 10.10.10.0/24 LAN
# and not a DHCP pool. BGPAdvertisement announces only addresses actually in
# use, while the MikroTik accepts those routes from the two workers.
#
# >> Ask Claude to help you pick this range before editing it — it needs
# to know your LAN's subnet and DHCP range, which it can't guess.
# A typical home LAN answer looks like "my router hands out
# 192.168.1.100–192.168.1.199, so let's use 192.168.1.240–192.168.1.250."
# The first and last few addresses remain reserved for future network use.
# Argo CD takes .10 and the demo app takes .11; .12-.250 remain available.
#
# This file lives under apps/metallb/templates/ alongside MetalLB's own
# Helm-installed resources, rather than as a separate app, because it
@@ -26,4 +22,4 @@ metadata:
argocd.argoproj.io/sync-wave: "1"
spec:
addresses:
- 192.168.1.240-192.168.1.250 # EDIT ME — replace with your chosen range
- 10.10.60.10-10.10.60.250
@@ -1,19 +0,0 @@
# L2Advertisement is what actually makes addresses from the pool reachable:
# it tells MetalLB to answer ARP requests for whichever address a Service
# was given, from whichever node currently hosts that Service. This is
# "Layer 2 mode" — the simplest of MetalLB's two modes, and the right
# choice here since it needs no cooperation from your router (the
# alternative, BGP mode, does — worth knowing exists if you outgrow a
# single L2 segment, not needed for this setup).
# Same sync-wave reasoning as ipaddresspool.yaml — deferred to wave "1" so
# it applies after MetalLB's own chart resources are up.
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
ipAddressPools:
- default-pool