Kubernetes Kind – A Simple Solution To Setup Local Kubernetes Cluster

In this article, you will learn how to set up a kubernetes cluster within a matter of minutes with the help of a kind tool.

If you are getting started with kubernetes you need a lab setup for practice. Thanks to the community you have various tools like minikube, kind, k3s, etc which help you in setting up the kubernetes cluster with a couple of commands. 

Think kind as an automation tool that takes care of setting up the cluster so we can focus on other stuff inside the cluster. 

Compared to other tools, kind offers a simple solution to set up single-node as well as multi-node clusters. Kind uses docker containers as nodes and all the Kubernetes services will be running as pods inside the containers using containerd runtime. 

Some of the features of kind include

  • Single and Multi node cluster.
  • Supports rootless docker and podman containers.
  • Possible proxy configuration. 
  • Building custom kind node images is possible.

Prerequisites

1. Kind needs docker to set up the container. You need to install docker before setting up the kind. 

https://docs.docker.com/engine/install/

2. The kubectl command helps you to interact with the kubernetes cluster. The containers launched by kind come with kubectl installed. But if you wish to interact without login into the container then install the kubectl on your local machine.

Setup Kind Binaries

There are a couple of ways to install kind on your machine. You can use any of the following methods.

  • Install using the go install command.
  • Install from the operating system package manager.
  • Install from the release binaries.
  • Install from source.

https://kind.sigs.k8s.io/docs/user/quick-start/#installation

Among these approaches, I suggest using the release binaries for installation. Below are the steps to set up the kind using the release binaries.

NOTE: At the time of writing this article the kind version is v0.18.0. For future releases, you have to modify the curl command URL with the correct version number.

Linux Operating system

$ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.18.0/kind-linux-amd64
$ chmod +x ./kind
$ sudo mv ./kind /usr/local/bin/kind

Mac Operating System

# for Intel Macs
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.18.0/kind-darwin-amd64

