Kind — Kubernetes in Docker
Overview
Kind1 (Kubernetes IN Docker)
- …run Kubernetes clusters in Docker containers
- …primarily used for local testing and development purposes
- …supports the creation of multi-node clusters
- …allows testing against multiple Kubernetess versions
- …test different configuration with multiple clusters
- …support for persistent volumes …no loadbalancer …no ingress
- Maintained by the Kubernetes community…
- …dedicated Kubernetes SIG (Special Interest Group)
- …focuses on testing and quality assurance for Kubernetes
- …find the Kind repository on GitHub2
 

Installation
Prerequisites…
- …ensure Docker is installed4 & Docker daemon is running
- …kubectl5 to interact with the Kubernetes cluster
Installation6…
# install Kind in the user home-directory
test -d ~/bin || mkdir ~/bin ; export PATH=$PATH:~/bin
curl -L https://kind.sigs.k8s.io/dl/v0.27.0/kind-linux-amd64 -o ~/bin/kind
chmod +x ~/bin/kind
# verify the installation
kind version…or use the script kind-install7
Usage
Simple example of multiple clusters…
# create clusters
kind create cluster --name alpha
kind create cluster --name beta
# list running clusters
kind get clusters
# switch configuration context between clusters
kubectl config use-context kind-alpha
# remove a cluster
kind delete cluster --name betaConfiguration
Kind supports to specify various settings by configuration file8…
- …for example number of nodes, networking options,etc
- Why use a configuration file?
- Documentation …servers a documentation of the setup
- Reproducibility …recreate the same setup consistently
- Version control …provides a setup for collaboration
- Automation …simplify CI/CD integration
 
Create a multi-node cluster from a configuration file
# simple configuration file example
cat > kind-config.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: alpha
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
# create a cluster using a configuration file
kind create cluster --config kind-config.yaml
# verify the number of nodes
kubectl get nodeskind load
Load a container image into the cluster9:
# create a container image
cat > Dockerfile <<EOF
FROM debian:latest
CMD ["sleep", "3000"]
EOF
docker build -t sleep:latest .
# start a cluster
Kind create cluster
# load the image into the cluster
kind load docker-image sleep:latest
# use the image
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: sleep
  spec:
    containers:
    - name: sleep
      image: sleep:latest
      imagePullPolicy: Never  # required if using latest
EOFDo not use the :latest tag or specify imagePullPolicy: Never
# create a named cluster
name=alpha ; kind create cluster --name $name
# container image with a specific version
docker build -t sleep:0.1 .
# upload the container image to the cluster
kind load docker-image --name $name sleep:0.1
# list images present on the cluster node
docker exec -it $name-control-plane crictl images
Network
Kind cluster leverages Docker’s networking…
- …alongside standard Kubernetes components
- Kind Kubernetes nodes in Docker containers…
- …share the same Linux network namespace
- …communication over a Docker bridge network
 
# example is running two Kind clusters
>>> kind get clusters               
alpba
delta
# The `kind` bridge running on the host
>>> docker network list
NETWORK ID     NAME      DRIVER    SCOPE
#…
ba3abde46bfb   kind      bridge    localA Linux bridge behaves like a network switch…
>>> docker inspect kind
#…
                "Name": "alpba-control-plane",
                "IPv4Address": "172.18.0.5/16",
#…
                "Name": "delta-control-plane",
                "IPv4Address": "172.18.0.2/16",Lightweight networking with kindnetd10 …no load-balancer, ingress
Port Forwarding
kubectl create deployment nginx --image nginx
kubectl expose deployment nginx --name nginx --type NodePort --port 80
kubectl port-forward service/nginx 8000:80
$BROWSER localhost:8000Port Mapping
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30080
    hostPort: 8080
    protocol: TCP
EOFkubectl run nginx --image=nginx --port=80
# service IP within the cluster
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  labels:
    run: nginx
  name: nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30080
  selector:
    run: nginx
  type: NodePort
status:
  loadBalancer: {}
EOFCloud Provider
sudo dnf install golang
go install sigs.k8s.io/cloud-provider-kind@latest
install ~/go/bin/cloud-provider-kind ~/bincloud-provider-kind11 …monitors all Kind clusters…
- …reacts to services of type LoadBalancer
- …creates a corresponding container to expose the service
# start a cluster
kind create cluster
# start the cloud provider
cloud-provider-kindAllow load-balancing of workloads on a control plane node…
kubectl label node $name-control-plane node.kubernetes.io/exclude-from-external-load-balancers-apiVersion: v1
kind: Service
metadata:
  #…
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  #…Kubernetes Dashboard
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm install dashboard kubernetes-dashboard/kubernetes-dashboard --namespace kubernetes-dashboard --create-namespace
# wait for all containers
kubectl -n kubernetes-dashboard get pods
kubectl -n kubernetes-dashboard port-forward svc/dashboard-kong-proxy 8443:443 &
$BROWSER https://localhost:8443
# create a user to access the dashboard
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
EOF
kubectl -n kubernetes-dashboard create token admin-userPrometheus
Install Promtheus from a Helm chart…
helm add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install -n prometheus --create-namespace prometheus prometheus-community/prometheus…start port forwarding to access the Prometheus dashboard:
prometheus_pod=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus" -o name)
kubectl --namespace prometheus port-forward $prometheus_pod 9090Footnotes
- Kind Documentation 
 https://kind.sigs.k8s.io↩︎
- Kind, GitHub 
 https://github.com/kubernetes-sigs/kind↩︎
- Keep Calm and Load Balance on KIND - Antonio Ojea & Benjamin Elder, Google, Kubecon 2024 
 https://www.youtube.com/watch?v=U6_-y24rJnI↩︎
- Install Docker Engine, Docker Documentation 
 https://docs.docker.com/engine/install↩︎
- Install Tools, Kubernetes Documentation 
 https://kubernetes.io/docs/tasks/tools/↩︎
- Installation, Kind Documentation 
 https://kind.sigs.k8s.io/docs/user/quick-start#installation↩︎
- kind-installscript, GitHub
 https://github.com/vpenso/scripts/blob/master/bin/kind-install↩︎
- Kind Configuration, Kind Documentation 
 https://kind.sigs.k8s.io/docs/user/configuration↩︎
- Loading an Image Into Your Cluster, Kind Documentation https://kind.sigs.k8s.io/docs/user/quick-start/#loading-an-image-into-your-cluster↩︎ 
- Kindnet Project 
 https://kindnet.es
 https://github.com/aojea/kindnet↩︎
- Cloud provider for KIND clusters, GitHub 
 https://github.com/kubernetes-sigs/cloud-provider-kind↩︎