---
title: "Kind multi-node install"
description: "Install Calico Open Source on a single- or multi-node Kind cluster for testing or development in roughly 10 minutes."
product: "Calico Open Source"
version: "3.32 (latest)"
section: "Installing and upgrading"
canonical_url: "https://docs.tigera.io/calico/latest/getting-started/kubernetes/kind"
---

# Kind multi-node install

## Big picture

This tutorial gets you a multi node Kind cluster with Calico in approximately 10 minutes.

## Value

kind is a tool for running local Kubernetes clusters using Docker container "nodes".

The geeky details of what you get:

| Policy | IPAM   | CNI    | Overlay | Routing | Datastore  |
| ------ | ------ | ------ | ------- | ------- | ---------- |
| Calico | Calico | Calico | VXLAN   | Calico  | Kubernetes |

?

## Before you begin

- Ensure Docker is installed
- Install, but do not create cluster, kind. [How to install Kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)
- Install kubectl.[How to install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)

## How to

### Create a multi-node kind cluster

KIND ships with a simple networking implementation ("kindnetd") based around standard CNI plugins (`ptp`, `host-local`, …) and simple netlink routes. You need to disable the default CNI to use Calico CNI.

Kind cluster creation can be modified by [configuration file](https://kind.sigs.k8s.io/docs/user/quick-start/#creating-a-cluster). Here you are providing kind configuration to disable simple networking implementation (default CNI) and change the pod ip CIDR.

1. Disable the default CNI to use Calico CNI by running the following command:

```bash
cat > values.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
  disableDefaultCNI: true
  podSubnet: 192.168.0.0/16
EOF
```

2. Start your Kind cluster with one control plane and two worker nodes by running the following command:

```bash
kind create cluster --config values.yaml --name dev
```

3. Confirm that you now have three nodes in your cluster by running the following command:

```bash
kubectl get nodes -o wide
```

It should return something like the following.

```text
NAME                STATUS      ROLES           AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION    CONTAINER-RUNTIME
dev-control-plane   NotReady    control-plane   4m     v1.25.0   172.18.0.2    <none>        Ubuntu 22.04.1 LTS   5.10.0-17-amd64   containerd://1.6.7
dev-worker          NotReady    <none>          4m     v1.25.0   172.18.0.4    <none>        Ubuntu 22.04.1 LTS   5.10.0-17-amd64   containerd://1.6.7
dev-worker2         NotReady    <none>          4m     v1.25.0   172.18.0.3    <none>        Ubuntu 22.04.1 LTS   5.10.0-17-amd64   containerd://1.6.7
```

### Install Calico

<!-- tabs -->

**Tab: Operator**

1. Install the Calico operator and custom resource definitions.

```bash
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/v1_crd_projectcalico_org.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/tigera-operator.yaml
```

2. Install Calico by creating the necessary custom resource. For more information on configuration options available in this manifest, see [the installation reference](https://docs.tigera.io/calico/latest/reference/installation/api.md).

> **SECONDARY:** Before creating this manifest, read its contents and make sure its settings are correct for your environment. For example, if you have replaced `pod-network-cidr` you must change it in this file as well.

```bash
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/custom-resources.yaml
```

**Tab: Manifest**

Install Calico by using the following command.

```bash
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml
```

> **SECONDARY:** Due to the large size of the CRD bundle, `kubectl apply` might exceed request limits. Instead, use `kubectl create` or `kubectl replace`.

> **SECONDARY:** You can also [view the YAML in a new tab](https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml).

You should see the following output.

```text
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
```

<!-- /tabs -->

### Verify Calico installation

You can verify Calico installation in your cluster by issuing the following command.

```bash
watch kubectl get pods -l k8s-app=calico-node -A
```

You should see a result similar to the below. Note that the namespace might be different, depending on the method you followed.

```text
NAMESPACE     NAME                READY   STATUS    RESTARTS   AGE
kube-system   calico-node-2xcf4   1/1     Running   0          57s
kube-system   calico-node-gkqkg   1/1     Running   0          57s
kube-system   calico-node-j44hp   1/1     Running   0          57s

```

Use `ctrl+c` to break out of watch.

Congratulations you now have a Kind cluster equipped with Calico

### Clean up

Issuing a delete command will destroy the cluster that you created in this tutorial.

```bash
kind delete cluster --name dev
```

## Next steps

**Required**

- [Install and configure calicoctl](https://docs.tigera.io/calico/latest/operations/calicoctl/install.md)

**Recommended tutorials**

- [Secure a simple application using the Kubernetes NetworkPolicy API](https://docs.tigera.io/calico/latest/network-policy/get-started/kubernetes-policy/kubernetes-policy-basic.md)
- [Control ingress and egress traffic using the Kubernetes NetworkPolicy API](https://docs.tigera.io/calico/latest/network-policy/get-started/kubernetes-policy/kubernetes-policy-advanced.md)
- [Run a tutorial that shows blocked and allowed connections in real time](https://docs.tigera.io/calico/latest/network-policy/get-started/kubernetes-policy/kubernetes-demo.md)
