Creating a Kubernetes Cluster for Development with Kind

Talha Khaild
5 min readNov 13, 2021

Previously, I have shared with you some options to have a cluster with which to develop your applications locally. Today I want to expand that list with a tool called Kind that allows you to generate clusters on Docker, even multi-node and/or simulating high availability.

Installation

To use Kind, the first thing you need is a host with Docker. On the other hand, you must install the Kind tool on your operating system. In the case of MacOs, like many other tools, it can be obtained through Homebrew:

brew install kind

Now you have everything you need to mount your cluster with this tool.

Create a Kubernetes cluster with Kind

The command you must use to create one, with the default options, is the following:

kind create cluster

This will generate the following output:

kind create cluster

What kind has done is, on the one hand, it has created a container called kind-control-plane, which is the one that will simulate your cluster. It also has port 6443 exposed to be able to talk to the Kubernetes API Server from the kubectl client in this example:

Kind-control-plane container

It has added the configuration to connect to it in the $ {HOME} /. Kube / config file. At the moment the cluster is created, your context is already configured so that it is pointing to it, so you can launch the following command:

kubectl get nodes

And you will see that you are now working with your cluster generated by Kind.

Single node for Kind cluster

Note: if you are working with Docker Desktop, it is recommended to configure it to use 6GB of RAM- 8GB recommended.

You can create multiple clusters if necessary. All you have to do is add the –name parameter to the kind cluster create command to give them identifying names.

kind create cluster --name abc

In the default command, the cluster name is Kind, so if you don’t assign any name in the following it will give you an error because it will try to create one with the same name:

Attempting a second cluster failed if you don’t specify a name

Create a cluster with more than one node

As you have already seen, without further configuration other than the create cluster command, what is created by default only has one node. However, it is possible to add more than one if we use a configuration like this (you can also add more than one control plane to simulate high availability):

# three node (two workers) cluster config
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

In order to apply this configuration, it is necessary to add the –config parameter and the name of the file where you have saved it:

kind create cluster --name multi-node --config=multi-node.yaml

If you now check the number of nodes in this cluster you will see the following output:

multi-node cluster with kind

Remote imaging applications

Now that you know how to create clusters with one or more nodes, it is time to test how to work with our applications. For example, if we wanted to test an application with an image in Docker Hub like the following:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web-nginx
name: web-nginx
spec:
replicas: 3
selector:
matchLabels:
app: web-nginx
template:
metadata:
labels:
app: web-nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-nginx
spec:
selector:
app: web-nginx
type: NodePort
ports:
- port: 80
nodePort: 30080

We need to create a cluster with some extra options, in order to expose the ports it needs, to be able to access it from outside. In this case, the configuration could be the following:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 30070

To make it clear, on the host I am going to say that when it is accessed through http: // localhost:30070 what will happen is that it will redirect to the container that is clustering, kind-control-plane, and this, in turn, will send it to that container within your cluster that is listening on port 30080.

As in the previous case, to create a cluster with this configuration you need to use the –config parameter:

kind create cluster --config=config-with-port-mapping.yaml

Now, if you do a docker ps you will see that your docker container exposes the port indicated in the configuration, 30070, and that it redirects it internally to 30080.

kind maps ports to the container that acts as a cluster

If you launch the yaml from the above web server.

kubectl create -f nginx.yaml

Now you can access the service through http: // localhost: 30070 from your local.

Applications with local images

Another scenario that may occur is that we may want to test an image that we are developing locally within the cluster, such as this one:

FROM nginx
COPY index.html /usr/share/nginx/html/

If you generate it in the same way as always:

docker build -t custom-nginx:v1.

And you try to use it for a new deployment:

kubectl create deploy custom-web --replicas=3 --image=custom-nginx:v1

Being in our premises, our cluster is not able to reach them if we do not put them in a remote place where it can reach.

kind does not reach the images that are in your premises

Kind’s solution is to load these images into the cluster using the following command:

kind load docker-image custom-nginx:v1

To see what images you have available in your cluster, you can see it by executing the crictl images command inside the kind-control-plane container in this case (unless you have chosen a name for your cluster):

docker exec -it kind-control-plane crictl images

Now that the image is available within it, the pods will appear in the Running state.

If you enjoyed this blog post, you can encourage me to produce more content by buying me a coffee.

--

--

Talha Khaild

A full-stack developer and DevOps engineer. Available for technical writing gigs! Contact: talhakhalid101[at]pm.me