Setup Local Kubernetes Cluster with Docker, WSL2 and KinD

Kubernetes has raced ahead of other container management platforms in last few years. However there remain difficulties in setup and running multi node clusters for developers to test their container workloads. Many organizations come around this by provisioning separate kubernetes clusters for devs. Some other go to the extent of provisioning one kubernetes cluster per developer. However it soon becomes additional hassle for devs and ops alike and also keeps contributing to company’s rising cost.

Minikube is one of solutions that can be used to solve this scenario but minikube is limited to single node setup. But to gain Kubernetes experience, most need to run multi node solutions or clusters. KinD is a tool which can be used for running local Kubernetes clusters using Docker container nodes. KinD was primarily designed for testing Kubernetes itself, but may be used for local development or CI.

KinD Pre-Requisites

Here is the list of the prerequisites needed and their version/lane:

  • OS: Windows 10 version 2004, Build 19041 or higher
  • WSL2 Enabled
  • Docker Desktop for Windows, stable channel
  • WSL2 distro installed from the Windows Store, We’ll use Ubuntu 20.04 LTS

Setup WSL2

For full instructions, refer to the official instructions for enabling WSL2. These are the instructions for those, who dont want to bother to read through whole document:

  • Verify if you are running on the correct version of Windows 10 by using winver. For x64 systems, it should be version 1903 or higher, with Build 18362 or higher. For ARM64 systems, it should be version 2004 or higher, with Build 19041 or higher.
  • Open a PowerShell window as admin and run below command. Restart when prompted.
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform, Microsoft-Windows-Subsystem-Linux
  • After the reboot, setup WSL default to WSL2:
wsl --set-default-version 2

Install Linux Distro

You can now install Linux Distro of your choice by going to Windows Store from start panel and then install the same. For the purpose of this blog post, we’ll use Ubuntu 20.04 LTS. If you don’t want to use the Windows Store, then follow the steps in the WSL docs for manual install.

Once installed, now startup your distro. For first time, it will ask you to setup username and password like any other place. Go ahead and do the same. Let’s also go ahead and enable nopassword login for the group %sudo:

# Edit the sudoers with the visudo command
sudo visudo

# Change the %sudo group to be password-less
%sudo   ALL=(ALL:ALL) NOPASSWD: ALL

Also, lets update the package repos and distribution for distro. For Ubuntu, run below:

# Update the repositories and list of the packages available
sudo apt update
# Update the system based on the packages installed > the "-y" will approve the change automatically
sudo apt upgrade -y

Setting up Docker Desktop in WSL2

For full instructions, install Docker Desktop with WSL2 backend here: https://docs.docker.com/docker-for-windows/wsl/. We can now switch to terminal in our distro and run following commands:

$ docker version
Client: Docker Engine - Community
 Cloud integration: 1.0.7
 Version:           20.10.2
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        2291f61
 Built:             Mon Dec 28 16:17:34 2020
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.2
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       8891c58
  Built:            Mon Dec 28 16:15:28 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.3
  GitCommit:        269548fa27e0089a8b8278fc4fc781d7f65a939b
 runc:
  Version:          1.0.0-rc92
  GitCommit:        ff819c7e9184c13b7c2607fe6c30ae19403a7aff
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:50:19Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?

If you dont see output like above, go back and revisit your steps.

Setup KinD on Linux Distro

As mentioned on the official page, you can setup KinD by using following commands:

# Download the latest version of KinD
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.10.0/kind-linux-amd64
# Make the binary executable
chmod +x ./kind
# Move the binary to your executable path
sudo mv ./kind /usr/local/bin/

Spin a KinD Kubernetes Cluster

Creating a Kubernetes cluster is as simple as kind create cluster.

This will bootstrap a Kubernetes cluster using a pre-built node image. Prebuilt images are hosted atkindest/node. To specify another image use the --image flag – kind create cluster --image=.... Using a different image allows you to change the Kubernetes version of the created cluster.

Let’s spin up a KinD cluster and give it a name say wslkind:

The cluster has been successfully created, and because we are using Docker Desktop, the network is all set for us to use as is. So we can open the Kubernetes master URL in our Windows browser:

Running Multi-node cluster with KinD

By default, the KinD creates a single node cluster. Lets first delete existing cluster using kind delete cluster --name wslkind. Now, let’s spin a 3 control plane and 3 worker node HA cluster for ourselves. First we need to save below configuration to a file say kind-6nodes-ha.yaml:

# a cluster with 3 control-plane nodes and 3 workers
kind: Cluster
apiVersion: kind.x-k8s.io/v1
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker

And spin up a Kubernetes cluster using the file we created above:

$ kind create cluster --name multicluster --config ./kind-6nodes-ha.yaml

If you see unknown API issues, you can run below command to get APIs available:

for kind in `kubectl api-resources | tail +2 | awk '{ print $1 }'`; do kubectl explain $kind; done | grep -e "KIND:" -e "VERSION:"

Also, the information can be gathered in a less efficient way from the kubernetes API docs (with links for each version) found here – https://kubernetes.io/docs/reference/#api-reference

We can check the services for all namespaces using kubectl get all --all-namespaces:

Part 2 of this blog post can be found here.

2 thoughts on “Setup Local Kubernetes Cluster with Docker, WSL2 and KinD

  1. […] In first part of this post, we setup WSL2, Docker Desktop, Enabled Integration of WSL2 with Docker, Setup KinD cluster and spin up a single node and multi node cluster. Since 6 nodes HA cluster was too much for our learning needs, lets first delete it using kind delete cluster –name multicluster and provision a fresh single node cluster for us. […]

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s