site/content/docs/user/configuration.md
To configure kind cluster creation, you will need to create a YAML config file. This file follows Kubernetes conventions for versioning etc. <!--todo links for this-->
A minimal valid config is:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
This config merely specifies that we are configuring a KIND cluster (kind: Cluster)
and that the version of KIND's config we are using is v1alpha4 (apiVersion: kind.x-k8s.io/v1alpha4).
Any given version of kind may support different versions which will have different options and behavior. This is why we must always specify the version.
This mechanism is inspired by Kubernetes resources and component config.
To use this config, place the contents in a file config.yaml and then run
kind create cluster --config=config.yaml from the same directory.
You can also include a full file path like kind create cluster --config=/foo/bar/config.yaml.
The structure of the Cluster type is defined by a Go struct, which is described
here.
Unless otherwise noted, parameters passed to the CLI take precedence over their equivalents in a config file. For example, if you invoke:
{{< codeFromInline lang="bash" >}} kind create cluster --name my-cluster {{< /codeFromInline >}}
The name my-cluster will be used regardless of the presence of that value in
your config file.
The following high level options are available.
NOTE: not all options are documented yet! We will fix this with time, PRs welcome!
You can give your cluster a name by specifying it in your config:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 name: app-1-cluster {{< /codeFromInline >}}
Kubernetes feature gates can be enabled cluster-wide across all Kubernetes components with the following config:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 featureGates:
"CSIMigration": true {{< /codeFromInline >}}
Kubernetes API server runtime-config can be toggled using the runtimeConfig
key, which maps to the --runtime-config kube-apiserver flag.
This may be used to e.g. disable beta / alpha APIs, or even enable deprecated APIs.
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 runtimeConfig: "api/alpha": "false" "apps/v1beta2": "true" {{< /codeFromInline >}}
Multiple details of the cluster's networking can be customized under the
networking field.
KIND has support for IPv4, IPv6 and dual-stack clusters, with the default being ipv4. You can change this by setting ipFamily under networking to ipv6 or dual, see below for more requirements.
You can run IPv6 single-stack clusters using kind, if the host that runs the docker containers support IPv6.
Most operating systems / distros have IPv6 enabled by default, but you can check on Linux with the following command:
sudo sysctl net.ipv6.conf.all.disable_ipv6
You should see:
net.ipv6.conf.all.disable_ipv6 = 0
If you are using Docker on Windows or Mac, you will need to use an IPv4 port forward for the API Server from the host because IPv6 port forwards don't work on these platforms, you can do this with the following config:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: ipFamily: ipv6 apiServerAddress: 127.0.0.1 {{< /codeFromInline >}}
On Linux all you need is:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: ipFamily: ipv6 {{< /codeFromInline >}}
You can run dual stack clusters using kind 0.11+, on kubernetes versions 1.20+.
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: ipFamily: dual {{< /codeFromInline >}}
The API Server listen address and port can be customized with: {{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking:
apiServerAddress: "127.0.0.1"
apiServerPort: 6443 {{< /codeFromInline >}}
{{< securitygoose >}}NOTE: You should really think thrice before exposing your kind cluster publicly! kind does not ship with state of the art security or any update strategy (other than disposing your cluster and creating a new one)! We strongly discourage exposing kind to anything other than loopback.{{</ securitygoose >}}
You can configure the subnet used for pod IPs by setting
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: podSubnet: "10.244.0.0/16" {{< /codeFromInline >}}
By default, kind uses 10.244.0.0/16 pod subnet for IPv4 and fd00:10:244::/56 pod subnet for IPv6.
You can configure the Kubernetes service subnet used for service IPs by setting
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: serviceSubnet: "10.96.0.0/12" {{< /codeFromInline >}}
By default, kind uses 10.96.0.0/16 service subnet for IPv4 and fd00:10:96::/112 service subnet for IPv6.
KIND ships with a simple networking implementation ("kindnetd") based around
standard CNI plugins (ptp, host-local, ...) and simple netlink routes.
This CNI also handles IP masquerade.
You may disable the default to install a different CNI. This is a power user feature with limited support, but many common CNI manifests are known to work, e.g. Calico. {{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking:
disableDefaultCNI: true {{< /codeFromInline >}}
You can configure the kube-proxy mode that will be used, between iptables, nftables (Kubernetes v1.31+), and ipvs. By default iptables is used
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: kubeProxyMode: "nftables" {{< /codeFromInline >}}
To disable kube-proxy, set the mode to "none".
The kind: Cluster object has a nodes field containing a list of node
objects. If unset this defaults to:
nodes:
# one node hosting a control plane
- role: control-plane
You can create a multi node cluster with the following config:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4
nodes:
Multiple control-plane nodes may be specified in order to test a "high availability"
control plane.
The following options are available for setting on each entry in nodes.
NOTE: not all options are documented yet! We will fix this with time, PRs welcome!
You can set a specific Kubernetes version by setting the node's container image. You can find available image tags on the releases page. Please include the @sha256: image digest from the image in the release notes, as seen in this example:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:
Note: Kubernetes versions are expressed as x.y.z, where x is the major version, y is the minor version, and z is the patch version, following Semantic Versioning terminology. For more information, see Kubernetes Release Versioning.
Extra mounts can be used to pass through storage on the host to a kind node for persisting data, mounting through code etc.
{{< codeFromFile file="static/examples/config-with-mounts.yaml" lang="yaml" >}}
NOTE: If you are using Docker for Mac or Windows check that the hostPath is included in the Preferences -> Resources -> File Sharing.
For more information see the Docker file sharing guide.
Extra port mappings can be used to port forward to the kind nodes. This is a cross-platform option to get traffic into your kind cluster.
If you are running Docker without the Docker Desktop Application on Linux, you can simply send traffic to the node IPs from the host without extra port mappings. With the installation of the Docker Desktop Application, whether it is on macOs, Windows or Linux, you'll want to use these.
You may also want to see the Ingress Guide.
NOTE: If you're running Kind on a remote host and need to send traffic to Kind node IPs from a different host than where kind is running, you need to configure port-mapping.
{{< codeFromFile file="static/examples/config-with-port-mapping.yaml" lang="yaml" >}}
An example http pod mapping host ports to a container port.
{{< codeFromInline lang="yaml">}} kind: Pod apiVersion: v1 metadata: name: foo spec: containers:
To use port mappings with NodePort, the kind node containerPort and the service nodePort needs to be equal.
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:
And then set nodePort to be 30950.
{{< codeFromInline lang="yaml">}} kind: Pod apiVersion: v1 metadata: name: foo labels: app: foo spec: containers:
apiVersion: v1 kind: Service metadata: name: foo spec: type: NodePort ports:
Extra labels might be useful for working with nodeSelectors.
An example label for specifying a tier label:
{{< codeFromInline lang="yaml">}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:
KIND uses kubeadm
to configure cluster nodes.
Formally KIND runs kubeadm init on the first control-plane node, we can customize the flags by using the kubeadm
InitConfiguration
(spec)
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:
If you want to do more customization, there are four configuration types available during kubeadm init: InitConfiguration, ClusterConfiguration, KubeProxyConfiguration, KubeletConfiguration. For example, we could override the apiserver flags by using the kubeadm ClusterConfiguration (spec):
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:
NOTE: When using
KubeletConfiguration, kubeadm only reads the kubelet configuration from the first node, which will apply to all nodes. This is a current limitation.
As a result, if you want to change the kubelet's configuration for any additional node, such as applying a taint, you must use JoinConfiguration:
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 name: test nodes:
On every additional node configured in the KIND cluster,
worker or control-plane (in HA mode),
KIND runs kubeadm join which can be configured using the
JoinConfiguration
(spec)
{{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:
If you need more control over patching, strategic merge and JSON6092 patches can
be used as well. These are specified using files in a directory, for example
./patches/kube-controller-manager.yaml could be the following.
{{< codeFromInline lang="yaml" >}} apiVersion: v1 kind: Pod metadata: name: kube-controller-manager namespace: kube-system spec: containers:
Then in your kind YAML configuration use the following.
{{< codeFromInline lang="yaml" >}} nodes:
kubeadmConfigPatches:
Note the extraMounts stanza. The node is a container created by
kind. kubeadm is run inside this node container, and the local directory
that contains the patches has to be accessible to kubeadm. extraMounts
plumbs a local directory through to this node container.
This example was for changing the manager in the control plane. To use a patch
for a worker node, use a JoinConfiguration patch and an extraMounts stanza
for the worker role.