k3d icon indicating copy to clipboard operation
k3d copied to clipboard

Suggestion: integrate MetalLb into this project

Open giggio opened this issue 1 year ago • 2 comments

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.

giggio avatar Oct 06 '23 19:10 giggio

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.

giggio avatar Oct 06 '23 19:10 giggio

Hi @giggio , thanks for putting this up! I have two questions though:

  1. K3s has a built-in servicelb that uses the host ports (IP of the K3s container) - is the problem with that just port-conflicts?

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

iwilltry42 avatar Oct 07 '23 06:10 iwilltry42