#!/usr/bin/env bash # MetalLB — makes `Service type: LoadBalancer` actually get an address. # The pool is derived from the kind Docker network at install time. # Notes: docs/notes/addons.md set -euo pipefail cd "$(dirname "$0")/.." source ./lib/config.sh load_config K="kubectl --context ${KUBECONTEXT}" # ── work out an address range ────────────────────────────────────────────── # kind hands node addresses out from the bottom of the subnet, so the top is # free. Taking a slice there avoids collisions with current and future nodes. subnet=$(docker network inspect kind \ -f '{{range .IPAM.Config}}{{.Subnet}} {{end}}' 2>/dev/null \ | tr ' ' '\n' | grep -E '^[0-9]+\.' | head -1) if [ -z "$subnet" ]; then echo " ! could not read the kind Docker network subnet" >&2 echo " (is the cluster up? MetalLB needs the network to exist first)" >&2 exit 1 fi base="${subnet%/*}"; prefix="${subnet#*/}" o1=$(echo "$base" | cut -d. -f1); o2=$(echo "$base" | cut -d. -f2) o3=$(echo "$base" | cut -d. -f3) case "$prefix" in 16) pool_start="${o1}.${o2}.255.200"; pool_end="${o1}.${o2}.255.250" ;; 24) pool_start="${o1}.${o2}.${o3}.200"; pool_end="${o1}.${o2}.${o3}.250" ;; *) # Guessing a range inside an unexpected prefix risks handing out # addresses that belong to something else. Say so instead. echo " ! kind network is $subnet — only /16 and /24 are handled" >&2 echo " set the pool by hand in ctrl/addons/metallb.sh" >&2 exit 1 ;; esac echo " kind network $subnet → pool ${pool_start}-${pool_end}" # ── install ──────────────────────────────────────────────────────────────── if $K get deployment -n metallb-system controller >/dev/null 2>&1; then echo " already installed" else $K apply -f "https://raw.githubusercontent.com/metallb/metallb/${METALLB_VERSION}/config/manifests/metallb-native.yaml" fi # `rollout status`, not `kubectl wait`: wait errors out while the pod doesn't exist yet. echo " waiting for the controller..." $K rollout status deployment/controller -n metallb-system --timeout=240s $K rollout status daemonset/speaker -n metallb-system --timeout=240s # The webhook rejects IPAddressPools until it is actually serving, and it comes # up a moment after the pod is Ready — so retry rather than fail the whole run # on a race that resolves itself in seconds. echo " configuring the address pool" for attempt in 1 2 3 4 5 6 7 8 9 10; do if $K apply -f - >/dev/null 2>&1 <&2 $K get pods -n metallb-system >&2 exit 1