Aller au contenu
English
Conteneurs & Orchestration medium

Créer votre premier cluster Kubernetes local avec kind

30 min de lecture

logo kubernetes

kind create cluster vous donne un cluster Kubernetes 1.37 complet sur votre poste, en moins d'une minute et sans un centime de cloud. Cette formation utilise kind et rien d'autre : c'est le seul outil local qui livre la version enseignée ici et qui exécute du Kubernetes vanilla, celui que les certifications évaluent. Vous allez installer le binaire en vérifiant son empreinte, créer un cluster, contrôler qu'il répond, apprendre à l'arrêter et le recréer, puis passer à un cluster multi-nœuds quand un seul ne suffira plus.

  • Installer kind en vérifiant l'empreinte du binaire
  • Créer un cluster Kubernetes 1.37 en une commande
  • Vérifier que le cluster est réellement opérationnel
  • Arrêter, redémarrer et supprimer un cluster
  • Passer à un cluster multi-nœuds avec un fichier de configuration

Pourquoi apprendre Kubernetes sur un cluster local ?

Section intitulée « Pourquoi apprendre Kubernetes sur un cluster local ? »

Kubernetes s'apprend en cassant des choses, et un cluster jetable est le seul endroit où c'est sans conséquence. Vous allez supprimer des Pods pour voir ce qui les recrée, saturer un nœud pour comprendre le scheduler, casser un manifeste pour lire l'erreur. Sur un cluster partagé, chacun de ces gestes dérange quelqu'un. Sur votre poste, la remise à zéro tient en deux commandes.

Ce que le local apportePourquoi ça compte pour apprendre
GratuitAucune facture cloud, donc aucune raison de s'autocensurer
RapideUn cluster neuf en une vingtaine de secondes
JetableVous cassez, vous supprimez, vous recréez
StandardLes commandes kubectl sont exactement celles de la production

Trois outils créent des clusters Kubernetes dans Docker, et cette formation a tranché pour kind. Le choix ne relève pas du goût : la formation prépare cinq certifications CNCF qui évaluent du Kubernetes standard en version courante. Il faut donc un outil qui livre la version 1.37 et qui n'ajoute rien à Kubernetes. Un seul satisfait les deux critères.

Critèrekind 0.33k3d / k3sminikube 1.39
Livre Kubernetes 1.37oui, par défautnon, plafonne à 1.36.4oui
Exécute du Kubernetes vanillaouinon, k3s est une distribution à partoui
Création d'un cluster à 3 workers18 srapide147 s
Volumes persistants en multi-nœudsfonctionne sans réglagefonctionnedemande un module en plus
Répartiteur de charge intégrénonouivia un tunnel

Les durées ci-dessus ont été mesurées sur un même poste, images déjà téléchargées. Le premier lancement ajoute le temps de récupérer l'image du nœud, plusieurs centaines de mégaoctets. Sur le stockage, la documentation de minikube prévient elle-même que son provisionneur de volumes par défaut ne gère pas les clusters multi-nœuds, ce qui oblige à activer un module supplémentaire avant d'aborder les PersistentVolumeClaims.

L'argument décisif tient en une phrase du projet lui-même : kind « a été conçu avant tout pour tester Kubernetes », et il est un installeur certifié conforme par la CNCF. L'outil qui sert à valider Kubernetes en amont est, par construction, celui qui s'écarte le moins de Kubernetes.

k3d et minikube restent d'excellents outils, documentés ailleurs sur ce site. Ce que cette formation exclut, c'est qu'un de ses guides suppose autre chose qu'un cluster kind : sans cela, les sorties affichées ne correspondraient plus à ce que vous voyez.

