I’m a big proponent of local testing. Being able to test a piece of code or configuration locally greatly increases developement and deployment speed. Its better to fail fast, and, in a sandboxed/controlled environment before deploying in production. Finally it also serves as a way to tinker (and break stuff) and learn.

Most of the applications I write and deploy end up being packaged as container images and run on orchestration platforms like Docker or Kubernetes. I’ve found a local Kubernetes cluster to be a life saver and a great way to expand my learning.

My Local machine (specs that matter)

OS: MacOS Sonoma
Processor Arch: Apple Silicon (M1, i.e. 64-bit ARM)

Installation

On Mac its as simple as brew install kind. For alternatives check the Kind docs here. In addition you’d want to have the following installed: Docker or an alternative runtime, and, kubectl.

Pre-requisites

Container runtime: Docker

Ensure you have Docker (Desktop, since this is a mac setup) installed as well. This is because Kind uses Docker containers by default to “emulate” Kubernetes nodes. This will add some additional complexity in our configuration and we shall see that shortly in the form of extraPortMappings when defining our cluster config YAMLs. In summary, bear in mind your Kubernetes nodes are containers acting as if they are nodes. You can download the Docker desktop dmg from here and install it.

If you are running this on your work Macbook or for another reason you don’t have Docker desktop license you can consider an alternative like Colima. Here’s a great post on getting started on Colima. If using this approach, we have yet another “layer” to our setup: Colima spins up VM(s) with the Docker (by default) daemon running. This VM runs Docker containers that will emulate our Kubernetes nodes.

If you took the Docker desktop route, ensure it is running at this point.

If you took the Colima route, start the Colima VM using:

# Use host networking for the VM, use 3 vCPUs, 6GiB of memory and OS architecture as arm64
colima start --network-address --cpu 3 --memory 6 --arch arm64

Note: Change the --arch to the architecture of your choice and ensure you pull images for it

Here are some useful colima commands:

colima list   # List your VM(s)
colima status
colima stop   # Stop your VM
colima ssh    # SSH into your colima VM

Interacting with the cluster: kubectl

Kubectl is a cli that is most commonly used to inteact with your cluster via the Kube API server. Installing it is as simple as brew install kubectl. For alternatives check the docs here

Creating a cluster

For a simple exercise you could just run a single node that runs both the control plane and the worker nodes, i.e. a single node.

Simple single node setup:

# kind-cluster.yaml
## Single node
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
  - role: control-plane
    extraPortMappings:
      - containerPort: 30001
        hostPort: 37899
        protocol: TCP

Two node setup (1x Control plane and 1x worker nodes, with storage):

# kind-cluster.yaml
## Two nodes - 1 control plane, 1 worker
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
  - role: control-plane
    extraPortMappings:
      - containerPort: 30001
        hostPort: 37899
        protocol: TCP
  - role: worker
    extraPortMappings:
      - containerPort: 30001
        hostPort: 37898
        protocol: TCP
    extraMounts:
        - hostPath: /Users/parth/k8s/cluster-0xuh/storage
          containerPath: /files # Since kind nodes are actualy (docker) containers
  • extraPortMappings specifies configuration that helps direct traffic from the host (your machine) to the node (docker container running as k8s node)
  • containerPort specifies the port your container running as K8s node will expose ; You’d want your application pod to listen on this port as well
  • hostPort specifies the port your host will host will expose; You’d use this port on your local browser to visit your application GUI or specify in your terminal command if using a CLI
  • extraMounts specifies configuration that helps us share one or more host (your machine) directories to our nodes
  • hostPath is the dir on the host; Contents of this dir would be available to the host under /files (i.e. (root)/files)
  • containerPath is the dir on our K8s node (which is actually a Docker container)

The extraPortMappings along with containerPort and hostPort allow us to use containers as nodes by setting up port forwarding. When setting up a K8s service for instance, you would set up your NodePort same as containerPort.

That’s it. Use this command to create the cluster:

kind create cluster --name playground --config kind-cluster.yaml

And to teardown:

kind delete cluster --name playground

Changes to the cluster configuration would need a cluster teardown and recreation.