Kind est une des solutions les plus simples et rapides pour déployer un cluster Kubernetes à des fins de tests sur une machine de développement. Kind supporte aussi bien Linux et macOS que Windows et il fait partie des installeurs Kubernetes certifiés par la CNCF.

Création d’un premier cluster

Une fois Kind installé, la façon la plus rapide d’obtenir un cluster est la suivante :

$ kind create cluster --name test
Creating cluster "test" ...
 ✓ Ensuring node image (kindest/node:v1.25.3) 🖼
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-test"
...

Kind créé automatiquement un contexte Kubernetes…

$ kubectl cluster-info --context kind-test
Kubernetes control plane is running at https://127.0.0.1:36661
CoreDNS is running at https://127.0.0.1:36661/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

… et active ce contexte par défaut :

$ kubectl config current-context
kind-test

On peut donc directement utiliser kubectl pour intéragir avec le cluster nouvellement créé :

$ kubectl get nodes
NAME                 STATUS   ROLES           AGE     VERSION
test-control-plane   Ready    control-plane   2m44s   v1.25.3

Si on regarde ce qu’il se passe au niveau Docker, on constate qu’un conteneur a bien été créé :

$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                       NAMES
8cad19604574   kindest/node:v1.25.3   "/usr/local/bin/entr…"   4 minutes ago   Up 4 minutes   127.0.0.1:36661->6443/tcp   test-control-plane

Et oui, Kind déploie les clusters Kubernetes dans des conteneurs Docker !

Manipuler les clusters

Kind permet de lister les clusters existants :

$ kind get clusters
test

Et la suppression d’un cluster est tout aussi simple :

$ kind delete cluster --name test
Deleting cluster "test" ...

Utilisation d’un fichier de configuration

Si on souhaite configurer plus finement notre cluster et son comportement, il est possible de créer un fichier de configuration, par exemple :

mon-cluster.yaml ouvrir

---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mon-cluster
nodes:
- role: control-plane

Créons le cluster :

$ kind create cluster --config mon-cluster.yaml
Creating cluster "mon-cluster" ...
 ✓ Ensuring node image (kindest/node:v1.25.3) 🖼
 ...

Choisir sa version de Kubernetes

La version de Kubernetes est liée à la version de Kind qui est installée sur le poste de travail.

Pour obtenir le détail des versions compatibles, il faut se rendre sur la page de Releases de Kind.

Exemple de déploiement d’un cluster en version 1.23 :

mon-cluster-version.yaml ouvrir

---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mon-cluster
nodes:
- role: control-plane
  image: kindest/node:v1.23.13@sha256:ef453bb7c79f0e3caba88d2067d4196f427794086a7d0df8df4f019d5e336b61
$ kind create cluster --config mon-cluster-version.yaml 
Creating cluster "mon-cluster" ...
 ✓ Ensuring node image (kindest/node:v1.23.13) 🖼 
 ...

Déploiement d’un ingress controller Nginx

Il est possible de déployer facilement un ingress controller Nginx avec la configuration suivante :

mon-cluster-ingress.yaml ouvrir

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mon-cluster
nodes:
- role: control-plane
  kubeadmConfigPatches:
  # Install ingress controller  
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"        
  # Configure ingress ports
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP

Il faut ensuite déployer le fichier yaml suivant sur le cluster :

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
deployment.apps/ingress-nginx-controller created
...

Les composants de l’ingress controller sont déployés dans le namespace ingress-nginx.

Création d’un cluster multi-noeuds

Kind ne se limite pas à des clusters à noeud unique comme dans nos exemples précédents. Nous pouvons aussi déployer des clusters multi-noeuds. Pour cela, dans le fichier de configuration, il nous suffit d’ajouter de nouvelles entrées .nodes.role en précisant la valeur worker :

mon-cluster-multinodes.yaml ouvrir

---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mon-cluster
nodes:
- role: control-plane
- role: worker
- role: worker

L’utilisation de ce fichier permet de créer un cluster avec 1 noeud Master et 2 noeuds Worker :

$ kind create cluster --config mon-cluster-multinodes.yaml 
Creating cluster "mon-cluster" ...
 ✓ Ensuring node image (kindest/node:v1.25.3) 🖼
 ✓ Preparing nodes 📦 📦 📦  
 ...
 ✓ Joining worker nodes 🚜 
 ...

Vérifions cela :

