Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: integrate MetalLb into this project #1354

Open
giggio opened this issue Oct 6, 2023 · 2 comments
Open

Suggestion: integrate MetalLb into this project #1354

giggio opened this issue Oct 6, 2023 · 2 comments
Labels
enhancement New feature or request

Comments

@giggio
Copy link

giggio commented Oct 6, 2023

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 giggio added the enhancement New feature or request label Oct 6, 2023
@giggio
Copy link
Author

giggio commented Oct 6, 2023

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.

@iwilltry42
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants