Kubernetes est devenu le standard de l’industrie pour l’orchestration de conteneurs, alimentant aussi bien les petites startups que les plus grandes plateformes natives du cloud de la planete. Si vous gerez des conteneurs avec Docker ou Docker Compose et que vous avez atteint le point ou vous avez besoin de mise a l’echelle automatique, d’auto-reparation, de mises a jour progressives et de deploiements multi-noeuds, Kubernetes est l’etape suivante. Ce guide vous emmene de zero a un cluster Kubernetes fonctionnel en utilisant kubeadm sur Ubuntu Server, couvrant l’architecture, l’installation, le premier deploiement, l’exposition des services et les commandes de gestion quotidienne.
Prerequis
Avant de commencer, assurez-vous d’avoir :
- Deux machines ou plus executant Ubuntu Server 22.04 ou 24.04 (physiques ou virtuelles)
- Chaque machine avec au moins 2 Go de RAM et 2 CPUs
- Connectivite reseau complete entre toutes les machines (reseau prive recommande)
- Hostname, adresse MAC et product_uuid uniques sur chaque noeud
- Acces terminal avec privileges sudo sur tous les noeuds
- Swap desactive sur tous les noeuds
Qu’est-ce que Kubernetes ?
Kubernetes (souvent abrege en k8s) est une plateforme d’orchestration de conteneurs open source, originalement concue par Google et maintenant maintenue par la Cloud Native Computing Foundation (CNCF). Elle automatise le deploiement, la mise a l’echelle et la gestion des applications conteneurisees.
A la base, Kubernetes resout un probleme fondamental : lorsque vous avez des dizaines ou des centaines de conteneurs s’executant sur plusieurs serveurs, vous avez besoin d’un systeme pour decider ou chaque conteneur s’execute, redemarrer les conteneurs qui echouent, les mettre a l’echelle a la hausse ou a la baisse selon la demande, et gerer le reseau entre eux. Kubernetes fait tout cela de maniere declarative — vous decrivez l’etat souhaite de votre application, et Kubernetes travaille continuellement pour que l’etat reel corresponde.
Concepts cles :
- Pod — la plus petite unite deployable, enveloppant un ou plusieurs conteneurs
- Service — un point d’acces reseau stable qui achemine le trafic vers un ensemble de Pods
- Deployment — une maniere declarative de gerer les Pods avec des replicas et des mises a jour progressives
- Namespace — une partition logique pour isoler les ressources au sein d’un cluster
- Node — une machine physique ou virtuelle dans le cluster
Architecture de Kubernetes
Un cluster Kubernetes se compose de deux types de noeuds :
Plan de Controle (Noeud Maitre)
Le plan de controle gere l’etat global du cluster et prend les decisions d’ordonnancement. Ses composants comprennent :
- kube-apiserver — la porte d’entree du cluster ; toute communication passe par le serveur API
- etcd — un magasin distribue cle-valeur qui contient toute la configuration et l’etat du cluster
- kube-scheduler — assigne les Pods aux noeuds en fonction des exigences et contraintes de ressources
- kube-controller-manager — execute les controleurs qui gerent les taches routinieres comme le maintien du nombre correct de replicas de Pods
- cloud-controller-manager — s’integre avec les APIs des fournisseurs cloud (optionnel, pour les deploiements cloud)
Noeuds Worker
Les noeuds worker executent vos conteneurs d’application. Chaque worker execute :
- kubelet — l’agent qui communique avec le plan de controle et gere les Pods sur le noeud
- kube-proxy — gere les regles reseau pour que les Pods puissent communiquer entre eux et avec le trafic externe
- Runtime de conteneurs — le logiciel qui execute reellement les conteneurs (containerd est le standard)
┌─────────────────────────────────────────┐
│ Noeud du Plan de Controle │
│ ┌───────────┐ ┌──────────────────┐ │
│ │ API Server│ │ Controller Mgr │ │
│ └───────────┘ └──────────────────┘ │
│ ┌───────────┐ ┌──────────────────┐ │
│ │ etcd │ │ Scheduler │ │
│ └───────────┘ └──────────────────┘ │
└─────────────────────────────────────────┘
│ │
┌────┴────┐ ┌───┴─────┐
│ Worker 1│ │ Worker 2│
│ kubelet │ │ kubelet │
│ kube- │ │ kube- │
│ proxy │ │ proxy │
│ runtime │ │ runtime │
└─────────┘ └─────────┘
Preparation de Tous les Noeuds
Les etapes suivantes doivent etre effectuees sur chaque noeud du cluster (plan de controle et workers).
Desactiver le Swap
Kubernetes exige que le swap soit desactive. Le kubelet ne demarrera pas si le swap est actif :
# Desactiver le swap immediatement
sudo swapoff -a
# Supprimer les entrees swap du fstab pour persister entre les redemarrages
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# Verifier que le swap est desactive
free -h
Charger les Modules du Noyau Requis
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
Configurer les Parametres sysctl
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# Appliquer sans redemarrer
sudo sysctl --system
Verifiez que les parametres sont appliques :
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
Les trois valeurs doivent retourner 1.
Installation du Runtime de Conteneurs (containerd)
Kubernetes a besoin d’un runtime de conteneurs qui implemente l’Interface de Runtime de Conteneurs (CRI). containerd est le standard de l’industrie et le choix recommande :
# Installer containerd
sudo apt update
sudo apt install -y containerd
# Generer la configuration par defaut
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# Activer SystemdCgroup (requis pour kubeadm)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# Redemarrer et activer containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
Verifiez que containerd est en cours d’execution :
sudo systemctl status containerd
La sortie doit afficher active (running).
Installation de kubeadm, kubelet et kubectl
Ces trois outils sont la base d’un cluster base sur kubeadm :
- kubeadm — amorce le cluster
- kubelet — s’execute sur chaque noeud et gere les Pods
- kubectl — l’outil en ligne de commande pour interagir avec le cluster
# Installer les paquets requis
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg
# Ajouter la cle de signature du depot APT de Kubernetes
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# Ajouter le depot APT de Kubernetes
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# Installer les paquets
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
# Empecher les mises a jour automatiques (critique pour la stabilite du cluster)
sudo apt-mark hold kubelet kubeadm kubectl
Verifiez l’installation :
kubeadm version
kubectl version --client
Initialisation du Plan de Controle
Executez la commande suivante uniquement sur le noeud du plan de controle :
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Le flag --pod-network-cidr specifie la plage d’IPs pour les Pods. La valeur 10.244.0.0/16 est celle par defaut pour Flannel. Si vous prevoyez d’utiliser Calico, utilisez 192.168.0.0/16 a la place.
Apres la fin de l’initialisation, vous verrez une sortie similaire a :
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:abc123...
Sauvegardez la commande kubeadm join — vous en aurez besoin pour ajouter des noeuds worker.
Configurez kubectl pour votre utilisateur :
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Verifiez que le plan de controle est en cours d’execution :
kubectl get nodes
La sortie montrera le noeud du plan de controle avec le statut NotReady — c’est attendu tant que vous n’avez pas installe un plugin reseau pour les Pods.
Installation d’un Plugin Reseau pour les Pods
Les Pods ont besoin d’un plugin reseau (CNI — Container Network Interface) pour communiquer entre eux a travers les noeuds. Sans lui, le cluster n’est pas fonctionnel.
Option A : Installer Flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Option B : Installer Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
Attendez que tous les Pods systeme soient prets :
kubectl get pods -n kube-system
Apres une ou deux minutes, tous les Pods doivent afficher le statut Running. Verifiez maintenant le statut du noeud a nouveau :
kubectl get nodes
Le noeud du plan de controle doit maintenant afficher Ready.
Joindre les Noeuds Worker
Sur chaque noeud worker, executez la commande kubeadm join que vous avez sauvegardee lors de l’initialisation du plan de controle :
sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:abc123...
Si vous avez perdu la commande de jointure, vous pouvez la regenerer sur le plan de controle :
kubeadm token create --print-join-command
Apres la jointure, verifiez tous les noeuds depuis le plan de controle :
kubectl get nodes
Sortie attendue :
NAME STATUS ROLES AGE VERSION
control-plane Ready control-plane 10m v1.31.0
worker-01 Ready <none> 2m v1.31.0
worker-02 Ready <none> 1m v1.31.0
Pour etiqueter vos noeuds worker pour une meilleure identification :
kubectl label node worker-01 node-role.kubernetes.io/worker=worker
kubectl label node worker-02 node-role.kubernetes.io/worker=worker
Deployer Votre Premiere Application
Maintenant que le cluster fonctionne, deployons un serveur web nginx simple.
Creer un Deployment
kubectl create deployment nginx --image=nginx:latest --replicas=3
Cela dit a Kubernetes : “Je veux 3 instances de nginx en cours d’execution en permanence.” Kubernetes planifiera les Pods sur vos noeuds worker.
Verifiez le deployment :
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 30s
Voir les Pods individuels :
kubectl get pods -o wide
Le flag -o wide montre sur quel noeud chaque Pod s’execute.
Utiliser un Manifeste YAML
Pour les charges de travail en production, vous devez definir les ressources dans des fichiers YAML. Creez un fichier appele nginx-deployment.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Appliquez-le :
kubectl apply -f nginx-deployment.yaml
Exposition des Services
Les Pods sont ephemeres et obtiennent de nouvelles adresses IP lorsqu’ils redemarrent. Les Services fournissent un point d’acces stable pour atteindre votre application.
ClusterIP (Interne Uniquement)
Le type de Service par defaut. Accessible uniquement depuis l’interieur du cluster :
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=ClusterIP
kubectl get services
NodePort (Acces Externe via IP du Noeud)
Expose le Service sur un port statique sur l’IP de chaque noeud :
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=NodePort --name=nginx-nodeport
kubectl get services nginx-nodeport
Vous pouvez maintenant acceder a l’application a http://<ip-de-nimporte-quel-noeud>:31234.
LoadBalancer (Environnements Cloud)
Dans les environnements cloud (AWS, GCP, Azure), le type LoadBalancer provisionne automatiquement un equilibreur de charge externe :
kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=LoadBalancer --name=nginx-lb
Pour les clusters bare-metal, vous pouvez utiliser MetalLB pour fournir la fonctionnalite LoadBalancer.
Manifeste YAML de Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
type: NodePort
Mise a l’Echelle et Mises a Jour Progressives
Mettre a l’Echelle les Replicas
# Augmenter a 5 replicas
kubectl scale deployment nginx-deployment --replicas=5
# Reduire a 2 replicas
kubectl scale deployment nginx-deployment --replicas=2
# Verifier
kubectl get deployment nginx-deployment
Mises a Jour Progressives
Mettez a jour l’image du conteneur sans temps d’arret :
# Mettre a jour l'image
kubectl set image deployment/nginx-deployment nginx=nginx:1.27-alpine
# Suivre la progression du deploiement
kubectl rollout status deployment/nginx-deployment
Kubernetes remplacera progressivement les anciens Pods par de nouveaux, garantissant que l’application reste disponible tout au long de la mise a jour.
Retour en Arriere
Si quelque chose tourne mal :
# Voir l'historique des deploiements
kubectl rollout history deployment/nginx-deployment
# Revenir a la version precedente
kubectl rollout undo deployment/nginx-deployment
# Revenir a une revision specifique
kubectl rollout undo deployment/nginx-deployment --to-revision=2
Inspection et Debogage des Charges de Travail
Voir les Logs des Pods
# Logs d'un Pod specifique
kubectl logs nginx-deployment-abc123
# Suivre les logs en temps reel
kubectl logs -f nginx-deployment-abc123
# Logs de tous les Pods d'un Deployment
kubectl logs -l app=nginx
Executer des Commandes dans un Pod
# Ouvrir un shell dans un Pod en cours d'execution
kubectl exec -it nginx-deployment-abc123 -- /bin/bash
# Executer une seule commande
kubectl exec nginx-deployment-abc123 -- cat /etc/nginx/nginx.conf
Decrire les Ressources
# Informations detaillees sur un Pod
kubectl describe pod nginx-deployment-abc123
# Informations detaillees sur un noeud
kubectl describe node worker-01
Depannage
Pods Bloques en Etat Pending
Cela signifie generalement que le scheduler ne peut pas trouver un noeud avec suffisamment de ressources :
kubectl describe pod <nom-du-pod>
Regardez la section Events en bas. Causes courantes :
- CPU ou memoire insuffisante sur les noeuds worker
- Taints de noeud empechant la planification
- Regles d’affinite de Pod qui ne peuvent pas etre satisfaites
Pods en CrashLoopBackOff
Le conteneur demarre mais s’arrete immediatement :
# Verifier les logs
kubectl logs <nom-du-pod>
kubectl logs <nom-du-pod> --previous
# Verifier les evenements
kubectl describe pod <nom-du-pod>
Causes courantes :
- Erreur d’application ou mauvaise configuration
- Variables d’environnement ou config maps manquantes
- Probes de readiness ou liveness echouant
Noeuds Affichent NotReady
# Verifier les conditions du noeud
kubectl describe node <nom-du-noeud>
# Sur le noeud affecte, verifier les logs du kubelet
sudo journalctl -u kubelet -f
Causes courantes :
- Plugin CNI non installe ou en echec
- kubelet ne peut pas atteindre le serveur API
- Pression de disque, pression de memoire ou pression de PID
Impossible d’Atteindre les Services
# Verifier les endpoints du Service
kubectl get endpoints <nom-du-service>
# Tester la connectivite depuis l'interieur du cluster
kubectl run debug --image=busybox --rm -it -- wget -qO- http://<nom-du-service>
Regenerer les Tokens de Jointure
Si le token de jointure a expire (les tokens sont valides pendant 24 heures par defaut) :
kubeadm token create --print-join-command
Reference des Commandes kubectl
| Commande | Description |
|---|---|
kubectl get nodes | Lister tous les noeuds du cluster |
kubectl get pods | Lister les Pods dans le namespace actuel |
kubectl get pods -A | Lister les Pods dans tous les namespaces |
kubectl get services | Lister tous les Services |
kubectl get deployments | Lister tous les Deployments |
kubectl describe pod <nom> | Afficher les informations detaillees du Pod |
kubectl logs <pod> | Voir les logs du Pod |
kubectl exec -it <pod> -- /bin/bash | Ouvrir un shell dans un Pod |
kubectl apply -f <fichier> | Appliquer un manifeste YAML |
kubectl delete -f <fichier> | Supprimer des ressources d’un manifeste YAML |
kubectl scale deployment <nom> --replicas=N | Mettre a l’echelle un Deployment |
kubectl rollout status deployment/<nom> | Verifier la progression du deploiement |
kubectl rollout undo deployment/<nom> | Revenir en arriere sur un Deployment |
kubectl top nodes | Afficher l’utilisation des ressources des noeuds |
kubectl top pods | Afficher l’utilisation des ressources des Pods |
kubectl config get-contexts | Lister les contextes de cluster disponibles |
kubectl cluster-info | Afficher les informations du point d’acces du cluster |
Resume
Vous disposez maintenant d’un cluster Kubernetes fonctionnel deploye avec kubeadm, complet avec un plan de controle, des noeuds worker, un plugin reseau CNI et votre premiere application en cours d’execution avec des services exposes. C’est la meme architecture fondamentale utilisee dans les environnements de production Kubernetes a travers le monde.
Points cles :
- Kubernetes orchestre les conteneurs a travers plusieurs noeuds avec une planification, une mise a l’echelle et une auto-reparation automatisees
- Le plan de controle (API server, etcd, scheduler, controller manager) gere l’etat du cluster tandis que les noeuds worker executent vos charges de travail
- kubeadm est l’outil officiel pour amorcer des clusters de niveau production
- Les Deployments fournissent une gestion declarative des Pods avec des mises a jour progressives et des retours en arriere
- Les Services (ClusterIP, NodePort, LoadBalancer) donnent aux Pods des points d’acces reseau stables
- Utilisez toujours des manifestes YAML pour les charges de travail en production afin de permettre le controle de version et la reproductibilite
Pour les fondamentaux de la conteneurisation qui completent ce guide, consultez nos tutoriels sur Comment Installer Docker sur Ubuntu et Docker Compose : Guide Pratique pour Administrateurs Systeme.