Quick Start 🔗︎

This guide covers getting started with the kind command.

If you are having problems please see the known issues guide.

Installation 🔗︎

You can either install kind with GO111MODULE="on" go get sigs.k8s.io/kind@v0.5.1 or clone this repo and run make build from the repository.

NOTE: please use the latest Go to do this, ideally go 1.13 or greater. A version of Go officially supported upstream by the Go project must be used.

This will put kind in $(go env GOPATH)/bin. You may need to add that directory to your $PATH as shown here if you encounter the error kind: command not found after installation.

Without installing go, kind can be built reproducibly with docker using make build.

Stable binaries are also available on the releases page. Stable releases are generally recommended for CI usage in particular. To install, download the binary for your platform from “Assets” and place this into your $PATH.

On macOS / Linux:

curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-$(uname)-amd64
chmod +x ./kind
mv ./kind /some-dir-in-your-PATH/kind

On Windows:

curl.exe -Lo kind-windows-amd64.exe https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-windows-amd64
Move-Item .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe

Creating a Cluster 🔗︎

Creating a Kubernetes cluster is as simple as kind create cluster.

This will bootstrap a Kubernetes cluster using a pre-built node image - you can find it on docker hub kindest/node. If you desire to build the node image yourself see the building image section. To specify another image use the --image flag.

By default, the cluster will be given the name kind. Use the --name flag to assign the cluster a different context name.

If you want the create cluster command to block until the control plane reaches a ready status, you can use the --wait flag and specify a timeout. To use --wait you must specify the units of the time to wait. For example, to wait for 30 seconds, do --wait 30s, for 5 minutes do --wait 5m, etc.

Interacting With Your Cluster 🔗︎

After creating a cluster, you can use kubectl to interact with it by using the configuration file generated by kind:

export KUBECONFIG="$(kind get kubeconfig-path)"
kubectl cluster-info

kind get kubeconfig-path returns the location of the generated confguration file. If you gave a non-default cluster context name to your cluster, then you can specify the name by using the --name flag.

To see all the clusters you have created, you can use the get clusters command.

For example, let’s say you create two clusters:

kind create cluster # Default cluster context name is `kind`.
kind create cluster --name kind-2

When you list your kind clusters, you will see something like the following:

kind get clusters

Both of these clusters will have a kubeconfig file to go along with them:

kind get kubeconfig-path

kind get kubeconfig-path --name kind-2

Deleting a Cluster 🔗︎

If you created a cluster with kind create cluster then deleting is equally simple:

kind delete cluster

If the flag --name is not specified, kind will use the default cluster context name kind and delete that cluster.

Loading an Image Into Your Cluster 🔗︎

Docker images can be loaded into your cluster nodes with: kind load docker-image my-custom-image

Additionally, image archives can be loaded with: kind load image-archive /my-image-archive.tar

This allows a workflow like:

docker build -t my-custom-image:unique-tag ./my-image-dir
kind load docker-image my-custom-image:unique-tag
kubectl apply -f my-manifest-using-my-image:unique-tag

Note: The Kubernetes default pull policy is IfNotPresent unless the image tag is :latest in which case the default policy is Always. IfNotPresent causes the Kubelet to skip pulling an image if it already exists. If you want those images loaded into node to work as expected, please:

and / or:

See Kubernetes imagePullPolicy for more information.

See also: Using kind with Private Registries.

Building Images 🔗︎

kind runs a local Kubernetes cluster by using Docker containers as “nodes”. kind uses the node-image to run Kubernetes artifacts, such as kubeadm or kubelet. The node-image in turn is built off the base-image, which installs all the dependencies needed for Docker and Kubernetes to run in a container.

See building the base image for more advanced information.

Currently, kind supports two different ways to build a node-image if you have the Kubernetes source in your host machine ($GOPATH/src/k8s.io/kubernetes), by using docker or bazel. To specify the build type use the flag --type. Note however that using --type=bazel on Windows or MacOS will not work currently due to Kubelet using CGO which requires GCC/glibc for linux. A workaround may be enabled in the future.

kind will default to using the build type docker if none is specified.

kind build node-image --type bazel

Similarly as for the base-image command, you can specify the name and tag of the resulting node image using the flag --image.

If you previously changed the name and tag of the base image, you can use here the flag --base-image to specify the name and tag you used.

Note: If you are running kind on MacOS or Windows then it is recommended that you have at least 8GB of RAM dedicated to the virtual machine (VM) running the Docker engine otherwise Building Kubernetes may fail.

To change the resource limits for the Docker on Mac, you’ll need to open the Preferences menu.

