What it is
Kind (Kubernetes IN Docker) is a tool for running local Kubernetes clusters using Docker containers as "nodes." It’s ideal for testing Kubernetes configurations, developing applications against a local cluster, or learning Kubernetes.
Installation
Linux
# Using go (if you have Go installed)
go install sigs.k8s.io/kind@v0.20.0
# Using Homebrew
brew install kind
# Download binary
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
Mac
# Using Homebrew
brew install kind
# Download binary
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-darwin-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
Windows
# Using Chocolatey
choco install kind
# Download binary (PowerShell)
Invoke-WebRequest -Uri https://kind.sigs.k8s.io/dl/v0.20.0/kind-windows-amd64 -OutFile .\kind.exe
# Move to PATH
Move-Item .\kind.exe C:\Users\YOUR_USERNAME\bin\kind.exe # Adjust path as needed
Prerequisites: Docker must be installed and running.
Core Concepts
- Node: In Kind, a "node" is a Docker container that runs Kubernetes components (like etcd, API server, kubelet) for a single Kubernetes node.
- Cluster: A Kind cluster is composed of one or more Docker containers, each acting as a Kubernetes node.
- Configuration File: Kind allows for advanced cluster configuration using a YAML file, specifying node images, number of nodes, control plane configuration, and more.
Commands / Usage
Cluster Creation
-
Create a default single-node cluster:
kind create clusterCreates a local Kubernetes cluster with one control-plane node.
-
Create a cluster with a specific name:
kind create cluster --name my-dev-clusterCreates a cluster named
my-dev-cluster. -
Create a multi-node cluster (e.g., 1 control-plane, 2 workers):
kind create cluster --config kind-multi-node.yamlRequires a
kind-multi-node.yamlconfiguration file (see examples below). -
Create a cluster from a configuration file:
kind create cluster --config kind-config.yamlCreates a cluster using the settings defined in
kind-config.yaml. -
Keep nodes after cluster deletion:
kind create cluster --retain-node-imagePrevents Kind from deleting the Docker containers that make up the cluster nodes. Useful for debugging.
Cluster Deletion
-
Delete the default cluster:
kind delete clusterRemoves all Docker containers and resources associated with the default cluster.
-
Delete a specific named cluster:
kind delete cluster --name my-dev-clusterRemoves the cluster named
my-dev-cluster. -
Delete all clusters:
kind delete clusters --allRemoves all Kind clusters currently running.
Cluster Information and Management
-
List all Kind clusters:
kind get clustersShows the names of all Kind clusters available.
-
Get the kubeconfig for a cluster:
kind get kubeconfig --name my-dev-clusterOutputs the kubeconfig content for the specified cluster. This is automatically merged into your default
~/.kube/configwhen creating a cluster. -
Load Docker images into a cluster:
kind load docker-image my-app:latest --name my-dev-clusterPushes a Docker image built locally (e.g.,
docker build -t my-app:latest .) into the Kind cluster’s nodes. -
Load images from a tarball:
kind load image-archive my-images.tar --name my-dev-clusterLoads Docker images from a tar archive into the cluster.
-
Get Node IP addresses:
kind get nodes --name my-dev-clusterLists the Docker container names for the nodes in the specified cluster.
-
Get Node IP addresses (for direct access):
{% raw %} docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(kind get nodes -q) {% endraw %} ``` Retrieves the IP addresses of the Kind nodes (containers).
Cluster Configuration (using kind-config.yaml)
-
Example multi-node cluster configuration:
# kind-multi-node.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: workerDefines a cluster with one control plane and two worker nodes.
-
Example cluster with specific Kubernetes version:
# kind-config-version.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane image: kindest/node:v1.27.3@sha256:25003e47011402093194c5f37137763581103092112151938c2691e3d7d6395b # Example for v1.27.3Uses a specific Kind node image for a particular Kubernetes version. You can find available images on Kind’s releases page.
-
Example cluster with custom API server port:
# kind-config-port.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane extraPortMappings: - containerPort: 6443 # The Kubernetes API server port inside the container hostPort: 6444 # The port exposed on the Docker hostExposes the Kubernetes API server on port
6444on your host machine.
Node Image Management
-
List available node images:
kind get node-imageShows the default node image Kind will use.
-
Build a custom node image:
kind build node-image --image-name my-custom-kind-node:latestBuilds a custom Docker image for a Kind node. Useful for testing specific Kubernetes versions or custom configurations.
Cluster Events
- Watch cluster events:
Monitors events happening within the cluster, often used to see pods starting up.kind create cluster --name watch-test kubectl cluster-info --context kind-watch-test kubectl get pods -n kube-system --watch
Other Utilities
-
Delete a specific cluster node:
kind delete node --name my-dev-cluster-control-plane # Replace with actual node name from 'kind get nodes'Deletes a specific node (Docker container) from a Kind cluster. Use with caution, as it can destabilize the cluster.
-
Get cluster diagnostic tarball:
kind export logs --dir ./kind-logs --name my-dev-clusterCollects logs and cluster information into a tarball for debugging.
Common Patterns
-
Setting kubectl context for a named cluster:
export KUBECONFIG="$(kind get kubeconfig --name my-dev-cluster)" # Or to merge into your existing kubeconfig kind get kubeconfig --name my-dev-cluster | tee -a ~/.kube/configEnsures
kubectlcommands target the correct Kind cluster. -
Deploying an application from local Docker image:
# 1. Build your Docker image docker build -t my-app:latest . # 2. Load the image into Kind kind load docker-image my-app:latest --name my-dev-cluster # 3. Apply your Kubernetes deployment manifest kubectl apply -f deployment.yamlA standard workflow for testing locally built containerized applications.
-
Exposing a service on the host machine: Use
hostPortin your Kubernetes Service definition orextraPortMappingsin the Kind config.# service-hostport.yaml apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8080 nodePort: 30080 # This will be exposed on the Kind node container type: NodePortThen access via
curl http://localhost:30080(iflocalhostresolves to the Kind node’s IP). For direct host access,extraPortMappingsis preferred. -
Debugging a running cluster:
# Get the container ID of the control plane node CONTROL_PLANE_NODE=$(docker ps -qf "label=io.x-k8s.kind.cluster=my-dev-cluster" -f "label=io.x-k8s.kind.role=control-plane") # Exec into the control plane node docker exec -it $CONTROL_PLANE_NODE bash # Inside the container, you can run kubectl, check logs, etc.Allows direct interaction with the Kubernetes components running inside the Docker containers.
Gotchas
- Port Conflicts: If you use
extraPortMappingsorNodePortservices, ensure the host ports are not already in use by other applications on your machine. kubectlContext: Kind automatically updates your~/.kube/configto point to the created cluster. If you have multiple Kubernetes configurations, be mindful of which context is active. Usekubectl config use-context <context-name>to switch.- Image Loading Performance: Loading large Docker images can take time. For faster iteration, consider building images directly within the cluster or using tools that support remote Docker daemons if available.
- Node Resource Limits: Kind nodes run as Docker containers, so they share your host machine’s resources. Complex deployments might hit resource limits faster than on a dedicated Kubernetes cluster.
- Network Isolation: By default, Kind nodes are on a separate Docker network. Accessing services running inside the cluster from your host machine requires specific port forwarding or Ingress configurations.
- No Persistent Storage by Default: Volumes created in Kind clusters are typically ephemeral unless you explicitly configure persistent storage using host paths or other mechanisms.