- Published on
KinD for Local Kubernetes Clusters
- Authors
- Name
- Ruan Bekker
- @ruanbekker
In this tutorial we will demonstrate how to use KinD (Kubernetes in Docker) to provision local kubernetes clusters for local development.
About
KinD uses container images to run as "nodes", so spinning up and tearing down clusters becomes really easy or running multiple or different versions, is as easy as pointing to a different container image.
Configuration such as node count, ports, volumes, image versions can either be controlled via the command line or via configuration, more information on that can be found on their documentation:
Installation
Follow the docs for more information, but for mac:
brew install kind
To verify if kind was installed, you can run:
kind version
Create a Cluster
Create the cluster with command line arguments, such as cluster name, the container image:
kind create cluster --name cluster-1 --image kindest/node:v1.24.0
And the output will look something like this:
Creating cluster "cluster-1" ...
â Ensuring node image (kindest/node:v1.24.0) đŧ
â Preparing nodes đĻ
â Writing configuration đ
â Starting control-plane đšī¸
â Installing CNI đ
â Installing StorageClass đž
Set kubectl context to "kind-cluster-1"
You can now use your cluster with:
kubectl cluster-info --context kind-cluster-1
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community đ
I highly recommend installing kubectx, which makes it easy to switch between kubernetes contexts.
Create a Cluster with Config
If you would like to define your cluster configuration as config, you can create a file default-config.yaml
with the following as a 2 node cluster, and specifying version 1.24.0:
---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
image: kindest/node:v1.24.0@sha256:0866296e693efe1fed79d5e6c7af8df71fc73ae45e3679af05342239cdc5bc8e
- role: worker
image: kindest/node:v1.24.0@sha256:0866296e693efe1fed79d5e6c7af8df71fc73ae45e3679af05342239cdc5bc8e
Then create the cluster and point the config:
kind create cluster --name kind-cluster --config default-config.yaml
Interact with the Cluster
View the cluster info:
kubectl cluster-info --context kind-kind-cluster
View cluster contexts:
kubectl config get-contexts
Use context:
kubectl config use-context kind-kind-cluster
View nodes:
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kind-cluster-control-plane Ready control-plane 2m11s v1.24.0 172.20.0.5 <none> Ubuntu 21.10 5.10.104-linuxkit containerd://1.6.4
kind-cluster-worker Ready <none> 108s v1.24.0 172.20.0.4 <none> Ubuntu 21.10 5.10.104-linuxkit containerd://1.6.4
Deploy Sample Application
We will create a deployment, a service and port-forward to our service to access our application. You can also specify port configuration to your cluster so that you don't need to port-forward, which you can find in their port mappings documentation
I will be using the following commands to generate the manifests, but will also add them to this post:
kubectl create deployment hostname --namespace default --replicas 2 --image ruanbekker/containers:hostname --port 8080 --dry-run=client -o yaml > hostname-deployment.yaml
kubectl expose deployment hostname --namespace default --port=80 --target-port=8080 --name=hostname-http --dry-run=client -o yaml > hostname-service.yaml
The manifest:
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: hostname
name: hostname
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: hostname
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: hostname
spec:
containers:
- image: ruanbekker/containers:hostname
name: containers
ports:
- containerPort: 8080
resources: {}
status: {}
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: hostname
name: hostname-http
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: hostname
status:
loadBalancer: {}
Then apply them with:
kubectl apply -f <name-of-manifest>.yaml
Or if you used kubectl to create them:
kubectl apply -f hostname-deployment.yaml
kubectl apply -f hostname-service.yaml
You can then view your resources with:
kubectl get deployment,pod,service
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hostname 2/2 2 2 9m27s
NAME READY STATUS RESTARTS AGE
pod/hostname-7ff58c5644-67vhq 1/1 Running 0 9m27s
pod/hostname-7ff58c5644-wjjbw 1/1 Running 0 9m27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hostname-http ClusterIP 10.96.218.58 <none> 80/TCP 5m48s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24m
Port forward to your service:
kubectl port-forward svc/hostname-http 8080:80
Then access your application:
curl http://localhost:8080/
Hostname: hostname-7ff58c5644-wjjbw
Delete Kind Cluster
View the clusters:
kind get clusters
Delete a cluster:
kind delete cluster --name kind-cluster
Extras
I highly recommend using kubectx
to switch contexts and kubens
to set the default namespace, and aliases:
alias k=kubectl
alias kx=kubectx
alias kns=kubens
Thank You
Thanks for reading, feel free to check out my website, feel free to subscribe to my newsletter or follow me at @ruanbekker on Twitter.
- Linktree: https://go.ruan.dev/links
- Patreon: https://go.ruan.dev/patreon