We will setup a local kubernetes cluster using k3d which is a wrapper around another tool called k3s, which is a lightweight Kubernetes distribution designed for resource-constrained environments. The beauty of k3d is that you can spin up a multi-node cluster on your machine with a single command. In our example the cluster will provide a simple website with a hello world message. This will give you the basis to setup any other complex cluster running your application. I tested this with heavy applications and works really well. I wouldn’t use it for a production environment handling a heavy load, but it’s perfect to replicate a production cluster locally for testing or developing purposes.
Prerequisites
Before we start we need to install some basic tools and also I would recommend some other extra, not necessary tools, that will make your like easier like k9s.
I assume you are familiar with the command line interface, if not, check my video here! I also assume you have docker installed and you are familiar with it as well, otherwise check this other video here. Also I assume you have some familiarity with Kubernetes, if not I recommend The Kubernetes Book by Nigel Poulton.
In this video I’m going to use homebrew for Mac and for Linux as well. For those not familiar with it, homebrew is a package manager for macOS and Linux, which will simplify the installation process. In case of Linux some might think “why using another package manager, we already have one for Linux!” that’s true, but installing these tools in Linux without Homebrew require more steps because not all of them are available in the usual repositories. There’s plenty of documentation on how to install them on Linux and at of this post, I left instructions.
If you don’t have Homebrew go to this link and install it. The process is straight forward. Once you have it installed continue here:
brew install k3d kubectl k9s
k9s
is not strictly necessary but I really recommend installing it. We will use it in this tutorial, it’s an extremely helpful and handy tool to have. You can do everything k9s
does with kubectl
but why wasting time when we have a took that makes our life way easier.
Create the registry
Before we create the cluster, it’s not mandatory, but we better create a registry. This will allow us to upload our Docker images similar to a real scenario.
Here I’m using port 5001 because on macOS the port 5000 is already used. You can use any port you want, as long as it’s free to use.
k3d registry create registry --port 5001
Create the cluster
We need to create the cluster first. It will deploy a series of Docker containers that will be responsible to run our cluster. We won’t have to deal with these containers, it’s all managed internally by k3d
.
k3d cluster create mycluster -p "8080:80@loadbalancer" --registry-use k3d-registry:5001 --agents 1
With this command we will create a cluster called mycluster
If we type docker ps
we can see the containers that run our cluster:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cbdc37d82bab ghcr.io/k3d-io/k3d-tools:5.8.3 "/app/k3d-tools noop" 54 seconds ago Up 54 seconds k3d-mycluster-tools
e45f49af592a ghcr.io/k3d-io/k3d-proxy:5.8.3 "/bin/sh -c nginx-pr…" 19 hours ago Up 49 seconds 0.0.0.0:8080->80/tcp, 0.0.0.0:49517->6443/tcp k3d-mycluster-serverlb
30741d5c522b rancher/k3s:v1.31.5-k3s1 "/bin/k3d-entrypoint…" 19 hours ago Up 50 seconds k3d-mycluster-agent-0
9c641645e023 rancher/k3s:v1.31.5-k3s1 "/bin/k3d-entrypoint…" 19 hours ago Up 53 seconds k3d-mycluster-server-0
02da975b678a registry:2 "/entrypoint.sh /etc…" 19 hours ago Up 19 hours 0.0.0.0:5001->5000/tcp k3d-myregistry
Create the container application
Let’s create a container application. I have one image available to download, it just presents a Hello World
message at port 8000
docker pull pietrozuco/helloworld:basic-latest
Next we need to push this image to our k3d registry:
docker tag pietrozuco/helloworld:basic-latest localhost:5001/helloworld:basic-latest
This will tag our image to point to the local registry. Finally we push it:
docker push localhost:5001/helloworld:basic-latest
To make sure the image is in the local registry we can use a couple of curl commands. The first will list the repository name:
$ curl -X GET http://localhost:5001/v2/_catalog
{"repositories":["helloworld"]}
The second, using that name will output the images:
$ curl -X GET http://localhost:5001/v2/helloworld/tags/list
{"name":"helloworld","tags":["basic-latest"]}
Now we are good to go to create our manifests to deploy the cluster
Deploying the cluster
Make sure our cluster is running
$ k3d cluster list
NAME SERVERS AGENTS LOADBALANCER
mycluster 1/1 1/1 true
We see servers 1/1
and agents 1/1
meaning the cluster is running.
We can check the kubernetes contexts:
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* k3d-mycluster k3d-mycluster admin@k3d-mycluster
In this case we won’t bother to setup a namespace because for testing purposes the default is fine. But k3d
is powerful enough to handle almost all kubernetes operations. It’s a great tool for learning and testing.
To deploy we just do the same as if we have a cluster running in the cloud or anywhere else. In this case we use simple manifests, but we can also use helm.
You can download the files from the repository associated to this video and run the following commands inside the repo:
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
We can see how the deployment is going by using the command kubectl
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-deployment-d678cff85-bjhfk 1/1 Running 0 6s
hello-world-deployment-d678cff85-rbmxq 1/1 Running 0 42s
Two replicas of our web app are running.
We can also check the rest of the configuration:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world-service ClusterIP 10.43.120.255 <none> 80/TCP 103s
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 2m37s
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
hello-world-ingress traefik * 172.20.0.4,172.20.0.5 80 107s
We can try our configuration at localhost:8080 and we should see the message Hello World
Typical commands with k3d
which are self explanatory
k3d cluster list
k3d registry list
k3d cluster delete mycluster
k3d registry delete k3d-registry
Linux / Raspberry Pi Installation
k3d
has a very good installation documentation, check it here.
k9s
can be installed on most distributions, check it here.
Finally kubectl
can be installed following the instructions from the kubernetes website