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) 🤔