Construire un cluster Kubernetes avec Kubeadm

Kubernetes s’est imposé comme le standard de facto pour l’orchestration de conteneurs en production. Que vous prépariez un environnement de développement, un lab pour la certification CKA, ou un cluster de préproduction, comprendre comment bootstrapper un cluster from scratch avec kubeadm reste une compétence fondamentale pour tout ingénieur DevOps ou SRE.

kubeadm est l’outil officiel du projet Kubernetes pour initialiser un cluster conforme aux bonnes pratiques de production. Il automatise la mise en place du control plane (API Server, etcd, Scheduler, Controller Manager) et simplifie la jonction des nœuds worker — sans pour autant masquer la mécanique interne, contrairement à des distributions managées comme EKS ou GKE.

Ce guide couvre l’installation complète d’un cluster Kubernetes 1.33 sur Ubuntu, avec containerd comme runtime et Calico comme plugin réseau (CNI). Les commandes ont été vérifiées et tiennent compte des ruptures de compatibilité introduites depuis la version 1.27 : nouveau dépôt APT, gestion des clés GPG, et activation obligatoire du driver cgroup systemd.

  1. Installation des paquets

1.1 Préparer le kernel

Charger les modules noyau nécessaires à Kubernetes :

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

Configurer les paramètres réseau système :

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

sudo sysctl --system

1.2 Installer et configurer containerd

sudo apt-get update && sudo apt-get install -y containerd.io

# Générer la configuration par défaut
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml

:warning: Étape critique pour Kubernetes 1.22+ : activer le driver cgroup systemd dans containerd. Sans cela, kubelet ne démarrera pas correctement.

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

sudo systemctl restart containerd
sudo systemctl enable containerd
sudo systemctl status containerd

1.3 Désactiver le swap

Kubernetes requiert que le swap soit désactivé :

sudo swapoff -a
# Rendre la désactivation permanente après reboot
sudo sed -i '/\sswap\s/d' /etc/fstab

1.4 Installer kubeadm, kubelet et kubectl

:warning: Important : L’ancien dépôt apt.kubernetes.io (kubernetes-xenial) est supprimé. Utilisez exclusivement pkgs.k8s.io.

sudo apt-get update && sudo apt-get install -y apt-transport-https curl

# Ajouter la clé GPG officielle
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# Ajouter le dépôt Kubernetes v1.33
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
  https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Répéter les étapes 1.1 à 1.4 sur les nœuds worker.

  1. Initialiser le cluster (Control Plane uniquement)
sudo kubeadm init --pod-network-cidr=192.168.0.0/16

Une fois l’initialisation terminée, configurer l’accès kubectl :

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Vérifier l’état du nœud control plane :

kubectl get nodes

3. Installer le plugin réseau Calico (CNI)

Depuis le nœud control plane :

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

Attendre que le nœud passe en statut Ready :

kubectl get nodes -w

4. Joindre les nœuds worker au cluster

Sur le Control Plane : générer le token de jointure

kubeadm token create --print-join-command

Cette commande produit une sortie de la forme :

kubeadm join <IP_CONTROL_PLANE>:6443 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

Sur chaque nœud worker : exécuter la commande de jointure

sudo kubeadm join <IP_CONTROL_PLANE>:6443 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

Vérifier l’état du cluster (depuis le Control Plane)

kubectl get nodes

Résultat attendu :

NAME             STATUS   ROLES           AGE   VERSION
control-plane    Ready    control-plane   10m   v1.33.x
worker-node-1    Ready    <none>          3m    v1.33.x
worker-node-2    Ready    <none>          2m    v1.33.x