درس 2 — Le cluster et le chart

Le cluster kind et l'Ingress

7 دقائق قراءة

هذا المحتوى غير مترجم بعد. تُعرض النسخة الأصلية.

Le cluster kind et l'Ingress

Tester un chart sur un cluster partagé de préproduction, c'est attendre une fenêtre, risquer de casser le travail d'une autre équipe et ne jamais pouvoir tout jeter. Un cluster kind (Kubernetes in Docker) se crée en une minute, coûte zéro et se supprime sans trace. Il a des limites, qu'il faut connaître pour ne pas en tirer de fausses conclusions : pas de LoadBalancer, pas de vraie isolation entre nœuds, des images qui ne viennent pas d'un registre.

Le mécanisme

Chaque nœud kind est un conteneur Docker qui fait tourner un kubelet et containerd. Le trafic entre par un port de la machine hôte, mappé sur le port 80 du conteneur control-plane, où tourne le contrôleur Ingress NGINX.

flowchart LR
  H["Hôte : 127.0.0.1:8081"] -->|"extraPortMappings"| CP["Conteneur lab-k8s-ia-control-plane :80"]
  CP --> IC["Pod ingress-nginx-controller (hostPort 80)"]
  IC -->|"Ingress host=assistant.127.0.0.1.nip.io"| W1["Conteneur lab-k8s-ia-worker : pods API"]
  IC --> W2["Conteneur lab-k8s-ia-worker2 : pods API"]
  D["docker build"] -->|"kind load docker-image"| W1
  D --> W2
  MS["metrics-server"] -->|"CPU / mémoire des pods"| HPA["HPA"]

Trois points distinguent kind d'un cluster managé :

SujetkindGKE (projet suivant)
Entréeport de l'hôte + hostPort sur un nœud étiqueté ingress-readyService LoadBalancer ou Gateway avec IP publique
Imageskind load docker-image copie l'image dans chaque nœudtirées d'Artifact Registry
Métriques CPUmetrics-server à installer, avec --kubelet-insecure-tlsfournies
NetworkPolicyappliquées par kindnet depuis kind 0.24Dataplane V2 (Cilium)

La mise en œuvre

files/k8s/kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    labels:
      ingress-ready: "true"
    extraPortMappings:
      - { containerPort: 80, hostPort: 8081, listenAddress: "127.0.0.1", protocol: TCP }
  - role: worker
  - role: worker

listenAddress: "127.0.0.1" : sans lui, le port s'ouvre sur toutes les interfaces et votre service de test devient joignable depuis le réseau Wi-Fi du bureau. Deux nœuds de travail suffisent pour vérifier la répartition des pods et le comportement du PodDisruptionBudget lors d'un drain.

La cible make up enchaîne cluster, extensions, image, Secret et chart. Les extensions sont installées depuis des manifestes à version figée :

files/Makefile
INGRESS_NGINX := https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/kind/deploy.yaml
METRICS_SERVER := https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.9.0/components.yaml
K := kubectl --context $(CTX)

cluster:
	@kind get clusters | grep -qx $(CLUSTER) || kind create cluster --name $(CLUSTER) --config k8s/kind-config.yaml --wait 120s

addons:
	@$(K) apply -f $(INGRESS_NGINX) >/dev/null
	@$(K) apply -f $(METRICS_SERVER) >/dev/null
	@$(K) -n kube-system patch deploy metrics-server --type=json \
	  -p '[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]' >/dev/null 2>&1 || true
	@$(K) -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=180s

Toutes les commandes passent --context kind-lab-k8s-ia. Sur un poste qui a aussi un contexte de production dans ~/.kube/config, un kubectl apply sans contexte explicite part là où pointe le contexte courant, et le contexte courant change dès qu'un autre outil crée un cluster.

Le nom assistant.127.0.0.1.nip.io est résolu par un DNS public vers 127.0.0.1 : pas de modification de /etc/hosts. Évitez *.localtest.me sur une machine qui préfère IPv6 : il peut se résoudre en ::1, alors que le port kind n'écoute qu'en IPv4.

