Kind K8s in Docker

Kind cheatsheet — create local Kubernetes clusters with Docker. kind create cluster, kind load docker-image, kind get clusters. Local K8s for development and CI.

7 min read

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 cluster
    

    Creates a local Kubernetes cluster with one control-plane node.

  • Create a cluster with a specific name:

    kind create cluster --name my-dev-cluster
    

    Creates 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.yaml
    

    Requires a kind-multi-node.yaml configuration file (see examples below).

  • Create a cluster from a configuration file:

    kind create cluster --config kind-config.yaml
    

    Creates a cluster using the settings defined in kind-config.yaml.

  • Keep nodes after cluster deletion:

    kind create cluster --retain-node-image
    

    Prevents Kind from deleting the Docker containers that make up the cluster nodes. Useful for debugging.

Cluster Deletion

  • Delete the default cluster:

    kind delete cluster
    

    Removes all Docker containers and resources associated with the default cluster.

  • Delete a specific named cluster:

    kind delete cluster --name my-dev-cluster
    

    Removes the cluster named my-dev-cluster.

  • Delete all clusters:

    kind delete clusters --all
    

    Removes all Kind clusters currently running.

Cluster Information and Management

  • List all Kind clusters:

    kind get clusters
    

    Shows the names of all Kind clusters available.

  • Get the kubeconfig for a cluster:

    kind get kubeconfig --name my-dev-cluster
    

    Outputs the kubeconfig content for the specified cluster. This is automatically merged into your default ~/.kube/config when creating a cluster.

  • Load Docker images into a cluster:

    kind load docker-image my-app:latest --name my-dev-cluster
    

    Pushes 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-cluster
    

    Loads Docker images from a tar archive into the cluster.

  • Get Node IP addresses:

    kind get nodes --name my-dev-cluster
    

    Lists 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: worker
    

    Defines 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.3
    

    Uses 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 host
    

    Exposes the Kubernetes API server on port 6444 on your host machine.

Node Image Management

  • List available node images:

    kind get node-image
    

    Shows the default node image Kind will use.

  • Build a custom node image:

    kind build node-image --image-name my-custom-kind-node:latest
    

    Builds a custom Docker image for a Kind node. Useful for testing specific Kubernetes versions or custom configurations.

Cluster Events

  • Watch cluster events:
    kind create cluster --name watch-test
    kubectl cluster-info --context kind-watch-test
    kubectl get pods -n kube-system --watch
    
    Monitors events happening within the cluster, often used to see pods starting up.

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-cluster
    

    Collects 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/config
    

    Ensures kubectl commands 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.yaml
    

    A standard workflow for testing locally built containerized applications.

  • Exposing a service on the host machine: Use hostPort in your Kubernetes Service definition or extraPortMappings in 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: NodePort
    

    Then access via curl http://localhost:30080 (if localhost resolves to the Kind node’s IP). For direct host access, extraPortMappings is 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 extraPortMappings or NodePort services, ensure the host ports are not already in use by other applications on your machine.
  • kubectl Context: Kind automatically updates your ~/.kube/config to point to the created cluster. If you have multiple Kubernetes configurations, be mindful of which context is active. Use kubectl 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.