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 :

  1. CPU ou memoire insuffisante sur les noeuds worker
  2. Taints de noeud empechant la planification
  3. 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 :

  1. Erreur d’application ou mauvaise configuration
  2. Variables d’environnement ou config maps manquantes
  3. 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 :

  1. Plugin CNI non installe ou en echec
  2. kubelet ne peut pas atteindre le serveur API
  3. 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

CommandeDescription
kubectl get nodesLister tous les noeuds du cluster
kubectl get podsLister les Pods dans le namespace actuel
kubectl get pods -ALister les Pods dans tous les namespaces
kubectl get servicesLister tous les Services
kubectl get deploymentsLister 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/bashOuvrir 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=NMettre 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 nodesAfficher l’utilisation des ressources des noeuds
kubectl top podsAfficher l’utilisation des ressources des Pods
kubectl config get-contextsLister les contextes de cluster disponibles
kubectl cluster-infoAfficher 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.