Un laboratoire Kubernetes local est l'endroit le plus rapide et le plus sûr pour explorer le comportement d'un cluster, tester des changements de configuration et s'exercer à la récupération d'incidents sans risquer d'affecter des environnements partagés. Ce guide montre comment mettre en place un petit laboratoire jetable, déployer des charges de travail simples, vérifier le tout avec des contrôles clairs et observables, dépanner les défaillances courantes et tout nettoyer proprement pour pouvoir recommencer le cycle.
La portée pratique est essentielle : commencez par un projet pilote étroit et mesurable que vous pouvez inspecter localement de bout en bout, puis élargissez une fois la base fiable. Cet article suit ce chemin : vous allez construire un cluster à deux nœuds, exposer un service sur un port connu, vérifier le trafic, modifier quelque chose de visible et faire un retour arrière. En cours de route, vous capturerez les détails de version et d'environnement pour que les répétitions soient prévisibles.
Inventaire des versions et de l'environnement
Avant de créer un cluster, faites un inventaire rapide. Cela évite les conjectures ultérieures et réduit le retravail lorsque vous répétez le laboratoire sur une nouvelle machine.
- Système hôte : Linux, macOS ou Windows (WSL2 recommandé sous Windows)
- CPU : 4 cœurs logiques minimum pour une expérience fluide
- RAM : 8 Go minimum ; 16 Go recommandés si vous prévoyez d'exécuter plusieurs services
- Disque : 20 Go libres (les images et les journaux s'accumulent)
- Virtualisation : requise pour les outils basés sur VM ; non nécessaire pour les clusters basés sur conteneurs
- Réseau : assurez-vous que les ports localhost que vous prévoyez d'utiliser (par exemple 8080, 8443) sont libres
Installez ces outils :
- kubectl (CLI client)
- Un outil Kubernetes local. Ce guide utilise kind (Kubernetes in containers) pour sa rapidité et sa facilité de démantèlement. Minikube est une alternative solide basée sur VM si vous préférez l'isolation par machine virtuelle.
Vérifiez votre chaîne d'outils après l'installation :
# Vérifier la version du client kubectl
kubectl version --client --output=yaml
# Si vous utilisez kind
kind version
# Si vous utilisez minikube
minikube version
Si une commande est manquante, corrigez le PATH ou terminez l'installation avant de continuer.
Choix d'une option de laboratoire local
Les chiffres du tableau sont des valeurs d'exemple construites pour vous aider à raisonner sur les compromis sur un portable de développeur typique.
| Option | Runtime | Isolation | RAM typique Go | Temps de démarrage s | Idéal pour | Source |
|---|---|---|---|---|---|---|
| kind | Conteneurs | Processus | 2-4 | 20-60 | Clusters rapides, jetables | Exemple construit |
| minikube | VM ou cont. | VM/proc | 3-6 | 30-120 | Isolation VM, pilotes optionnels | Exemple construit |
| k3d | Conteneurs | Processus | 2-4 | 15-45 | Léger, configurations multi-clusters | Exemple construit |
Choisissez-en un, notez la version et continuez à l'utiliser de manière cohérente pour le reste de ce guide.
Chemin de configuration sûr
Pour garder le laboratoire simple et débogable, utilisez kind avec des mappages de ports explicites et un espace de noms dédié. Nous allons :
- Créer un cluster à deux nœuds (1 control-plane, 1 worker)
- Pré-mapper le NodePort 30080 sur localhost:8080 et le NodePort 30443 sur localhost:8443
- Travailler dans un seul espace de noms : lab
Pourquoi mapper les NodePorts ? Cela évite les pièces mobiles supplémentaires d'un contrôleur Ingress tout en testant l'exposition du service depuis votre hôte.
1) Créer le cluster Kind
Créez un fichier nommé kind-lab.yaml avec ce contenu :
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: lab
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 30080
hostPort: 8080
protocol: TCP
- containerPort: 30443
hostPort: 8443
protocol: TCP
- role: worker
Créez le cluster :
kind create cluster --config kind-lab.yaml
kubectl cluster-info
kubectl get nodes -o wide
Vous devriez voir le statut Ready sur les deux nœuds. Sinon, consultez Modes de défaillance et récupération ci-dessous.
Créez et utilisez l'espace de noms pour l'isolation :
kubectl create namespace lab
kubectl config set-context --current --namespace=lab
Exemples pratiques
Vous allez déployer un serveur web NGINX devant un Service NodePort. Ensuite, vous personnaliserez le contenu avec un ConfigMap et effectuerez une mise à jour progressive.
Exemple 1 : Déploiement NGINX + Service NodePort
Créez un fichier nommé web.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: NodePort
selector:
app: web
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
Appliquez et vérifiez :
kubectl apply -f web.yaml
kubectl rollout status deployment/web
kubectl get svc web -o wide
Testez depuis l'hôte en utilisant le port mappé :
curl -sSf http://localhost:8080/ | head -n 5
Résultat attendu : contenu HTML par défaut de NGINX et HTTP 200.
Augmentez l'échelle pour observer un effet progressif :
kubectl scale deploy/web --replicas=3
kubectl get pods -l app=web -w
Exemple 2 : Personnaliser le contenu avec un ConfigMap et mise à jour progressive
Créez un ConfigMap avec un fichier index.html et montez-le dans NGINX.
Créez un fichier nommé web-custom.yaml :
apiVersion: v1
kind: ConfigMap
metadata:
name: web-content
labels:
app: web
data:
index.html: |
<!doctype html>
<html>
<head><title>Lab Web</title></head>
<body>
<h1>Exemple construit : Kubernetes lab web</h1>
<p>Servi par NGINX depuis un ConfigMap.</p>
</body>
</html>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
volumeMounts:
- name: web-root
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
readinessProbe:
httpGet:
path: /
port: 80
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
volumes:
- name: web-root
configMap:
name: web-content
items:
- key: index.html
path: index.html
Appliquez et observez le déploiement :
kubectl apply -f web-custom.yaml
kubectl rollout status deployment/web
Vérifiez le changement de contenu :
curl -sSf http://localhost:8080/ | grep -F "Exemple construit : Kubernetes lab web"
Revenez au ReplicaSet précédent si nécessaire :
kubectl rollout undo deployment/web
Vérification et diagnostics
Des vérifications systématiques aident à détecter les problèmes tôt.
Santé du cluster
# Nœuds Ready
kubectl get nodes
# Composants principaux dans kube-system
kubectl get pods -n kube-system -o wide
# Événements si quelque chose est Pending ou CrashLoopBackOff
kubectl get events --sort-by=.lastTimestamp | tail -n 20
Résultat attendu : tous les nœuds affichent Ready ; les pods kube-proxy, CoreDNS sont Running ; pas de boucles de crash répétées dans les événements.
Charge de travail et réseau
# Pods et Services dans l'espace de noms lab
kubectl get deploy,rs,po,svc -n lab -o wide
# Décrire un pod pour vérifier readiness/liveness et les tirages d'image
kubectl describe pod -n lab -l app=web | sed -n '1,80p'
# Tester le mappage NodePort depuis l'hôte
curl -I http://localhost:8080/
Résultat attendu : HTTP/1.1 200 OK et Server: nginx dans les en-têtes.
Journaux et détails du déploiement
# Journaux d'un pod (choisissez-en un depuis kubectl get pods)
POD="$(kubectl get pods -n lab -l app=web -o jsonpath='{.items[0].metadata.name}')"
kubectl logs -n lab "$POD" --tail=50
# Historique et statut du déploiement
kubectl rollout history deployment/web
kubectl rollout status deployment/web
Modes de défaillance et récupération
Utilisez cette matrice rapide pour trier les problèmes courants.
| Symptôme | Cause probable | Commande pour vérifier | Remédiation | Source |
|---|---|---|---|---|
| Nœuds NotReady | Runtime de conteneur non démarré | docker ps OU podman ps | Démarrer le runtime ; recréer le cluster si nécessaire | Exemple construit |
| Pods Pending | Ressources insuffisantes | kubectl describe pod -n lab <pod> | Réduire les répliques ; libérer RAM/CPU ; reprogrammer | Exemple construit |
| CrashLoopBackOff dans CoreDNS | Problème CNI ou config DNS | kubectl logs -n kube-system <coredns-pod> | Recréer le cluster ; assurer le CNI par défaut actif | Exemple construit |
| Service inaccessible sur 8080 | Conflit de port ou NodePort | ss -lntp | grep 8080; kubectl get svc web -o yaml | Libérer le port hôte ; assurer nodePort 30080 | Exemple construit |
| ImagePullBackOff | Réseau ou nom d'image | kubectl describe pod -n lab <pod> | Corriger le nom d'image ; confirmer l'accès internet de l'hôte | Exemple construit |
| Déploiement bloqué | Mauvaises sondes readiness | kubectl describe deploy/web | Corriger les sondes ; kubectl rollout undo | Exemple construit |
Retour arrière rapide et réinitialisation complète
Si vous n'avez besoin que de revenir au dernier changement :
# Annuler le dernier déploiement du déploiement web
kubectl rollout undo deployment/web -n lab
# Ou revenir au contenu en supprimant le ConfigMap pour que les pods utilisent les défauts intégrés
kubectl delete configmap web-content -n lab
kubectl rollout restart deployment/web -n lab
Si le cluster est dans un mauvais état, supprimez-le et recréez-le. C'est un laboratoire ; les reconstructions sont peu coûteuses.
# Démanteler le cluster
kind delete cluster --name lab
# Optionnel : libérer de l'espace disque en élaguant les images (à utiliser avec précaution)
docker system prune -f
# ou, si vous utilisez podman
podman system prune -f
# Recréer proprement
kind create cluster --config kind-lab.yaml
kubectl get nodes
Après une recréation, réappliquez vos manifestes :
kubectl create namespace lab
kubectl config set-context --current --namespace=lab
kubectl apply -f web.yaml
# ou appliquer la version personnalisée
yaml_to_apply=web.yaml
[ -f web-custom.yaml ] && yaml_to_apply=web-custom.yaml
kubectl apply -f "$yaml_to_apply"
Liste de contrôle des opérations
Utilisez ceci comme un manuel d'exécution reproductible.
- Enregistrer l'environnement : OS, CPU, RAM, disque, runtime, versions kubectl et kind
- S'assurer que les ports hôtes 8080 (HTTP) et 8443 (HTTPS) sont libres
- Créer le cluster : kind create cluster --config kind-lab.yaml
- Vérifier les nœuds Ready : kubectl get nodes ; vérifier les pods kube-system
- Créer l'espace de noms : kubectl create namespace lab ; définir le contexte courant
- Déployer la charge de travail : kubectl apply -f web.yaml
- Vérifier le déploiement : kubectl rollout status deployment/web
- Tester le service : curl http://localhost:8080/
- Faire un changement sûr : appliquer web-custom.yaml ; valider le contenu ; observer le déploiement
- Si quelque chose casse : kubectl describe, logs, events ; kubectl rollout undo
- Capturer les notes : versions, manifestes, sorties observées et correctifs
- Démanteler quand terminé : kind delete cluster --name lab
Notes sur l'extension du laboratoire en toute sécurité
Une fois la base solide et rapide à reconstruire, vous pouvez l'étendre par petits incréments :
- Ajouter HTTPS : mapper le NodePort 30443 sur localhost:8443 et placer une application avec terminaison TLS dans votre application ou via un proxy léger
- Ajouter Ingress : installer un contrôleur Ingress et basculer les Services en ClusterIP ; vérifier le mappage DNS via le fichier hosts si nécessaire
- Ajouter du stockage : introduire un provisionneur de stockage local simple et tester un StatefulSet utilisant un petit PersistentVolumeClaim
- Ajouter de l'observabilité : installer metrics-server pour kubectl top et une petite pile Prometheus ; confirmer les cibles et les données collectées
Ajoutez un composant à la fois, vérifiez et documentez les signaux attendus avant de passer au suivant.
Conclusion
Vous disposez maintenant d'un laboratoire Kubernetes pratique et jetable que vous pouvez créer, vérifier, casser intentionnellement et reconstruire en quelques minutes. En limitant la portée de la configuration, en mappant un NodePort connu sur localhost et en vous concentrant sur des exemples observables, vous réduisez le temps avant d'obtenir un signal et facilitez la pratique de véritables tâches d'exploitation : déploiements, retours arrière, mise à l'échelle et diagnostics. Le cluster kind à deux nœuds avec ports pré-mappés vous donne une topologie réaliste control-plane-plus-worker sans la surcharge d'une pile VM complète. Chaque exemple de ce guide produit un résultat visible que vous pouvez interroger avec curl depuis votre hôte, donc vous savez toujours si un changement a réussi ou échoué. Conservez vos manifestes dans le contrôle de version, étiquetez les bases de référence connues comme bonnes et répétez les scénarios de défaillance courants jusqu'à ce que la récupération devienne une routine. Un laboratoire local fiable transforme l'expérimentation en une habitude sûre et reproductible qui renforce la confiance en production.