init rig
This commit is contained in:
103
rig/ctrl/addons/metallb.sh
Executable file
103
rig/ctrl/addons/metallb.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
# MetalLB — makes `Service type: LoadBalancer` actually get an address.
|
||||
#
|
||||
# Why it matters here: real manifests use LoadBalancer, because a real cluster
|
||||
# has one. On a bare kind cluster those Services sit at EXTERNAL-IP <pending>
|
||||
# forever with no error anywhere — the deployment looks fine and simply is not
|
||||
# reachable. Without this, every such Service has to be edited to NodePort,
|
||||
# which means the local manifests stop matching the ones being modelled.
|
||||
#
|
||||
# The address pool is derived from the kind Docker network at install time, not
|
||||
# hardcoded: Docker picks that subnet, it differs between machines, and a pool
|
||||
# outside it is silently unroutable.
|
||||
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
|
||||
|
||||
# `kubectl wait` on a selector errors out immediately when nothing matches yet,
|
||||
# and right after apply the ReplicaSet has not created the pod — so it loses a
|
||||
# race it looks like it should win. `rollout status` waits for the Deployment
|
||||
# itself and handles the not-yet-created case.
|
||||
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 <<YAML
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: IPAddressPool
|
||||
metadata:
|
||||
name: default
|
||||
namespace: metallb-system
|
||||
spec:
|
||||
addresses:
|
||||
- ${pool_start}-${pool_end}
|
||||
---
|
||||
# Layer 2 mode: one node answers ARP for each address. No BGP peer needed, which
|
||||
# is what makes this work on a laptop.
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: L2Advertisement
|
||||
metadata:
|
||||
name: default
|
||||
namespace: metallb-system
|
||||
spec:
|
||||
ipAddressPools:
|
||||
- default
|
||||
YAML
|
||||
then
|
||||
echo " pool ready: ${pool_start}-${pool_end}"
|
||||
exit 0
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
|
||||
echo " ! the pool was rejected after 10 attempts — is the webhook up?" >&2
|
||||
$K get pods -n metallb-system >&2
|
||||
exit 1
|
||||
Reference in New Issue
Block a user