Local Kubernetes setup with KinD

Getting started with Kubernetes these days is easy and does not require to be in the lucky position having access to a cloud provider subscription for playing around with managed Kubernetes like AKS, EKS or GKE.

All you need is your local machine.

But then you must choose which one of the available offerings you would like to use: minikube, Docker Desktop, MicroK8s, k3s/k3d or KinD?

Today I like to walk you through my local Kubernetes setup with KinD.

The only two requirements to get started are having Docker installed and the KinD binary.

-> https://www.docker.com/products/docker-desktop
-> https://kind.sigs.k8s.io/docs/user/quick-start/

Before getting started with KinD I have used Docker Desktop, but was missing the CNI capability there as well not able to run an entire Kubernetes cluster on a local machine. In both cases KinD fills the gap supporting CNI and spinning up Kubernetes nodes as Docker containers.

This makes KinD ideal for testing in CI/CD pipelines, but this is another topic I do not touch in this blog post.

Currently, I am running KinD on my MacBook Pro as a single node Kubernetes cluster with the following configuration.

apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
  apiServerAddress: ""
  apiServerPort: 6443
  podSubnet: ""
  serviceSubnet: ""
  disableDefaultCNI: true
- role: control-plane
  - |
    kind: InitConfiguration
        node-labels: "ingress-ready=true"
  - containerPort: 30000
    hostPort: 80
    listenAddress: ""
    protocol: TCP
  - containerPort: 30001
    hostPort: 443
    listenAddress: ""
    protocol: TCP
  - containerPort: 30002
    hostPort: 15021
    listenAddress: ""
    protocol: TCP

-> https://github.com/neumanndaniel/kubernetes/blob/master/kind/single-node.yaml

Looking at the configuration I want to highlight some parts.

First, the definition of podSubnet and serviceSubnet. I have chosen these specific volumes as they are the default ones for Azure Kubernetes Service.

Furthermore, I am disabling the default CNI plugin of KinD. So, I can use Calico as CNI plugin and for Kubernetes network policies.

As you might already get it, I try to have a single node cluster installation similar to an AKS installation in Azure.

Next stop is the extra label for the node acting as the control plane. This node will always host the ingress gateway despite the fact I am currently only aim for a single node Kubernetes cluster setup. Just to be prepared for a multiple node one.

The last part are the extraPortMappings. I am specifically using those ones for my Istio installation on KinD: HTTP, HTTPS and the Istio ingress gateway health check endpoint port.

Why I am using 30000, 30001 and 30002 as the container ports you might ask now? Good point.

As KinD does not have a SLB (Software Load Balancer) on board by default you need to expose the Istio ingress gateway via node ports to the outside world.

An alternative approach is installing MetalLB as SLB onto KinD.

-> https://mauilion.dev/posts/kind-metallb/
-> https://www.thehumblelab.com/kind-and-metallb-on-mac/

The listening address of the ports is pinned to instead of the default

Just a hint, I will cover the Istio on KinD installation in another blog post in the next couple of weeks.

Now, we install KinD with the following script including Calico and the Kubernetes Metrics Server.

set -e
kind create cluster --config=single-node.yaml
# Calico
curl https://docs.projectcalico.org/manifests/calico.yaml | kubectl apply -f -
# CoreDNS
kubectl scale deployment --replicas 1 coredns --namespace kube-system
# Metrics Server
helm repo add stable https://kubernetes-charts.storage.googleapis.com
helm repo update
helm upgrade metrics-server --install --set "args={--kubelet-insecure-tls, --kubelet-preferred-address-types=InternalIP}" stable/metrics-server --namespace kube-system

-> https://github.com/neumanndaniel/kubernetes/blob/master/kind/setup.sh

The full installation should be done in about three minutes.

> kubectl get nodes -o wide
kind-control-plane   Ready    master   2d22h   v1.18.2    <none>        Ubuntu 19.10   4.19.76-linuxkit   containerd://1.3.3-14-g449e9269
> kubectl get pods -n kube-system
NAME                                         READY   STATUS    RESTARTS   AGE
azure-policy-7b566d9574-dzmk7                1/1     Running   1          2d22h
azure-policy-webhook-795b8fbb7c-lt7hj        1/1     Running   1          2d22h
calico-kube-controllers-58b656d69f-tj7wl     1/1     Running   1          2d22h
calico-node-5gjgr                            1/1     Running   1          2d22h
coredns-66bff467f8-fwhpn                     1/1     Running   1          2d22h
etcd-kind-control-plane                      1/1     Running   1          2d22h
kube-apiserver-kind-control-plane            1/1     Running   1          2d22h
kube-controller-manager-kind-control-plane   1/1     Running   1          2d22h
kube-proxy-5c5lv                             1/1     Running   1          2d22h
kube-scheduler-kind-control-plane            1/1     Running   1          2d22h
metrics-server-68d479bb9-jwwkl               1/1     Running   1          2d22h
omsagent-dshbw                               1/1     Running   1          2d22h
omsagent-rs-94955cb79-lck27                  1/1     Running   1          2d22h

When you look for further scenarios for KinD like Azure Monitor for containers or Azure Arc enabled Kubernetes, I got you covered.

-> https://www.danielstechblog.io/connect-kind-with-azure-monitor-for-containers/
-> https://www.danielstechblog.io/connect-kind-with-azure-arc-enabled-kubernetes/

Further information about KinD are available under https://kind.sigs.k8s.io/.