Local Feature Comparison

Ingress, Load Balancing and Registry Support Compared

In the benchmark a LoadBalancer Service on port 80 was still <pending> after 20 seconds on all three. kind 14,561 and minikube 14,561 have no load-balancer controller. k3d's ServiceLB binds Service ports on every node with hostPort, and Traefik 27,315 holds 80 and 443, so the Service stays pending, as the k3s 51,195 documentation warns; port 33080 always worked. kind's answer is cloud-provider-kind 508 (The Cloud Controller Manager), run on the host:

A LoadBalancer Service on kind, served by cloud-provider-kind 0.11.1YAML
REL=https://github.com/kubernetes-sigs/cloud-provider-kind/releases/download/v0.11.1
curl -sL $REL/cloud-provider-kind_0.11.1_linux_amd64.tar.gz | tar xz cloud-provider-kind
kubectl expose deployment nginx --type=LoadBalancer --port=33080 --target-port=80
./cloud-provider-kind > cpk.log 2>&1 & CPK=$!
sleep 20; kubectl get service nginx
IP=$(kubectl get service nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -s "http://$IP:33080/" | grep -o '<title>.*</title>'
docker ps --filter label=io.x-k8s.cloud-provider-kind.cluster --format '{{.Names}}  {{.Image}}'
kill $CPK
Output
service/nginx exposed
NAME    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
nginx   LoadBalancer   10.96.212.78   172.18.0.5    33080:30685/TCP   20s
<title>Welcome to nginx!</title>
kindccm-1d5e36ea3a4e  envoyproxy/envoy:v1.33.2

It starts an Envoy 117,531 container per Service on the kind network, whose IP becomes the external IP, and here also published the port on the host. It serves every kind cluster on the Docker 514 host, and if stopped while a Service exists, kubectl 5,150 delete service hangs on the service.kubernetes.io/load-balancer-cleanup finalizer.

Getting traffic and images into each local cluster
Need kind k3d minikube
LoadBalancer Services cloud-provider-kind on the host ServiceLB built in (node IPs) minikube tunnel
Ingress cloud-provider-kind, or install a controller Traefik preinstalled addons enable ingress
Gateway API cloud-provider-kind (standard channel) CRDs preinstalled by k3s Install a controller
Load a local image kind load docker-image k3d image import minikube image load
Local registry containerd 234,762 hosts.toml script in the docs k3d registry create addons enable registry

Since version 0.9.0, cloud-provider-kind also serves Ingress and the Gateway API with no separate controller, which matters now that ingress-nginx is retired (Ingress-NGINX Retirement). Images come from Image Registries's registry through the hosts.toml pattern (Loading Local Images).