terminal
make cluster addons
kubectl --context kind-lab-k8s-ia get nodes
kubectl --context kind-lab-k8s-ia top nodes

Ce qui casse en production

SymptômeCauseParade
kind create cluster échoue : port is already allocatedle port 8081 est pris par un autre processuschanger hostPort et HTTP_PORT du Makefile
Pods en ErrImagePull pour lab-k8s-ia/inference:0.1.0image construite mais pas chargée dans les nœudsmake image (build + kind load) ; garder imagePullPolicy: IfNotPresent
kubectl top : Metrics API not available, HPA en <unknown>metrics-server absent ou refuse les certificats des kubelets kind--kubelet-insecure-tls, en lab uniquement
Une commande de lab modifie un cluster de productioncontexte kubectl courant mal positionné--context explicite partout, jamais de contexte implicite dans un Makefile
L'Ingress répond 404l'en-tête Host ne correspond pas à ingress.hostappeler l'URL avec le bon nom, ou curl -H 'Host: …'

La règle de décision

  • kind pour tout ce qui se vérifie sur un poste : chart, sondes, rollouts, NetworkPolicy, HPA. Ne mesurez pas la performance absolue sur kind : les nœuds partagent le même CPU.
  • Versions figées pour chaque manifeste externe, jamais main ni latest.
  • Ingress NGINX seulement là où il est déjà exploité ; Gateway API pour tout nouveau cluster.

Pratique

Un collègue lance make up sur son poste ; quelques secondes plus tard, son kubectl get pods affiche les pods de production de l'équipe paiement. Quelle est l'explication la plus probable ?

L'HPA affiche cpu: <unknown>/60% depuis 10 minutes. kubectl top pods renvoie « Metrics API not available ». Que corrigez-vous ?

Exercice

Ajoutez un troisième nœud de travail, recréez le cluster et vérifiez que l'Ingress fonctionne toujours. Combien de temps prend la recréation complète (make down up) sur votre machine ?

Voir la solution

Ajoutez - role: worker dans k8s/kind-config.yaml, puis :

terminal
time (make down && make up)
kubectl --context kind-lab-k8s-ia get nodes          # 4 nœuds Ready
curl -s http://assistant.127.0.0.1.nip.io:8081/health/live

L'Ingress continue de fonctionner parce que son pod est épinglé au nœud control-plane (étiquette ingress-ready), le seul à recevoir le port de l'hôte. Sur la machine de référence, make up complet a pris 1 min 40 s, images comprises.

Résultat obtenu

Exécution du 2026-10-15, après make up (1 min 40 s) :

$ kubectl --context kind-lab-k8s-ia get nodes
NAME                       STATUS   ROLES           AGE   VERSION
lab-k8s-ia-control-plane   Ready    control-plane   19m   v1.37.0
lab-k8s-ia-worker          Ready    <none>          19m   v1.37.0
lab-k8s-ia-worker2         Ready    <none>          19m   v1.37.0

$ kubectl --context kind-lab-k8s-ia -n ingress-nginx get pods -o wide
ingress-nginx-controller-596f5b6bcf-66dcl   Running   lab-k8s-ia-control-plane

$ kubectl --context kind-lab-k8s-ia top nodes        # pendant le test de charge de la leçon 5
NAME                       CPU(cores)   MEMORY(bytes)
lab-k8s-ia-control-plane   330m         1119Mi
lab-k8s-ia-worker          3590m        354Mi
lab-k8s-ia-worker2         1848m        406Mi

Je sais faire

  • Créer un cluster kind multi-nœuds avec un port d'entrée limité à 127.0.0.1
  • Installer Ingress NGINX et metrics-server à version figée
  • Charger une image locale dans les nœuds kind
  • Expliquer pourquoi un nouveau cluster de production part sur Gateway API
التالي