$ kubectl get nodes
NAME                        STATUS   ROLES           AGE    VERSION
mon-cluster-control-plane   Ready    control-plane   109s   v1.25.3
mon-cluster-worker          Ready    <none>          90s    v1.25.3
mon-cluster-worker2         Ready    <none>          77s    v1.25.3

Et côté Docker :

$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED         STATUS         PORTS                       NAMES
2c75bb06ada6   kindest/node:v1.25.3   "/usr/local/bin/entr…"   2 minutes ago   Up 2 minutes                               mon-cluster-worker
307ea39b5e4b   kindest/node:v1.25.3   "/usr/local/bin/entr…"   2 minutes ago   Up 2 minutes                               mon-cluster-worker2
7d0ac01ec614   kindest/node:v1.25.3   "/usr/local/bin/entr…"   2 minutes ago   Up 2 minutes   127.0.0.1:36285->6443/tcp   mon-cluster-control-plane

Création d’un cluster Haute Disponibilité

Même simplicité pour déployer un cluster avec plusieurs noeuds Masters :

mon-cluster-multinodes-ha.yaml ouvrir

---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mon-cluster
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
$ kind create cluster --config mon-cluster-multinodes-ha.yaml 
Creating cluster "mon-cluster" ...
 ✓ Ensuring node image (kindest/node:v1.25.3) 🖼
 ✓ Preparing nodes 📦 📦 📦 📦 📦 📦  
 ✓ Configuring the external load balancer ⚖️ 
 ...
 ✓ Joining more control-plane nodes 🎮 
 ✓ Joining worker nodes 🚜 
 ...

Voyons si les noeuds sont bien présents :

$ kubectl get nodes
NAME                         STATUS   ROLES           AGE     VERSION
mon-cluster-control-plane    Ready    control-plane   3m11s   v1.25.3
mon-cluster-control-plane2   Ready    control-plane   2m57s   v1.25.3
mon-cluster-control-plane3   Ready    control-plane   112s    v1.25.3
mon-cluster-worker           Ready    <none>          92s     v1.25.3
mon-cluster-worker2          Ready    <none>          92s     v1.25.3
mon-cluster-worker3          Ready    <none>          92s     v1.25.3

Et les 6 conteneurs Docker sont bien là :

$ docker ps
CONTAINER ID   IMAGE                                COMMAND                  CREATED         STATUS         PORTS                       NAMES
37b699fac28a   kindest/haproxy:v20220607-9a4d8d2a   "haproxy -sf 7 -W -d…"   3 minutes ago   Up 3 minutes   127.0.0.1:39785->6443/tcp   mon-cluster-external-load-balancer
3410123a98a7   kindest/node:v1.25.3                 "/usr/local/bin/entr…"   3 minutes ago   Up 3 minutes   127.0.0.1:38239->6443/tcp   mon-cluster-control-plane
d8d30f3b378d   kindest/node:v1.25.3                 "/usr/local/bin/entr…"   3 minutes ago   Up 3 minutes   127.0.0.1:45199->6443/tcp   mon-cluster-control-plane2
a8130acf26e3   kindest/node:v1.25.3                 "/usr/local/bin/entr…"   3 minutes ago   Up 3 minutes                               mon-cluster-worker
990abbad3ca6   kindest/node:v1.25.3                 "/usr/local/bin/entr…"   3 minutes ago   Up 3 minutes                               mon-cluster-worker3
5ee4caf05b8b   kindest/node:v1.25.3                 "/usr/local/bin/entr…"   3 minutes ago   Up 3 minutes   127.0.0.1:41971->6443/tcp   mon-cluster-control-plane3
81696dbbdc7c   kindest/node:v1.25.3                 "/usr/local/bin/entr…"   3 minutes ago   Up 3 minutes                               mon-cluster-worker2

Eviter le redémarrage automatique d’un cluster

Par défaut Kind configure les clusters pour qu’ils redémarrent au reboot du poste de travail. C’est pratique qu’on on travaille avec un seul cluster mais ça peut vite être embêtant si on a plusieurs clusters déclarés et que tous redémarrent systématiquement quand vous allumez votre machine en arrivant au boulot le matin !

Heureusement voici une petite astuce pour désactiver ce redémarrage automatique pour un cluster donné de la manière suivante :

docker stop kind-control-plane
docker update --restart=no kind-control-plane

kind-control-plane est le nom du conteneur docker.