Now, go to the Advanced settings page, and change the settings there, see changing Docker’s resource limits.
Setting 8Gb of memory in Docker for Mac

To change the resource limits for the Docker on Windows, you’ll need to right-click the Moby icon on the taskbar, and choose “Settings”. If you see “Switch to Linux Containers”, then you’ll need to do that first before opening “Settings”

Now, go to the Advanced settings page, and change the settings there, see changing Docker’s resource limits.

Setting 8Gb of memory in Docker for Windows

You may also try removing any unused data left by the Docker engine - e.g., docker system prune.

Advanced 🔗︎

Building The Base Image 🔗︎

To build the base-image we use the build command:

kind build base-image

If you want to specify the path to the base image source files you can use the --source flag.

If --source is not specified, kind will attempt to automatically locate the images/base base source directory.

By default, the base image will be tagged as kindest/base:latest. If you want to change this, you can use the --image flag.

kind build base-image --image base:v0.1.0

Configuring Your kind Cluster 🔗︎

When creating your kind cluster, via create cluster, you can use a configuration file to run specific commands before or after systemd or kubeadm run. For a sample kind configuration file see kind-example-config. To specify a configuration file when creating a cluster, use the --config flag:

kind create cluster --config kind-example-config.yaml

Multi-node clusters 🔗︎

In particular, many users may be interested in multi-node clusters. A simple configuration for this can be achieved with the following config file contents:

# three node (two workers) cluster config
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
- role: control-plane
- role: worker
- role: worker

Control-plane HA 🔗︎

You can also have a cluster with multiple control-plane nodes:

# a cluster with 3 control-plane nodes and 3 workers
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker

Mapping ports to the host machine 🔗︎

You can map extra ports from the nodes to the host machine with extraPortMappings:

kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
- role: control-plane
- role: worker
  - containerPort: 80
    hostPort: 80
    listenAddress: "" # Optional, defaults to ""
    protocol: udp # Optional, defaults to tcp

This can be useful if using NodePort services or daemonsets exposing host ports.

Note: binding the listenAddress to may affect your ability to access the service.

Enable Feature Gates in Your Cluster 🔗︎

Feature gates are a set of key=value pairs that describe alpha or experimental features. In order to enable a gate you have to customize your kubeadm configuration, and it will depend on what gate and component you want to enable. An example kind config can be:

# this config file contains all config fields with comments
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
# patch the generated kubeadm config with some extra settings
- |
  apiVersion: kubeadm.k8s.io/v1beta2
  kind: ClusterConfiguration
    name: config
      "feature-gates": "FeatureGateName=true"
      "feature-gates": "FeatureGateName=true"
      "feature-gates": "FeatureGateName=true"
- |
  apiVersion: kubeadm.k8s.io/v1beta2
  kind: InitConfiguration
    name: config
      "feature-gates": "FeatureGateName=true"
# 1 control plane node and 3 workers
# the control plane node config
- role: control-plane
# the three workers
- role: worker
- role: worker
- role: worker

IPv6 clusters 🔗︎

You can run ipv6 only clusters using kind, but first you need to enable ipv6 in your docker daemon by editing /etc/docker/daemon.json as described here. Ensure you systemctl restart docker to pick up the changes.

# an ipv6 cluster
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
  ipFamily: ipv6
# the control plane node
- role: control-plane
- role: worker
- role: worker

Configure kind to use a proxy 🔗︎

If you are running kind in an environment that requires a proxy, you may need to configure kind to use it.

You can configure kind to use a proxy using one or more of the following environment variables (uppercase takes precedence):

Note: If you set a proxy it would be used for all the connection requests. It’s important that you define what addresses doesn’t need to be proxied with the NO_PROXY variable, typically you should avoid to proxy your docker network range NO_PROXY=

Exporting Cluster Logs 🔗︎

kind has the ability to export all kind related logs for you to explore. To export all logs from the default cluster (context name kind):

kind export logs
Exported logs to: /tmp/396758314

Like all other commands, if you want to perform the action on a cluster with a different context name use the --name flag.

As you can see, kind placed all the logs for the cluster kind in a temporary directory. If you want to specify a location then simply add the path to the directory after the command:

kind export logs ./somedir  
Exported logs to: ./somedir

The structure of the logs will look more or less like this:

├── docker-info.txt
└── kind-control-plane/
    ├── containers
    ├── docker.log
    ├── inspect.json
    ├── journal.log
    ├── kubelet.log
    ├── kubernetes-version.txt
    └── pods/

The logs contain information about the Docker host, the containers running kind, the Kubernetes cluster itself, etc.