Automatically set MetalLB IP Addresses with kind

09 Jul 2023 in TIL

kind doesn't come with a Load Balancer implementation by default. MetalLB seems like the most commonly used load balancer, but I have to look up how to configure it every time.

That is, until I saw an awesome docker network inspect | yq hack that I'm adding here for posterity.

First, install MetalLB:

bash
kubectl apply -f \
https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml

Then extract the subnet from the kind network and use yq to set the spec.addresses value in the manifest before applying it:

js
echo "---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: example
namespace: metallb-system
spec:
addresses: [] # set by make target
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: empty
namespace: metallb-system
" | \
SUBNET=$(docker network inspect kind --format '{{ (index .IPAM.Config 0).Subnet }}') \
yq '(select(.kind == "IPAddressPool") | .spec.addresses[0]) = env(SUBNET)' | \
kubectl apply -f -

That's all! For a few more details, here's what gets returned by docker network inspect:

bash
❯ docker network inspect kind --format '{{ (index .IPAM.Config 0).Subnet }}'
172.18.0.0/16

And if I run kubectl get services we'll see an IP address of 172.18.0.0 which is in that range:

bash
❯ kubectl get services -n kong
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kong-controller-validation-webhook ClusterIP 10.96.92.13 <none> 443/TCP 105s
kong-gateway-admin NodePort 10.96.124.129 <none> 8444:30735/TCP 105s
kong-gateway-proxy LoadBalancer 10.96.66.27 172.18.0.0 80:31884/TCP,443:31329/TCP 105s