k3d
k3d copied to clipboard
Suggestion: integrate MetalLb into this project
Scope of your request
A way to expose load balanced services.
Describe the solution you'd like
MetalLb allows the usage of k3d with services of type LoadBalancer. It is not hard to configure and will expose container network IPs to the host. I believe it could be simple to integrate into this project.
Describe alternatives you've considered
Docs to show how people could do it themselves.
This is a working proof of concept to make the integration:
#!/bin/bash
set -euo pipefail
if ! kubectl get crd ipaddresspools.metallb.io &> /dev/null; then
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.11/config/manifests/metallb-native.yaml
sleep 60
fi
function create_address_range () {
BASE_IP=${1%/*}
IP_CIDR=${1#*/}
if [ "$IP_CIDR" -lt 8 ]; then
echo "Max range is /8."
return
fi
IP_MASK=$((0xFFFFFFFF << (32 - IP_CIDR)))
IFS=. read A B C D <<<"$BASE_IP"
IP=$(((B << 16) + (C << 8) + D))
IPSTARTNUM=$(((IP & IP_MASK) + 256))
IPSTART="$A".$(((IPSTARTNUM & 0xFF0000) >> 16)).$(((IPSTARTNUM & 0xFF00) >> 8)).$((IPSTARTNUM & 0x00FF))
IPENDNUM=$(((IPSTARTNUM | ~IP_MASK) & 0x7FFFFFFF))
IPEND="$A".$(((IPENDNUM & 0xFF0000) >> 16)).$(((IPENDNUM & 0xFF00) >> 8)).$((IPENDNUM & 0x00FF))
echo "$IPSTART-$IPEND"
}
CIDR_BLOCK=`docker network inspect k3d-mycluster --format '{{ (index .IPAM.Config 0).Subnet }}'`
ADDRESS_RANGE=`create_address_range "$CIDR_BLOCK"`
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- $ADDRESS_RANGE
EOF
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default-advertisement
namespace: metallb-system
EOF
After that, any LoadBalancer service created will get an IP from MetalLB and will be reachable from the host.
Hi @giggio , thanks for putting this up! I have two questions though:
-
K3s has a built-in servicelb that uses the host ports (IP of the K3s container) - is the problem with that just port-conflicts?
-
Will this work on MacOS/Windows where docker is in a VM and afaik the container IPs are not routable?
I like it as a feature, but doubt that it would make sense to have it in the k3d core. I'd love to see it as a plugin (once that system is there) or an add-on. I see this as easy as using your script as a post-start hook combined with auto-deploy manifests (or a basic kubectl apply) 🤔