k3d: K3s in Docker Cheatsheet
What it is
k3d is a tool for running K3s (a lightweight Kubernetes distribution) inside Docker containers, making it easy to spin up local Kubernetes clusters for development and testing.
Installation
Linux
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
macOS
brew install k3d
Windows
Download the appropriate binary from the k3d releases page and add it to your system’s PATH. Alternatively, use a package manager like Chocolatey:
choco install k3d
Core Concepts
- Cluster: A k3d cluster is a collection of nodes (containers) running K3s.
- Node: Each node in a k3d cluster is a Docker container. These can be server nodes (control plane) or agent nodes (workers).
- Context: When you create a cluster, k3d automatically updates your Kubernetes configuration (
~/.kube/config) to include a context for that cluster, allowing you to manage it withkubectl.
Commands / Usage
Cluster Management
Creating a Cluster
k3d cluster create mycluster
Creates a new k3s cluster named mycluster with one server node and no agent nodes.
k3d cluster create mycluster --servers 3 --agents 2
Creates a cluster named mycluster with 3 server nodes and 2 agent nodes.
k3d cluster create mycluster --k3s-arg '--disable=traefik'
Creates a cluster named mycluster and disables the default Traefik ingress controller.
k3d cluster create mycluster --registry-config k3d-registry.yaml
Creates a cluster named mycluster and configures a private Docker registry for it.
Listing Clusters
k3d cluster list
Lists all k3d clusters currently running.
Deleting a Cluster
k3d cluster delete mycluster
Deletes the cluster named mycluster.
k3d cluster delete --all
Deletes all k3d clusters.
Stopping a Cluster
k3d cluster stop mycluster
Stops the cluster named mycluster without deleting its data.
Starting a Cluster
k3d cluster start mycluster
Starts a previously stopped cluster named mycluster.
Listing Cluster Nodes
k3d node list mycluster
Lists the Docker containers (nodes) that make up the mycluster cluster.
Deleting Cluster Nodes
k3d node delete mycluster-server-0
Deletes a specific node (e.g., the first server node) from the mycluster cluster.
Accessing a Cluster’s Shell
k3d cluster exec mycluster -- /bin/sh
Opens a shell inside the first server node of the mycluster cluster.
Image Management
Loading Docker Images into a Cluster
k3d image import my-docker-image:latest -c mycluster
Loads the my-docker-image:latest from your local Docker daemon into the mycluster cluster.
k3d image import ./my-app.tar -c mycluster
Loads a Docker image saved as a tarball into the mycluster cluster.
Listing Images in a Cluster
k3d image list -c mycluster
Lists all Docker images available within the mycluster cluster.
Deleting Images from a Cluster
k3d image delete my-docker-image:latest -c mycluster
Deletes the my-docker-image:latest from the mycluster cluster.
Registry Management
Creating a Private Registry
k3d registry create myregistry --port 5000
Creates a new private Docker registry accessible on your host machine via port 5000.
Listing Registries
k3d registry list
Lists all k3d managed registries.
Deleting a Registry
k3d registry delete myregistry
Deletes the private registry named myregistry.
Configuration
Getting Cluster Configuration
k3d kubeconfig get mycluster
Prints the kubeconfig entry for the mycluster cluster.
k3d kubeconfig merge mycluster
Merges the kubeconfig for mycluster into your default ~/.kube/config.
Updating Cluster Configuration
k3d cluster update mycluster --servers 2
Updates the mycluster cluster to have 2 server nodes.
Helper Commands
Pinging a Cluster
k3d cluster ping mycluster
Checks if the mycluster cluster is responsive.
Showing Cluster Information
k3d cluster info mycluster
Displays detailed information about the mycluster cluster.
Common Patterns
Developing with kubectl
After creating a cluster (e.g., k3d cluster create dev), k3d automatically merges the cluster’s context into your ~/.kube/config. You can then use kubectl as usual:
kubectl get nodes
kubectl apply -f my-deployment.yaml
Loading a local Docker image for a deployment
Build your Docker image locally, then load it into your k3d cluster:
docker build -t myapp:latest .
k3d image import myapp:latest -c mycluster
kubectl apply -f my-deployment.yaml # The deployment uses image 'myapp:latest'
Running a multi-server HA cluster
k3d cluster create ha-cluster --servers 3 --agents 2
Using a custom Kubernetes version
k3d cluster create custom-k8s --image rancher/k3s:v1.25.7-k3s1
Mounting local directories into cluster nodes (for persistent development)
While k3d doesn’t have a direct flag for this during cluster creation, you can achieve it by manually creating a node with a bind mount. This is more advanced and often involves using docker run directly, then integrating it with k3d, or using Kubernetes PersistentVolumes with hostPath.
A simpler approach for development is to use a tool like Skaffold or Tilt which handles image building and deployment iteration.
Accessing Traefik Dashboard
If Traefik is enabled (default), you can access its dashboard:
- Get the Traefik service IP and port:
(This might vary slightly depending on k3d version and Traefik configuration).kubectl get svc traefik -n kube-system -o jsonpath='{.spec.ports[?(@.name=="web")].nodePort}' - Alternatively, use
k3dto port-forward:
Then accessk3d cluster exec mycluster -- /bin/sh -c 'kubectl port-forward service/traefik -n kube-system 8080:9000'http://localhost:8080in your browser.
Gotchas
- Image Loading: Images are loaded into the runtime of the nodes, not directly into the Docker daemon of the nodes. This means
docker imagesinside a k3d node will show the loaded images. - Node Restart: Stopping and starting a cluster preserves its state (pods, deployments), but restarting the underlying Docker daemon on your host might require recreating the cluster if it was not properly stopped.
- Resource Limits: Running multiple k3d clusters or complex workloads can consume significant host resources (CPU, RAM).
- Network Conflicts: If you run a custom registry on a port already in use on your host,
k3d registry createwill fail. kubectlContext: Ensure yourkubectlcontext is set to the desired k3d cluster if you have multiple Kubernetes clusters configured. Usekubectl config use-context <cluster-name>.- Ingress: By default, Traefik is installed. If you disable it, you’ll need to install your own ingress controller or use NodePort services for external access.
- Docker Daemon Access: k3d relies on your host’s Docker daemon to create and manage the node containers. Ensure Docker is running and accessible.