# for M1 / ARM Macs
[ $(uname -m) = arm64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.18.0/kind-darwin-arm64
chmod +x ./kind

Move the kind binary to any directory which is already added to the $PATH env variable.

Windows Operating System

Move the file to anywhere in your drive which is already added to the PATH env variable.

$ curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.18.0/kind-windows-amd64
$ Move-Item .\kind-windows-amd64.exe <any directory available in PATH>

Once the installation is completed you can run the following command to check the version.

$ kind version
kind v0.18.0 go1.20.2 linux/amd64

Setting Up Single Node Kubernetes Cluster

As foretold, kind uses the docker container as a node to start the cluster. Run the following command to set up the cluster.

$ kind create cluster

The above command will create a one-node kubernetes setup where all the master and slave services will be running in the same node.

Output from the create cluster command.

Creating cluster "kind" ...
 โœ“ Ensuring node image (kindest/node:v1.26.3) ๐Ÿ–ผ
 โœ“ Preparing nodes ๐Ÿ“ฆ
 โœ“ Writing configuration ๐Ÿ“œ
 โœ“ Starting control-plane ๐Ÿ•น๏ธ
 โœ“ Installing CNI ๐Ÿ”Œ
 โœ“ Installing StorageClass ๐Ÿ’พ
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a nice day! ๐Ÿ‘‹

Letโ€™s understand what happens when you run the โ€˜create clusterโ€™ command.

  • kind uses pre-defined docker images. In the first step of the above output you can see the node image used is kindest/node:v1.26.3 which is a docker image.
  • kind uses kubeadm to set up the cluster components.
  • A config file will be automatically generated under ~/.kube/config which contains the cluster, contexts, and user authentication metadata. When you run the kubectl command the config file is used to communicate with the cluster.

Kind Cluster With User-Defined Cluster Name

By default, kind sets the cluster name as โ€˜kindโ€™. When you try to create a second cluster you will get an error saying the name โ€œkindโ€ already exists for a cluster.

$ kind create cluster
ERROR: failed to create cluster: node(s) already exist for a cluster with the name "kind"

It is recommended to create the cluster with different names. You can do this with the help of –name flag.

$ kind create cluster --name=testk8s

Creating cluster "testk8s" ...
 โœ“ Ensuring node image (kindest/node:v1.26.3) ๐Ÿ–ผ
 โœ“ Preparing nodes ๐Ÿ“ฆ
 โœ“ Writing configuration ๐Ÿ“œ
 โœ“ Starting control-plane ๐Ÿ•น๏ธ
 โœ“ Installing CNI ๐Ÿ”Œ
 โœ“ Installing StorageClass ๐Ÿ’พ
Set kubectl context to "kind-testk8s"
You can now use your cluster with:

kubectl cluster-info --context kind-testk8s

Kind Cluster With Different Node Image

Kind by default pulls a certain image version which in my case is v1.26.3. It is also possible to spin up the cluster with different node versions.

Ensuring node image (kindest/node:v1.26.3)

You can get version-related information from the docker hub
To spin up the cluster with different image version use the –image flag. At the time of writing this article, the latest image version is 1.27.1 so I am using it.

$ kind create cluster --image kindest/node:v1.27.1 --name k8svs5

Creating cluster "k8svs5" ...
 โœ“ Ensuring node image (kindest/node:v1.27.1) ๐Ÿ–ผ
 โœ“ Preparing nodes ๐Ÿ“ฆ
 โœ“ Writing configuration ๐Ÿ“œ
 โœ“ Starting control-plane ๐Ÿ•น๏ธ
 โœ“ Installing CNI ๐Ÿ”Œ
 โœ“ Installing StorageClass ๐Ÿ’พ
Set kubectl context to "kind-k8svs5"
You can now use your cluster with:

kubectl cluster-info --context kind-k8svs5

Multi-Node Kind Cluster Setup

Kind allows you to create a multi-node cluster setup by creating a YAML config file. The config file uses a similar pattern with the kubernetes manifest file.

Letโ€™s create a config file to spin up 2 node kind cluster.

$ mkdir ~/kind-multinode
$ vim ~/kind-multinode/config.yaml

Add the following yaml definition in the config.yaml file. Under the nodes section, you will define how many nodes you need and what is the node role.

Setting the role to โ€œcontrol-planeโ€ will spin up the node with master components.
Setting the role to โ€œworkerโ€ will spin up the node with worker components.

# TWO NODE CLUSTER WITH ONE MASTER & ONE WORKER
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker

Use –config flag and pass the config.yaml as an argument.

$ kind create cluster --config config.yaml --name multik8s

Creating cluster "multik8s" ...
 โœ“ Ensuring node image (kindest/node:v1.26.3) ๐Ÿ–ผ
 โœ“ Preparing nodes ๐Ÿ“ฆ ๐Ÿ“ฆ
 โœ“ Writing configuration ๐Ÿ“œ
 โœ“ Starting control-plane ๐Ÿ•น๏ธ
 โœ“ Installing CNI ๐Ÿ”Œ
 โœ“ Installing StorageClass ๐Ÿ’พ
 โœ“ Joining worker nodes ๐Ÿšœ
Set kubectl context to "kind-multik8s"
You can now use your cluster with:

kubectl cluster-info --context kind-multik8s

To pass different image name, use the image property and provide the image name along with sha256 shasum. You can get both the image version and related checksum value from the docker hub.

You can also scale the nodes by just adding more roles in the yaml file. Two master and two worker will be created by the below configuration.

# FOUR NODE CLUSTER WITH TWO MASTER & TWO WORKER
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: worker
- role: worker

Kind Nodes – Docker Containers

Till now we have seen how to create single and multi node clusters. Kind creates a docker container and runs the kubernetes services as pods inside the containers.

Once the cluster is created, run the โ€˜docker psโ€™ command and you will see the container created with โ€œ{clustername}-control-paneโ€ or โ€œ{clustername}-workerโ€ as its name.

In the above image, you can see the container does the port forwarding from 127.0.0.1:random_port to 6443(API Server) Port.

kind does not provide support to stop and start containers or kubernetes services natively. We have to achieve this natively using docker commands.

$ docker container stop {container name}
$ docker container start {container name}

You can connect to the master container and see the services running as pods. Here I am using the default kind cluster.

$ docker container exec -it kind-control-plane bash
$ kubectl get pods -A
NAMESPACE            NAME                                         READY   STATUS    RESTARTS      AGE
kube-system          coredns-787d4945fb-j9xl4                     1/1     Running   1 (96s ago)   4h22m
kube-system          coredns-787d4945fb-whdzg                     1/1     Running   1 (95s ago)   4h22m
kube-system          etcd-kind-control-plane                      1/1     Running   1 (96s ago)   4h22m
kube-system          kindnet-zwp6t                                1/1     Running   1 (95s ago)   4h22m
kube-system          kube-apiserver-kind-control-plane            1/1     Running   1 (96s ago)   4h22m
kube-system          kube-controller-manager-kind-control-plane   1/1     Running   2 (96s ago)   4h22m
kube-system          kube-proxy-g7dgm                             1/1     Running   1 (96s ago)   4h22m
kube-system          kube-scheduler-kind-control-plane            1/1     Running   2 (95s ago)   4h22m
local-path-storage   local-path-provisioner-75f5b54ffd-hwkcf      1/1     Running   2 (50s ago)   4h22m

You can also run the same command from any client machine considering the kubectl config file is set up properly.

Cluster & Config Information

To get the list of created clusters run the following command.

$ kind get clusters 

You can also get the cluster info with the kubectl command.

$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:42777
CoreDNS is running at https://127.0.0.1:42777/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

To check the status of different clusters run the same kubectl command with the appropriate context name.

$ kubectl config get-contexts                       # GET ALL CONTEXTS
$ kubectl cluster-info --context <context-name>     # SYNTAX
 
$ kubectl cluster-info --context kind-k8svs5
Kubernetes control plane is running at https://127.0.0.1:43469
CoreDNS is running at https://127.0.0.1:43469/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To get a node list for a cluster run the following command.

$ kubectl get nodes
$ kubectl get nodes --context <context-name>

To get the kubeconfig file information either you can access it manually from ~/.kube/config or run the following command.

$ kind get kubeconfig 
$ kind get kubeconfig --name <cluster-name>

If you use the above command without any cluster name it will print the config details for the default cluster name โ€œkindโ€. To view different cluster config files use the –name <clustername> option.

Test The Cluster With Deployment

Letโ€™s create a simple deployment controller and run it on the default kind cluster. I am using the deployment definition from the official documentation and you can use the same. Below is the link for the manifest file.

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment

Create the manifest file. Run the following command to create the deployment.

$ kubectl apply -f <manifest.yaml>

Verify the status of the pod by running any of the following commands.

$ kubectl get pods
$ kubectl get po

Delete Kind Cluster

The โ€œdelete clusterโ€ command by default will remove the default cluster named โ€œkindโ€.

$ kind delete cluster

Deleting cluster "kind" ...
Deleted nodes: ["kind-control-plane"]

You can run this command N number of times. It will try to remove the kind cluster instead of throwing an error saying no cluster.

To remove user-defined clusters pass the cluster names as the argument. Also, you can pass multiple cluster names in a single command.

$ kind delete clusters k8svs5 multik8s testk8s

Deleted nodes: ["k8svs5-control-plane"]
Deleted nodes: ["multik8s-control-plane" "multik8s-worker"]
Deleted nodes: ["testk8s-control-plane"]
Deleted clusters: ["k8svs5" "multik8s" "testk8s"]

Wrap Up

We have reached the end of the article, hope this article helped you to learn what kind as a tool offers.

Reference – https://kind.sigs.k8s.io/

Leave a Reply

2 × four =