Minikube, Kind, and K3d all let you run Kubernetes locally, but they achieve it in radically different ways, making them suited for entirely different workflows.

Let’s see Kind in action. Imagine you want to spin up a multi-node cluster with a specific Kubernetes version and then deploy an application.

# Create a cluster with two nodes (a control-plane and a worker)
kind create cluster --name my-test-cluster --nodes 2 --image kindest/node:v1.28.0

# Verify the cluster is running and nodes are ready
kubectl cluster-info --context kind-my-test-cluster
kubectl get nodes

# Load a Docker image into the cluster
docker tag my-app:latest my-app:latest
kind load docker-image my-app:latest --name my-test-cluster

# Deploy your application
kubectl apply -f my-app.yaml

Here, kind leverages Docker containers as nodes. This is its core differentiator. When you create a kind cluster, you’re essentially running Docker containers that act like Kubernetes nodes. The control plane runs in one container, and worker nodes run in others. This makes kind incredibly fast to start and stop, and also makes it easy to manage the lifecycle of your "nodes" via Docker commands.

The problem kind solves is providing a fast, disposable, and reproducible Kubernetes environment for development and testing, particularly when you need to test Kubernetes features or operators that interact with the cluster at a node level. Because each node is a Docker container, you can easily delete and recreate clusters, or even run multiple clusters simultaneously, each with its own isolated set of Docker containers.

The mental model for kind is: Kubernetes control plane and nodes are Docker containers. This has profound implications. Upgrading Kubernetes is as simple as pulling a new kindest/node image and recreating the cluster. Testing multi-node scenarios is trivial – just specify --nodes 3 or more. Because your "nodes" are just containers, you can docker exec into them to inspect their filesystem or running processes, offering a level of direct access not easily achievable with Minikube or K3d.

Minikube, on the other hand, uses a VM or a bare-metal installation for its single node. It’s been around the longest and is often the default choice for beginners. It abstracts away the underlying virtualization or containerization, presenting a single Kubernetes node that you interact with via kubectl.

# Start Minikube (defaults to VirtualBox or Docker driver)
minikube start --driver=docker --kubernetes-version=v1.27.5

# Check status and access kubectl
minikube status
kubectl get nodes
minikube dashboard

Minikube’s strength is its simplicity for getting a single-node cluster up and running quickly. It’s great for learning Kubernetes concepts or running single-node applications. It handles the complexities of setting up a VM or container for you. The downside is that it’s typically a single node, and simulating multi-node environments requires extra configuration or specific drivers.

K3d is a wrapper around K3s, which is a lightweight, certified Kubernetes distribution designed for edge, IoT, and development. K3s itself is a single binary that bundles etcd (or uses SQLite/external DB), the API server, controller manager, scheduler, and Kubelet. K3d then runs K3s inside Docker containers, similar to kind, but with K3s’s specific optimizations.

# Install k3d if you haven't already
# curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash

# Create a multi-node cluster with K3s
k3d cluster create my-k3s-cluster --servers 1 --agents 2 --k3s-server-arg "--disable=traefik"

# Verify
kubectl get nodes

K3d’s advantage is that it leverages K3s, making it extremely lightweight and fast. K3s is designed to have minimal dependencies. K3d makes it easy to run multi-server (HA) K3s clusters or single-server clusters with multiple agents, all within Docker. This is ideal for testing scenarios where you want a small footprint but need the robustness of a K3s distribution.

The most surprising thing about these tools is how their underlying implementation dictates their performance and testing capabilities. kind using Docker containers as nodes means you can docker exec directly into your "nodes" to poke around, which is invaluable for debugging operator issues or understanding how Kubernetes components interact at a fundamental level. Minikube, by abstracting the VM, makes it easier to get started but harder to introspect the "node" itself. K3d, by wrapping K3s, offers a highly optimized, minimal Kubernetes distribution that’s still containerized for ease of use.

Ultimately, the choice boils down to your needs: Minikube for simple, single-node learning; kind for reproducible, multi-node testing and development where direct node introspection is beneficial; and K3d for lightweight, performant Kubernetes clusters using the K3s distribution, especially for edge or multi-node simulations.

Once you’ve mastered local cluster management, you’ll likely want to explore how to integrate these local environments with CI/CD pipelines.

Want structured learning?

Take the full Minikube course →