kind n'a besoin de presque rien, parce qu'il délègue tout le travail lourd à Docker : chaque nœud du cluster est un conteneur. Si docker ps répond, vous avez déjà 90 % de ce qu'il faut.

  • Docker installé et fonctionnel
  • kubectl installé (guide d'installation)
  • environ 2 Go de RAM disponibles pour un cluster à un nœud
Vérifier que Docker répond
docker ps

Une liste, même vide, signifie que Docker est prêt. Le message Cannot connect to the Docker daemon signifie au contraire que le service n'est pas démarré : rien de la suite ne fonctionnera avant de l'avoir corrigé.

kind se distribue en binaire unique, sans dépendance et sans service à lancer. Le projet publie à côté de chaque version un fichier d'empreinte SHA-256 par plateforme : comparer le binaire téléchargé à cette empreinte garantit que vous exécutez bien ce que le projet a produit, et pas un fichier altéré en chemin. Le nom inscrit dans le fichier d'empreinte est le nom d'origine, il faut donc le conserver pendant la vérification et ne renommer qu'à l'installation.

Installer kind avec vérification d'empreinte
KIND_VERSION=v0.33.0
BASE="https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}"
curl -sSLO "${BASE}/kind-linux-amd64"
curl -sSL "${BASE}/kind-linux-amd64.sha256sum" | sha256sum --check -
sudo install -m 0755 kind-linux-amd64 /usr/local/bin/kind

La vérification doit afficher kind-linux-amd64: OK. Si elle affiche FAILED, supprimez le fichier et recommencez : ne l'installez pas. Sur macOS et Linux, brew install kind fait le même travail en gérant les mises à jour.

Vérifier la version installée
kind version
Résultat
kind v0.33.0 go1.26.7 linux/amd64

Prenez une version récente. Les versions antérieures à 0.33 ne savent pas créer un cluster Kubernetes 1.37 et échouent sur un message mentionnant une old API spec kubeadm.k8s.io/v1beta3.

Une seule commande suffit. Le nom que vous donnez sert de préfixe à tout ce qui sera créé : conteneurs, réseau Docker, contexte kubectl. Précisez toujours l'image du nœud : sans elle, vous héritez de la version figée dans votre binaire kind, qui prendra du retard à mesure que Kubernetes publie de nouvelles versions.

Créer le cluster
kind create cluster --name monapp --image kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5
Résultat
Creating cluster "monapp" ...
✓ Ensuring node image (kindest/node:v1.37.0)
✓ Preparing nodes
✓ Writing configuration
✓ Starting control-plane
✓ Installing CNI
✓ Installing StorageClass
Set kubectl context to "kind-monapp"
You can now use your cluster with:
kubectl cluster-info --context kind-monapp

Le @sha256:… qui suit le tag n'est pas décoratif : un tag peut être republié avec un contenu différent, un digest désigne un contenu et un seul. kind accepte cette forme et vous obtenez alors, à coup sûr, l'image de nœud sur laquelle cette formation a été écrite. Le tag reste écrit devant, pour que la commande reste lisible.

La ligne Ensuring node image est la plus longue au premier lancement : elle télécharge l'image kindest/node, qui contient un Kubernetes complet. Les créations suivantes réutilisent cette image et aboutissent en une vingtaine de secondes. La dernière ligne n'est qu'une suggestion, pas une commande exécutée : en revanche le contexte kubectl est déjà basculé sur ce nouveau cluster.

Rien de ce que kind vient de faire n'est magique, et le vérifier démystifie beaucoup Kubernetes. Le cluster tient dans un conteneur Docker par nœud, que vous pouvez lister, inspecter et arrêter à la main. La conséquence pratique compte : un docker system prune un peu large détruit votre cluster sans passer par kind.

Élément crééCe que c'est
Conteneur de nœudmonapp-control-plane, un conteneur qui exécute un Kubernetes complet
Réseau DockerUn réseau nommé kind, partagé par tous vos clusters kind
Contexte kubectlkind-monapp, ajouté et sélectionné automatiquement
Voir le conteneur du cluster
docker ps --filter "name=monapp"
Résultat
NAMES IMAGE STATUS
monapp-control-plane kindest/node:v1.37.0 Up 9 seconds

Un cluster qui répond n'est pas forcément un cluster prêt. Ces quatre contrôles se font dans l'ordre, du plus général au plus précis, et chacun élimine une cause différente : le mauvais contexte, l'API injoignable, un nœud pas encore admis, un composant système en échec.

  1. Vérifiez le contexte kubectl

    Fenêtre de terminal
    kubectl config current-context
    Résultat
    kind-monapp

    C'est le contrôle le plus rentable de la liste. La mésaventure classique consiste à déployer sur le dernier cluster créé en croyant travailler sur le précédent.

  2. Interrogez l'API du cluster

    Fenêtre de terminal
    kubectl cluster-info
    Résultat
    Kubernetes control plane is running at https://127.0.0.1:34201
    CoreDNS is running at https://127.0.0.1:34201/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

    Le numéro de port est tiré au hasard à la création, le vôtre sera différent. Ce qui compte est que la commande réponde : un message The connection to the server ... was refused signifie que le cluster est arrêté ou que le contexte pointe ailleurs.

  3. Listez les nœuds

    Fenêtre de terminal
    kubectl get nodes
    Résultat
    NAME STATUS ROLES AGE VERSION
    monapp-control-plane Ready control-plane 25s v1.37.0

    La colonne VERSION confirme la version sur laquelle vous allez travailler : vérifiez qu'elle affiche bien v1.37.0. Dans les premières secondes qui suivent la création, le statut affiche NotReady : le réseau du cluster n'est pas encore en place. C'est normal, attendez une dizaine de secondes.

  4. Vérifiez les composants système

    Fenêtre de terminal
    kubectl get pods -A
    Résultat
    NAMESPACE NAME READY STATUS RESTARTS AGE
    kube-system coredns-559f6c778d-8qtdd 1/1 Running 0 15s
    kube-system coredns-559f6c778d-wdpf7 1/1 Running 0 15s
    kube-system etcd-monapp-control-plane 1/1 Running 0 24s
    kube-system kindnet-g9z8s 1/1 Running 0 15s
    kube-system kube-apiserver-monapp-control-plane 1/1 Running 0 24s
    kube-system kube-controller-manager-monapp-control-plane 1/1 Running 0 24s
    kube-system kube-proxy-kqhzt 1/1 Running 0 15s
    kube-system kube-scheduler-monapp-control-plane 1/1 Running 0 24s
    local-path-storage local-path-provisioner-75f7fc7dc5-drgb7 1/1 Running 0 15s

    Kubernetes tourne déjà avec ses propres composants, avant que vous n'ayez rien déployé. Tous doivent être en Running. Le suffixe aléatoire des noms sera différent chez vous.

Cette liste de neuf Pods est le Kubernetes standard, sans ajout : la base de données etcd, les trois composants du control plane, le réseau (kindnet et kube-proxy), la résolution de noms (coredns) et le fournisseur de stockage local. Vous ne trouverez ici ni Ingress Controller, ni répartiteur de charge préinstallés, contrairement à ce que livrent certaines distributions.

Trois gestes couvrent tout ce que vous ferez d'un cluster d'apprentissage : le retrouver, l'arrêter pour récupérer de la mémoire, le détruire quand il ne sert plus. Seul le dernier est irréversible.

kind ne connaît que ses propres clusters : un cluster créé avec un autre outil n'apparaîtra pas ici, et inversement.

Fenêtre de terminal
kind get clusters
Résultat
monapp

kind n'a pas de sous-commande stop, et beaucoup en concluent qu'il faut détruire le cluster pour libérer la mémoire. C'est inexact. Les nœuds étant des conteneurs Docker, docker stop les arrête et docker start les relance, sans rien perdre : vos Deployments, vos ConfigMaps et vos volumes sont toujours là au redémarrage.

Arrêter tous les nœuds du cluster
docker stop $(docker ps -q --filter "name=monapp-")
Les relancer
docker start $(docker ps -aq --filter "name=monapp-")

Comptez une dizaine de secondes pour que les nœuds repassent en Ready. Le geste vaut aussi pour un cluster multi-nœuds : sur un cluster à quatre nœuds portant trois réplicas, tous les nœuds sont revenus Ready en 9 secondes et les trois Pods ont été retrouvés sur leurs nœuds d'origine.

Contrôler le retour à la normale
kubectl get nodes

La suppression est définitive et sans confirmation. Tout ce qui vivait dans le cluster disparaît, volumes compris. Sur un cluster d'apprentissage c'est sans conséquence, mais prenez l'habitude de relire le nom avant de valider.

Fenêtre de terminal
kind delete cluster --name monapp
Résultat
Deleting cluster "monapp" ...
Deleted nodes: ["monapp-control-plane"]

L'opération arrête les conteneurs, les supprime, et retire le contexte de votre fichier kubectl.

Un cluster à un seul nœud suffit pour déployer une application, mais il masque tout ce qui relève de la répartition : le scheduler n'a aucun choix à faire, les contraintes de placement n'ont pas d'effet visible, et une panne de nœud ne peut pas être simulée. Ajouter des workers coûte peu, chaque nœud n'étant qu'un conteneur de plus.

Au-delà d'un nœud, kind attend un fichier de configuration plutôt que des options. C'est une bonne nouvelle : le fichier se versionne, se partage et se rejoue à l'identique, là où une ligne de commande se perd.

kind-multi.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
labels:
topology.kubernetes.io/zone: zone-a
- role: worker
labels:
topology.kubernetes.io/zone: zone-b
- role: worker
labels:
topology.kubernetes.io/zone: zone-c

Les libellés de zone ne sont pas décoratifs. topology.kubernetes.io/zone est le libellé standard que les clusters cloud posent sur leurs nœuds pour indiquer leur zone de disponibilité. En le déclarant ici, vous obtenez sur votre poste un cluster qui se comporte comme un cluster réparti, et les contraintes de placement que vous écrirez auront un effet observable.

Créer le cluster multi-nœuds
kind create cluster --name demo --config kind-multi.yaml
Résultat
Creating cluster "demo" ...
✓ Ensuring node image (kindest/node:v1.37.0)
✓ Preparing nodes
✓ Writing configuration
✓ Starting control-plane
✓ Installing CNI
✓ Installing StorageClass
✓ Joining worker nodes
Set kubectl context to "kind-demo"

L'étape Joining worker nodes est la seule nouveauté par rapport au cluster à un nœud : c'est kubeadm qui enrôle chaque worker auprès du control plane, exactement comme sur une installation sur serveurs. Le cluster complet est prêt en une vingtaine de secondes.

Vérifier les nœuds et leurs zones
kubectl get nodes -L topology.kubernetes.io/zone
Résultat
NAME STATUS ROLES AGE VERSION ZONE
demo-control-plane Ready control-plane 45s v1.37.0
demo-worker Ready <none> 30s v1.37.0 zone-a
demo-worker2 Ready <none> 30s v1.37.0 zone-b
demo-worker3 Ready <none> 30s v1.37.0 zone-c

La colonne ROLES affiche <none> pour les workers : c'est normal et non un défaut. Kubernetes ne pose pas de libellé de rôle sur un nœud de travail, seul le control plane en porte un.

Ce cluster à quatre nœuds coûte environ 1,7 Go de mémoire, soit à peine plus qu'un cluster à un nœud, les workers étant bien plus légers que le control plane. En échange, il rend visibles des comportements qu'un nœud unique rend indémontrables.

Ce que vous pouvez enfin observerCe qui devient possible
Répartition du schedulerSix réplicas se répartissent en 2, 2 et 2 sur les trois workers
Contraintes de placementtopologySpreadConstraints et l'affinité de nœud ont un effet mesurable
Mise en maintenancekubectl drain vide un nœud, les Pods repartent sur les autres
Panne de nœuddocker stop sur un worker le fait passer NotReady en une minute
Stockage localUn PersistentVolumeClaim se lie sur un nœud et y retient ses Pods

Le dernier point est un enseignement à lui seul. La classe de stockage livrée par kind est locale au nœud : une fois le volume créé sur un worker, tout Pod qui réclame ce volume est replanifié sur ce même worker. C'est le comportement réel du stockage local, et il explique pourquoi la production lui préfère un stockage réseau.

kubectl ne parle qu'à un seul cluster à la fois, celui désigné par le contexte courant. Créer un cluster bascule ce contexte automatiquement, d'où l'erreur classique du déploiement envoyé au mauvais endroit. Deux commandes suffisent à reprendre la main.

Lister les contextes connus
kubectl config get-contexts
Basculer sur un cluster précis
kubectl config use-context kind-monapp
Résultat
Switched to context "kind-monapp".

Ce que vous n'avez pas besoin de comprendre tout de suite

Section intitulée « Ce que vous n'avez pas besoin de comprendre tout de suite »

Vous venez de voir passer des noms de composants dans kubectl get pods -A, et il serait contre-productif de tout élucider maintenant. Chacun fait l'objet d'une leçon plus loin dans cette formation. Pour l'instant, un cluster qui répond à kubectl vous suffit.

Composant aperçuPourquoi l'ignorer aujourd'hui
etcdLa base de données interne du cluster, gérée pour vous
kindnetLe réseau des Pods, préinstallé et fonctionnel
local-path-provisionerLe stockage local, déjà branché comme classe par défaut
kube-schedulerLe composant qui place les Pods, sans réglage nécessaire
kube-proxyLa mécanique qui rend les Services joignables

Les trois pannes ci-dessous couvrent la quasi-totalité des blocages à ce stade, et aucune ne vient de Kubernetes lui-même. Gardez le réflexe de la section précédente : sur un cluster d'apprentissage, détruire et recréer coûte vingt secondes et règle la majorité des cas.

Les trois causes ci-dessous se situent toutes en dehors de Kubernetes : le démon Docker, les ports de l'hôte, la mémoire disponible. Avant de chercher du côté du cluster, exécutez docker ps : si cette commande échoue, aucune étape de ce guide ne peut aboutir.

SymptômeCause probableSolution
Cannot connect to the Docker daemonDocker n'est pas démarréDémarrez le service Docker ou Docker Desktop
port is already allocatedLe port d'API est occupéFixez un autre port avec networking.apiServerPort dans le fichier de configuration
Insufficient memoryMémoire insuffisanteFermez des applications ou réduisez le nombre de nœuds

Le fichier ~/.kube/config peut avoir été écrasé, par exemple par un outil cloud qui le régénère. Commencez par lister les contextes : si le vôtre a disparu, kubectl ne sait plus où se connecter, même si les conteneurs tournent toujours.

Vérifier les contextes disponibles
kubectl config get-contexts

Si le contexte manque, le plus simple est de recréer le cluster :

Repartir proprement
kind delete cluster --name monapp
kind create cluster --name monapp --image kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5

Un Pod en Pending n'a pas encore été placé sur un nœud : le problème est en amont du conteneur, et kubectl logs ne renverra donc rien d'utile. Les événements sont la bonne source, ils disent explicitement pourquoi le scheduler n'a trouvé aucun nœud acceptable.

Lire les événements récents
kubectl get events -A --sort-by='.lastTimestamp' | tail -20

La cause la plus fréquente sur un poste de travail est le manque de ressources. Sur cette formation, une seconde cause revient souvent : un Service de type LoadBalancer qui reste en attente d'une adresse que kind ne distribue pas.

Un détail de syntaxe mérite d'être retenu : kind attend le nom du cluster dans l'option --name, jamais en argument positionnel. L'oublier fait agir la commande sur le cluster par défaut, appelé kind, et non sur le vôtre.

ActionCommande
Créerkind create cluster --name monapp --image kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5
Créer en multi-nœudskind create cluster --name demo --config kind-multi.yaml
Listerkind get clusters
Arrêterdocker stop $(docker ps -q --filter "name=monapp-")
Redémarrerdocker start $(docker ps -aq --filter "name=monapp-")
Supprimerkind delete cluster --name monapp
  1. Cette formation utilise kind, seul outil local qui livre Kubernetes 1.37 en version vanilla, celle qu'évaluent les certifications.
  2. Précisez toujours --image kindest/node:v1.37.0 : sans cela vous héritez de la version figée dans votre binaire.
  3. Un cluster kind se jette : supprimer et recréer coûte une vingtaine de secondes et résout la majorité des blocages.
  4. kind n'a pas de commande d'arrêt, mais un cluster s'arrête quand même avec docker stop, et redémarre sans rien perdre.
  5. Le multi-nœuds passe par un fichier de configuration, qui se versionne et se rejoue, et coûte environ 1,7 Go pour quatre nœuds.
  6. Les libellés topology.kubernetes.io/zone rendent observables les contraintes de placement sur un simple poste de travail.
  7. kind ne fournit pas de répartiteur de charge : un Service LoadBalancer y reste en Pending, et c'est le comportement normal d'un Kubernetes nu.

Sept questions sur ce qui coûte du temps quand on démarre : l'image de nœud qu'on oublie de préciser, le contexte qui a basculé sans prévenir, et ce qui relève du comportement normal de kind plutôt que d'une panne.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

7 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • Contrôle des connaissances : Vérifier que les fondamentaux sont acquis avant d'attaquer les ressources Kubernetes.
  • Architecture de Kubernetes : Ce que contiennent réellement les conteneurs que kind vient de démarrer.
  • Les Pods : La première ressource à créer sur le cluster que vous venez d'obtenir.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn