Ce chapitre est gratuit
Pas besoin de compte pour le lire. Decouvre le contenu et decide si le programme est fait pour toi.
Voir les autres chapitresUn conteneur, c’est cool. Cent conteneurs, c’est le chaos.
Tu sais utiliser Docker. Tu sais créer des images, lancer des conteneurs, exposer des ports. Nickel. Mais maintenant, imagine la situation suivante :
Tu gères une application en production. Elle a :
- 3 conteneurs pour l’API
- 2 conteneurs pour le frontend
- 1 conteneur pour la base de données
- 1 conteneur pour le cache Redis
- 1 conteneur pour le worker de tâches en arrière-plan
Ça fait 8 conteneurs. Gérable à la main ? Peut-être. Maintenant, multiplie par 10. Tu as 80 conteneurs répartis sur 15 serveurs.
Qui redémarre un conteneur quand il plante à 3h du matin ? Toi ? Non merci.
Qui ajoute des conteneurs quand le trafic explose un vendredi soir ? Un script bash fragile ? Bon courage.
Qui déploie la nouvelle version sans couper le service ? Tu vas vraiment arrêter tous les conteneurs, mettre à jour, et relancer en priant ?
C’est exactement là que l’orchestration entre en jeu. Et l’orchestrateur qui a gagné la bataille, c’est Kubernetes.
L’analogie du manager d’hôtel
Pour bien comprendre le rôle de Kubernetes, imagine un hôtel avec 100 chambres. Chaque chambre représente un conteneur. Tu as besoin d’un manager qui :
- Attribue les chambres aux clients → place les conteneurs sur les bons serveurs
- Vérifie que tout fonctionne → si une chambre a un problème, il en attribue une autre automatiquement
- Gère l’affluence → plus de clients ? On ouvre des chambres supplémentaires
- Organise les rénovations → mettre à jour une chambre sans mettre le client dehors
- Gère les accès → qui peut aller où, avec quelle clé
Kubernetes, c’est ce manager. Tu lui dis “je veux 5 instances de mon API, toujours disponibles” et il se débrouille. Un serveur tombe ? Il relance les conteneurs ailleurs. Le trafic double ? Il en crée de nouveaux. Une nouvelle version arrive ? Il fait la transition en douceur.
🧠 À retenir : Kubernetes ne fait pas tourner tes conteneurs directement. Il déclare un état souhaité et s’assure en permanence que l’état réel y correspond. C’est le principe du contrôle déclaratif : tu dis “je veux 3 réplicas de mon API”, Kubernetes fait le nécessaire pour que ce soit toujours le cas.
Pourquoi Kubernetes s’est imposé ?
Avant K8s, il existait d’autres solutions d’orchestration : Docker Swarm, Apache Mesos, HashiCorp Nomad… Kubernetes a gagné, et de loin. Voici pourquoi :
Une base solide : 15 ans d’expérience Google
Kubernetes n’est pas sorti de nulle part. Google utilisait un système interne appelé Borg depuis le début des années 2000 pour orchestrer des millions de conteneurs dans ses datacenters. Quand Google a open-sourcé Kubernetes en 2014, c’était une version repensée de cette expertise.
🔥 Cas réel en entreprise : Chez Google, Borg gère des workloads massifs — Gmail, YouTube, Google Search. Chaque semaine, Google lance environ 4 milliards de conteneurs. Kubernetes est le fils spirituel de cette infrastructure. Quand tu utilises K8s, tu bénéficies de patterns éprouvés à une échelle que peu d’entreprises atteignent.
L’écosystème et la communauté
Kubernetes a un avantage écrasant : sa communauté. C’est le projet le plus actif de la CNCF (Cloud Native Computing Foundation) avec :
- Plus de 88 000 étoiles sur GitHub
- Des milliers de contributeurs (Google, Red Hat, Microsoft, Amazon, VMware…)
- Un écosystème d’outils massif : Helm, Istio, ArgoCD, Prometheus, Grafana, Cert-Manager, Tekton…
Le standard de l’industrie
Tous les grands cloud providers proposent un Kubernetes managé :
| Cloud Provider | Service Kubernetes |
|---|---|
| AWS | EKS (Elastic Kubernetes Service) |
| Google Cloud | GKE (Google Kubernetes Engine) |
| Azure | AKS (Azure Kubernetes Service) |
| OVHcloud | Managed Kubernetes |
| DigitalOcean | DOKS |
| Scaleway | Kapsule |
💡 Tip DevOps : En entreprise, tu travailleras rarement avec un cluster “bare metal”. La plupart des boîtes utilisent un Kubernetes managé (EKS, GKE, AKS). Le control plane est géré par le cloud provider — tu n’as qu’à te soucier de tes workloads. Mais comprendre l’architecture complète est indispensable pour debugger les problèmes en production.
Et les alternatives ?
Pour être honnête, les alternatives existent encore et ont leurs use cases :
- Docker Swarm → Plus simple à configurer, mais écosystème limité. Docker Inc. a officiellement arrêté Swarm Mode dans Docker Desktop.
- Nomad (HashiCorp) → Excellente alternative, plus simple que K8s, supporte les conteneurs ET les VMs. Adopté par certaines boîtes qui trouvent K8s trop complexe.
- Amazon ECS → Spécifique AWS, pas d’orchestration multi-cloud.
Mais dans les offres d’emploi DevOps, c’est K8s qui domine massivement. Si tu dois choisir un orchestrateur à apprendre, c’est celui-là.
🧠 À retenir : Kubernetes n’est pas “le meilleur” dans l’absolu. C’est le standard. Et en informatique, le standard gagne souvent sur le meilleur (voir VHS vs Betamax, TCP/IP vs OSI). Le savoir-faire K8s est transférable partout : d’AWS à GCP, d’une startup à un grand groupe.
Prérequis
Avant d’aller plus loin, assure-toi d’avoir les bases suivantes :
- ✅ Docker — Tu sais créer des images, lancer des conteneurs, écrire un Dockerfile et utiliser docker-compose
- ✅ Linux — Tu es à l’aise dans un terminal (naviguer, éditer des fichiers, gérer des processus)
- ✅ Réseau — Tu comprends les concepts d’IP, ports, DNS et load balancing
- ✅ YAML — Tu sais lire et écrire du YAML (c’est le langage de configuration de Kubernetes)
⚠️ Attention : Si tu ne maîtrises pas Docker, arrête-toi ici. Kubernetes orchestre des conteneurs — il ne les remplace pas. Sans une bonne compréhension de Docker, tu vas te perdre dans l’abstraction. Reviens après avoir suivi une formation Docker complète.
Ce que tu vas apprendre dans ce chapitre
- ☸️ Pourquoi l’orchestration de conteneurs est nécessaire
- 🏗️ L’architecture de Kubernetes (control plane, worker nodes, composants)
- 📦 Les concepts fondamentaux : Pods, Deployments, Services, Namespaces
- 🛠️ Installer un cluster local avec Kind et utiliser
kubectl - 🚀 Déployer ta première application sur Kubernetes
- 🔍 Inspecter, debugger et gérer tes ressources K8s
Architecture de Kubernetes
Comprendre l’architecture de K8s, c’est la clé pour debugger efficacement en production. On va décortiquer chaque composant.
Un cluster Kubernetes se compose de deux grandes parties :
- Le Control Plane (le cerveau) — il prend les décisions
- Les Worker Nodes (les bras) — ils exécutent les conteneurs
Schéma d’architecture
graph TB
subgraph CP["Control Plane"]
API[API Server]
ETCD[(etcd)]
Sched[Scheduler]
CM[Controller Manager]
API --- ETCD
API --- Sched
API --- CM
end
subgraph W1["Worker Node 1"]
Kubelet1[Kubelet]
KProxy1[Kube-proxy]
Pod1[Pod A]
Pod2[Pod B]
Kubelet1 --> Pod1
Kubelet1 --> Pod2
end
subgraph W2["Worker Node 2"]
Kubelet2[Kubelet]
KProxy2[Kube-proxy]
Pod3[Pod C]
Pod4[Pod D]
Kubelet2 --> Pod3
Kubelet2 --> Pod4
end
API --> Kubelet1
API --> Kubelet2
style CP fill:#0a0e17,stroke:#dc2626,color:#f1f5f9
style W1 fill:#0a0e17,stroke:#3b82f6,color:#f1f5f9
style W2 fill:#0a0e17,stroke:#3b82f6,color:#f1f5f9
style API fill:#7f1d1d,stroke:#dc2626,color:#f1f5f9
style ETCD fill:#1a2332,stroke:#f59e0b,color:#f1f5f9
Le Control Plane : le cerveau du cluster
Le Control Plane est l’ensemble des composants qui gèrent l’état global du cluster. En production, ces composants tournent sur des nœuds dédiés appelés “masters” (généralement 3 pour la haute disponibilité).
API Server (kube-apiserver)
C’est le point d’entrée unique de tout le cluster. Absolument toute interaction avec Kubernetes passe par lui :
- Quand tu tapes
kubectl get pods, ta requête arrive à l’API Server - Quand le Scheduler doit placer un pod, il communique avec l’API Server
- Quand un kubelet rapporte l’état d’un nœud, il envoie ça à l’API Server
- Quand ArgoCD déploie une application, il parle à l’API Server
L’API Server expose une API REST et gère trois étapes pour chaque requête :
- Authentification — Qui es-tu ? (certificat, token, OIDC…)
- Autorisation — As-tu le droit ? (RBAC, ABAC…)
- Admission — La requête est-elle valide ? (Admission controllers, webhooks…)
🔥 Cas réel en entreprise : Dans un cluster de production multi-équipes, l’API Server est souvent le premier goulot d’étranglement. Si tu as des centaines de développeurs qui interrogent le cluster simultanément, ou des outils de monitoring trop agressifs, l’API Server peut saturer. C’est pour ça qu’on configure des rate limits et qu’on utilise des informers/caches côté client plutôt que de bombarder l’API directement.
etcd
etcd est une base de données clé-valeur distribuée qui stocke tout l’état du cluster :
- La liste des pods, deployments, services
- Les configurations (ConfigMaps)
- Les secrets
- Les RBAC (rôles, bindings)
- L’état des nœuds
C’est la source de vérité unique du cluster. Si etcd est perdu et qu’il n’y a pas de backup, le cluster est perdu.
⚠️ Attention : En production, etcd est LE composant le plus critique. Il doit tourner en cluster de 3 ou 5 instances (toujours un nombre impair pour le consensus Raft). Les backups etcd doivent être automatisés et testés régulièrement. Un
etcdctl snapshot savequotidien est le strict minimum.
💡 Tip DevOps : Sur les Kubernetes managés (EKS, GKE, AKS), tu n’as pas accès à etcd — c’est le cloud provider qui le gère et le backup. C’est un des gros avantages du managed : tu ne te réveilles pas à 3h du matin parce qu’etcd a rempli son disque.
Scheduler (kube-scheduler)
Quand un nouveau pod doit être créé et qu’il n’est pas encore assigné à un nœud, le Scheduler entre en action. Son rôle : décider sur quel nœud placer le pod.
Le Scheduler fonctionne en deux phases :
- Filtrage — Éliminer les nœuds qui ne conviennent pas (pas assez de CPU, mauvaise zone, taints incompatibles…)
- Scoring — Parmi les nœuds restants, attribuer un score pour choisir le meilleur
Les critères pris en compte sont nombreux :
- Ressources disponibles — CPU et mémoire libres sur le nœud
- Affinité/Anti-affinité — “Place ce pod près de tel autre” ou “éloigne-le de tel autre”
- Taints et Tolerations — “Ce nœud est réservé aux workloads GPU” (taint), “ce pod accepte les nœuds GPU” (toleration)
- Topologie — Zones de disponibilité, régions
🧠 À retenir : Le Scheduler ne déplace jamais un pod déjà en cours d’exécution. Il ne s’occupe que des pods non assignés. Si tu veux rééquilibrer les pods sur tes nœuds, tu dois utiliser un outil comme
descheduler.
Controller Manager (kube-controller-manager)
Le Controller Manager regroupe un ensemble de boucles de contrôle (controllers) qui surveillent en permanence l’état du cluster et le corrigent si nécessaire. Chaque controller a une responsabilité précise :
| Controller | Rôle |
|---|---|
| ReplicaSet Controller | Vérifie que le bon nombre de pods tourne. Un pod meurt ? Il en relance un. |
| Deployment Controller | Gère les rolling updates et les rollbacks |
| Node Controller | Surveille la santé des nœuds (heartbeat toutes les 10s) |
| Job Controller | Gère les tâches ponctuelles (batch jobs) |
| ServiceAccount Controller | Crée les comptes de service par défaut dans les namespaces |
| Endpoint Controller | Maintient la liste des IPs de pods derrière un Service |
Le principe est toujours le même : boucle de réconciliation. Le controller compare l’état souhaité (ce que tu as déclaré dans ton YAML) avec l’état actuel (ce qui tourne réellement) et agit pour combler l’écart.
🧠 À retenir : Cette boucle de réconciliation est le cœur de Kubernetes. On l’appelle aussi le pattern du contrôleur ou reconciliation loop. C’est ce qui rend K8s self-healing : si quelque chose diverge de l’état souhaité, un controller le corrige automatiquement.
Les Worker Nodes : les bras du cluster
Les Worker Nodes sont les machines (physiques ou virtuelles) qui font tourner tes conteneurs. Chaque nœud embarque trois composants essentiels.
kubelet
Le kubelet est l’agent qui tourne sur chaque nœud. C’est lui qui fait le lien entre le Control Plane et les conteneurs.
Son fonctionnement :
- Il reçoit les spécifications de pods depuis l’API Server (via un watch)
- Il communique avec le container runtime pour créer/supprimer des conteneurs
- Il effectue des health checks (liveness probes, readiness probes) sur les conteneurs
- Il rapporte l’état du nœud et des pods au Control Plane
💡 Tip DevOps : Si un pod ne démarre pas sur un nœud, le premier réflexe est de vérifier les logs du kubelet :
journalctl -u kubelet -f. C’est souvent lui qui te dira pourquoi (image introuvable, ressources insuffisantes, problème de permissions…).
kube-proxy
kube-proxy gère les règles réseau sur chaque nœud. Quand tu crées un Service Kubernetes, kube-proxy s’assure que le trafic réseau est correctement routé vers les bons pods.
Il fonctionne en trois modes possibles :
- iptables (par défaut) — Crée des règles iptables pour le routage. Performant pour la plupart des cas.
- IPVS — Plus performant pour les clusters avec beaucoup de Services (milliers). Utilise le module IPVS du kernel Linux.
- userspace — Mode legacy, plus utilisé.
🔥 Cas réel en entreprise : Dans un cluster avec 5000+ Services, le mode iptables peut devenir lent (les règles iptables sont parcourues séquentiellement). C’est là qu’on passe en mode IPVS. Si tu gères un cluster de cette taille, tu le sais déjà. Sinon, iptables suffit largement.
Container Runtime
Le container runtime est le moteur qui fait réellement tourner les conteneurs. Kubernetes communique avec lui via l’interface standard CRI (Container Runtime Interface).
Les runtimes les plus courants :
- containerd — Le plus répandu. C’est le runtime que Docker utilise en interne. Léger et fiable.
- CRI-O — Créé spécifiquement pour Kubernetes par Red Hat. Utilisé par défaut dans OpenShift.
⚠️ Attention : Depuis Kubernetes 1.24, Docker n’est plus supporté comme runtime direct (suppression du “dockershim”). Mais pas de panique : tes images Docker restent 100% compatibles. Docker produit des images OCI standard que containerd sait lancer. C’est uniquement le “runtime Docker” qui n’est plus utilisé côté cluster.
Concepts fondamentaux
Maintenant que tu connais l’architecture, passons aux objets que tu vas manipuler au quotidien. On commence par les quatre piliers : Pods, Deployments, Services et Namespaces.
Pods : la brique de base
Le Pod est la plus petite unité déployable dans Kubernetes. Ce n’est pas un conteneur — c’est une enveloppe autour d’un ou plusieurs conteneurs qui partagent :
- Le même réseau — Même adresse IP, mêmes ports (les conteneurs du pod se parlent via
localhost) - Le même stockage — Volumes partagés entre conteneurs du pod
- Le même cycle de vie — Ils démarrent et s’arrêtent ensemble
Dans 90% des cas, un pod contient un seul conteneur. Les pods multi-conteneurs servent pour des patterns bien spécifiques :
- Sidecar — Un conteneur auxiliaire qui ajoute une fonctionnalité (ex: un proxy Envoy, un collecteur de logs)
- Init Container — Un conteneur qui s’exécute avant le conteneur principal (ex: migrations de BDD, téléchargement de config)
Voici à quoi ressemble la déclaration d’un Pod simple. On déclare l’API version, le type d’objet, les métadonnées (nom et labels), puis la spec avec le ou les conteneurs :
apiVersion: v1
kind: Pod
metadata:
name: mon-api
labels:
app: mon-api
env: dev
spec:
containers:
- name: api
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "250m"
Décortiquons ce YAML :
apiVersion: v1— Les pods font partie de l’API core de Kuberneteskind: Pod— Le type d’objet qu’on créemetadata.name— Le nom unique du pod dans son namespacemetadata.labels— Des étiquettes clé-valeur pour organiser et sélectionner les podsspec.containers— La liste des conteneurs dans le podresources.requests— Le minimum garanti de ressources (utilisé par le Scheduler pour placer le pod)resources.limits— Le maximum autorisé (le pod est tué s’il dépasse la mémoire limit)
⚠️ Attention : Ne déploie jamais des pods directement en production. Un pod seul n’est pas résilient : s’il meurt, personne ne le recrée. Utilise toujours un Deployment (ou un StatefulSet, DaemonSet selon le cas) qui gère le cycle de vie des pods pour toi.
💡 Tip DevOps : Toujours définir les
resources.requestsetresources.limitssur tes conteneurs. Sans ça, le Scheduler ne peut pas prendre de bonnes décisions de placement, et un pod gourmand peut tuer le nœud entier en consommant toute la mémoire (OOM Kill). En entreprise, on utilise des LimitRange et ResourceQuota pour forcer ces bonnes pratiques au niveau du namespace.
Deployments : la gestion déclarative des pods
Un Deployment est l’objet que tu utiliseras 95% du temps pour déployer des applications. Il déclare l’état souhaité : quelle image, combien de réplicas, quelle stratégie de mise à jour.
Sous le capot, un Deployment crée un ReplicaSet, qui à son tour crée les Pods. La hiérarchie est :
Deployment → ReplicaSet → Pod(s)
Pourquoi cette hiérarchie ? Parce que lors d’une mise à jour, le Deployment crée un nouveau ReplicaSet avec la nouvelle version et scale down l’ancien progressivement. C’est comme ça que le rolling update fonctionne.
Voici un Deployment complet avec les bonnes pratiques :
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-api
labels:
app: mon-api
spec:
replicas: 3
selector:
matchLabels:
app: mon-api
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: mon-api
spec:
containers:
- name: api
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "250m"
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Détaillons les éléments importants :
replicas: 3— Kubernetes maintient toujours 3 pods actifs. Un pod meurt ? Un nouveau est recréé immédiatement.selector.matchLabels— Le Deployment sait quels pods il gère grâce aux labels. Le selector doit matcher les labels du template.strategy.type: RollingUpdate— Pendant une mise à jour, les anciens pods sont remplacés progressivementmaxUnavailable: 1— Au maximum 1 pod indisponible pendant le updatemaxSurge: 1— Au maximum 1 pod en plus pendant le update (donc entre 2 et 4 pods pendant la transition)livenessProbe— “Est-ce que le conteneur est vivant ?” Si la probe échoue, Kubernetes redémarre le conteneurreadinessProbe— “Est-ce que le conteneur est prêt à recevoir du trafic ?” Si la probe échoue, le pod est retiré du Service (plus de trafic)
🧠 À retenir : La différence entre liveness et readiness est cruciale. Liveness = le conteneur est-il vivant ? (sinon, on le tue et on le relance). Readiness = le conteneur est-il prêt ? (sinon, on arrête de lui envoyer du trafic mais on ne le tue pas). Confondre les deux est une erreur classique qui provoque des cascades de redémarrages.
🔥 Cas réel en entreprise : Imagine une API qui charge un gros modèle ML au démarrage (30 secondes). Si ta liveness probe a un
initialDelaySecondstrop court, Kubernetes va tuer le conteneur avant qu’il ait fini de démarrer, le relancer, le tuer à nouveau… en boucle infinie. C’est le CrashLoopBackOff, un classique qu’on a tous vécu au moins une fois.
Services : l’accès réseau stable
Les pods sont éphémères — ils peuvent être recréés à tout moment avec une IP différente. Tu ne peux pas hardcoder l’IP d’un pod quelque part, elle changera au prochain redémarrage.
Un Service résout ce problème en fournissant :
- Une adresse IP stable (ClusterIP) qui ne change pas
- Un nom DNS pour la découverte de service (ex:
mon-api-service.default.svc.cluster.local) - Du load balancing automatique entre les pods ciblés
Le Service sait quels pods cibler grâce au selector : il envoie le trafic à tous les pods dont les labels matchent.
Les types de Services
Kubernetes propose trois types de Services principaux, chacun avec un use case différent :
ClusterIP (par défaut) — Accessible uniquement à l’intérieur du cluster. C’est le type le plus utilisé pour la communication entre microservices.
apiVersion: v1
kind: Service
metadata:
name: mon-api-service
spec:
selector:
app: mon-api
ports:
- port: 80
targetPort: 80
type: ClusterIP
Ce Service crée une IP virtuelle interne au cluster. Tout pod du cluster peut atteindre ton API via mon-api-service ou mon-api-service.default.svc.cluster.local.
NodePort — Expose le Service sur un port de chaque nœud du cluster (plage 30000-32767). Le trafic externe arrive sur <IP-du-noeud>:<NodePort> et est routé vers les pods.
apiVersion: v1
kind: Service
metadata:
name: mon-api-nodeport
spec:
selector:
app: mon-api
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
💡 Tip DevOps : Le NodePort est pratique pour le développement local ou les tests, mais en production, on l’utilise rarement directement. On préfère un LoadBalancer ou un Ingress Controller (NGINX, Traefik) qui gère le TLS, le routing par nom de domaine, etc.
LoadBalancer — Provisionne automatiquement un load balancer externe via le cloud provider (AWS ELB, GCP LB, Azure LB…). C’est la manière standard d’exposer un Service au monde extérieur en cloud.
apiVersion: v1
kind: Service
metadata:
name: mon-api-lb
spec:
selector:
app: mon-api
ports:
- port: 80
targetPort: 80
type: LoadBalancer
⚠️ Attention : Chaque Service de type LoadBalancer crée un load balancer dédié chez ton cloud provider. À 15-25€/mois chacun, ça chiffre vite si tu as 20 services. En pratique, on utilise un seul Ingress Controller (NGINX ou Traefik) derrière un LoadBalancer, et l’Ingress Controller route vers les différents services internes. On verra ça dans un chapitre ultérieur.
Comment le DNS fonctionne dans Kubernetes
Kubernetes inclut un serveur DNS interne (CoreDNS) qui attribue automatiquement un nom DNS à chaque Service. Le format est :
<nom-du-service>.<namespace>.svc.cluster.local
Exemples concrets :
mon-api-service.default.svc.cluster.local— Service “mon-api-service” dans le namespace “default”postgres.database.svc.cluster.local— Service “postgres” dans le namespace “database”
Dans le même namespace, tu peux utiliser le nom court : mon-api-service.
🧠 À retenir : Grâce au DNS interne, tes microservices n’ont jamais besoin de connaître les IPs des pods. Ils se réfèrent aux Services par leur nom. C’est la base de la découverte de services dans Kubernetes.
Namespaces : l’isolation logique
Les Namespaces permettent de partitionner un cluster en espaces logiques isolés. C’est essentiel quand plusieurs équipes ou plusieurs environnements partagent le même cluster.
Par défaut, Kubernetes crée quatre namespaces :
| Namespace | Rôle |
|---|---|
default | Là où tes ressources atterrissent si tu ne spécifies pas de namespace |
kube-system | Les composants système de K8s (CoreDNS, kube-proxy, controller-manager…) |
kube-public | Ressources lisibles par tous (rarement utilisé) |
kube-node-lease | Utilisé pour les heartbeats des nœuds (mécanisme interne) |
En pratique, tu crées tes propres namespaces. Deux stratégies courantes :
Par environnement :
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production
Par équipe :
kubectl create namespace team-backend
kubectl create namespace team-frontend
kubectl create namespace team-data
🔥 Cas réel en entreprise : Dans un cluster mutualisé, les namespaces sont combinés avec des ResourceQuota (limiter les ressources par namespace) et des NetworkPolicy (isoler le réseau entre namespaces). Sans ça, l’équipe data peut lancer un job Spark qui consomme toute la mémoire du cluster et fait tomber l’API de production. Vécu, pas inventé.
💡 Tip DevOps : Ajoute toujours
-n <namespace>à tes commandes kubectl, ou mieux, configure un contexte par défaut :kubectl config set-context --current --namespace=dev. Ça évite de travailler accidentellement dans le mauvais namespace. En production, unkubectl delete poddans le mauvais namespace, ça fait mal.
Installation locale avec Kind
Pourquoi Kind plutôt que Minikube ?
Kind (Kubernetes IN Docker) crée des clusters Kubernetes en utilisant des conteneurs Docker comme nœuds. C’est devenu l’outil de référence pour le développement local, et voici pourquoi :
| Critère | Kind | Minikube |
|---|---|---|
| Technologie | Conteneurs Docker | VM (ou conteneurs) |
| Démarrage | ~30 secondes | ~2-5 minutes |
| Multi-nœuds | ✅ Natif | ⚠️ Expérimental |
| Ressources | Léger | Plus lourd (VM) |
| CI/CD | ✅ Parfait | ⚠️ Plus complexe |
| Utilisé par | Le projet Kubernetes lui-même | Développeurs individuels |
💡 Tip DevOps : Kind est utilisé par le projet Kubernetes pour ses propres tests d’intégration. Si c’est assez bon pour tester Kubernetes lui-même, c’est assez bon pour ton dev local.
Installation de Kind et kubectl
Avant de créer un cluster, tu as besoin de deux outils : Kind pour créer le cluster et kubectl pour interagir avec.
Sur macOS avec Homebrew :
brew install kind kubectl
Sur Linux (amd64) :
# Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
# Vérification
kind version
kubectl version --client
⚠️ Attention : Docker doit être installé et en cours d’exécution avant d’utiliser Kind. Kind crée des conteneurs Docker qui simulent des nœuds Kubernetes. Sans Docker, rien ne fonctionne.
Créer ton premier cluster
La commande la plus simple pour démarrer :
kind create cluster --name mon-cluster
Kind va :
- Télécharger l’image Docker du nœud Kubernetes
- Lancer un conteneur qui fait office de nœud (control plane + worker combinés)
- Configurer
kubectlpour pointer vers ce cluster
Vérifie que tout fonctionne :
# Infos sur le cluster
kubectl cluster-info --context kind-mon-cluster
# Liste des nœuds
kubectl get nodes
# Tu devrais voir quelque chose comme :
# NAME STATUS ROLES AGE VERSION
# mon-cluster-control-plane Ready control-plane 30s v1.31.0
Cluster multi-nœuds : simuler la production
Un cluster avec un seul nœud, c’est bien pour commencer. Mais pour tester le scheduling, les affinités et la haute disponibilité, tu veux plusieurs nœuds.
Crée un fichier de configuration Kind :
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
Puis lance le cluster avec cette config :
kind create cluster --name lab --config kind-config.yaml
Vérifie :
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# lab-control-plane Ready control-plane 45s v1.31.0
# lab-worker Ready <none> 30s v1.31.0
# lab-worker2 Ready <none> 30s v1.31.0
Tu as maintenant un cluster avec 1 control plane et 2 workers, le tout dans des conteneurs Docker. Tu peux vérifier avec docker ps que Kind a lancé 3 conteneurs.
🧠 À retenir : Kind est parfait pour le dev local et les tests CI/CD. Mais ce n’est pas fait pour la production. Pour de la prod, utilise un Kubernetes managé (EKS, GKE, AKS) ou une installation bare-metal avec kubeadm.
Commandes kubectl essentielles
kubectl est ton interface principale avec Kubernetes. Voici les commandes que tu vas utiliser tous les jours :
Lire des informations
# Lister les pods (namespace par défaut)
kubectl get pods
# Lister les pods dans tous les namespaces
kubectl get pods -A
# Lister avec plus de détails (IP, nœud, statut)
kubectl get pods -o wide
# Détails complets d'un pod (événements, conditions, volumes...)
kubectl describe pod <nom-du-pod>
# Voir les logs d'un pod
kubectl logs <nom-du-pod>
# Suivre les logs en temps réel (comme tail -f)
kubectl logs -f <nom-du-pod>
# Logs d'un conteneur spécifique dans un pod multi-conteneurs
kubectl logs <nom-du-pod> -c <nom-du-conteneur>
Créer et modifier des ressources
# Appliquer un fichier YAML (crée ou met à jour)
kubectl apply -f mon-fichier.yaml
# Supprimer une ressource
kubectl delete -f mon-fichier.yaml
kubectl delete pod <nom-du-pod>
# Scaler un deployment
kubectl scale deployment mon-api --replicas=5
# Mettre à jour l'image d'un deployment
kubectl set image deployment/mon-api api=nginx:1.28
Debugger
# Ouvrir un shell dans un pod en cours d'exécution
kubectl exec -it <nom-du-pod> -- /bin/sh
# Voir les événements du cluster (très utile pour debug)
kubectl get events --sort-by='.lastTimestamp'
# Voir les ressources consommées par les pods
kubectl top pods
# Voir les ressources consommées par les nœuds
kubectl top nodes
# Voir toutes les ressources API disponibles
kubectl api-resources
💡 Tip DevOps : Configure l’autocomplétion de kubectl dans ton shell. Ça change la vie :
# Bash echo 'source <(kubectl completion bash)' >> ~/.bashrc # Zsh echo 'source <(kubectl completion zsh)' >> ~/.zshrcEt crée un alias :
alias k=kubectldans ton.bashrcou.zshrc. En production, quand tu debugges un incident à 3h du matin, chaque frappe économisée compte.
Déploie ta première application
Passons à la pratique. Tu vas déployer une application nginx complète avec un Deployment et un Service.
Étape 1 — Le Deployment
Crée un fichier nginx-deployment.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
labels:
app: nginx-demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "64Mi"
cpu: "100m"
Applique-le :
kubectl apply -f nginx-deployment.yaml
Vérifie le déploiement :
# Le deployment
kubectl get deployment nginx-demo
# Les pods créés
kubectl get pods -l app=nginx-demo
# Le ReplicaSet créé automatiquement
kubectl get replicaset
Tu devrais voir 3 pods en status Running. Si un pod est en Pending ou CrashLoopBackOff, utilise kubectl describe pod <nom> pour comprendre pourquoi.
Étape 2 — Le Service
Maintenant, expose ton Deployment avec un Service. Crée nginx-service.yaml :
apiVersion: v1
kind: Service
metadata:
name: nginx-demo-service
spec:
selector:
app: nginx-demo
ports:
- port: 80
targetPort: 80
type: NodePort
Applique-le :
kubectl apply -f nginx-service.yaml
Vérifie :
kubectl get service nginx-demo-service
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# nginx-demo-service NodePort 10.96.123.456 <none> 80:30XXX/TCP 5s
Le port 30XXX est le NodePort attribué automatiquement. Avec Kind, tu peux accéder à ton application via le port-forward :
kubectl port-forward service/nginx-demo-service 8080:80
Ouvre http://localhost:8080 dans ton navigateur — tu verras la page d’accueil nginx. 🎉
Étape 3 — Teste la résilience
Kubernetes promet le self-healing. Vérifions :
# Liste les pods
kubectl get pods -l app=nginx-demo
# Supprime un pod (simule un crash)
kubectl delete pod <nom-du-premier-pod>
# Regarde ce qui se passe
kubectl get pods -l app=nginx-demo -w
Tu vas voir : le pod supprimé disparaît, et un nouveau pod est immédiatement créé par le ReplicaSet pour maintenir les 3 réplicas. C’est le self-healing en action.
🧠 À retenir : Tu viens de voir le cœur de Kubernetes : tu déclares un état souhaité (3 réplicas), et Kubernetes se bat en permanence pour maintenir cet état. Que ce soit un crash, un nœud qui tombe, ou une suppression manuelle — le controller recrée ce qui manque.
Étape 4 — Teste le rolling update
Mets à jour l’image de ton deployment :
# Passe de nginx 1.27 à 1.28
kubectl set image deployment/nginx-demo nginx=nginx:1.28
# Observe le rolling update en temps réel
kubectl rollout status deployment/nginx-demo
# Vérifie l'historique des déploiements
kubectl rollout history deployment/nginx-demo
Pendant le rolling update, Kubernetes :
- Crée un nouveau ReplicaSet avec l’image 1.28
- Scale up le nouveau ReplicaSet (1 pod)
- Vérifie que le nouveau pod est Ready
- Scale down l’ancien ReplicaSet (1 pod)
- Répète jusqu’à ce que tous les pods soient sur la nouvelle version
Si quelque chose ne va pas, rollback instantané :
kubectl rollout undo deployment/nginx-demo
🔥 Cas réel en entreprise : Le rolling update est la stratégie de déploiement par défaut, mais il y en a d’autres. Le Blue/Green (deux environnements complets, switch instantané) et le Canary (envoyer un petit pourcentage de trafic vers la nouvelle version) sont courants en production. Des outils comme ArgoCD Rollouts ou Flagger permettent d’implémenter ces stratégies avancées sur Kubernetes.
Nettoyage
Quand tu as fini de jouer avec ton cluster, nettoie :
# Supprimer les ressources créées
kubectl delete -f nginx-deployment.yaml
kubectl delete -f nginx-service.yaml
# Ou supprimer le cluster entier
kind delete cluster --name mon-cluster
kind delete cluster --name lab
Résumé du chapitre
Voici ce que tu as appris dans ce premier chapitre :
| Concept | Ce qu’il faut retenir |
|---|---|
| Kubernetes | Un orchestrateur de conteneurs qui maintient un état déclaré |
| Control Plane | Le cerveau : API Server, etcd, Scheduler, Controller Manager |
| Worker Node | Les bras : kubelet, kube-proxy, container runtime |
| Pod | La plus petite unité déployable (1 pod ≈ 1 conteneur) |
| Deployment | Gère les pods : réplicas, rolling updates, rollbacks |
| Service | Adresse réseau stable pour accéder aux pods (ClusterIP, NodePort, LoadBalancer) |
| Namespace | Isolation logique des ressources dans le cluster |
| Kind | Outil pour créer des clusters K8s locaux dans Docker |
| kubectl | CLI pour interagir avec Kubernetes |
🧠 À retenir : Kubernetes fonctionne sur un principe simple mais puissant : tu déclares ce que tu veux, Kubernetes s’assure que ça existe. Ce modèle déclaratif, combiné aux boucles de réconciliation des controllers, rend le système self-healing et résilient.
À toi de jouer
Exercice 1 — Crée ton cluster Kind
Installe Kind et crée un cluster multi-nœuds :
kind create cluster --name devops-lab --config kind-config.yaml
Vérifie avec kubectl cluster-info et kubectl get nodes. Explore les namespaces par défaut avec kubectl get ns. Combien de pods tournent dans kube-system ? À quoi sert chacun d’eux ?
Exercice 2 — Déploie et expose une application
- Crée un Deployment avec 5 réplicas d’une image
httpd:2.4(Apache) - Ajoute des
resources.requestsetresources.limits - Expose-le avec un Service de type NodePort
- Utilise
kubectl port-forwardpour y accéder dans ton navigateur - Vérifie que les 5 pods sont répartis sur les différents nœuds avec
kubectl get pods -o wide
Exercice 3 — Teste la résilience
- Supprime 2 pods manuellement et observe la recréation automatique
- Change l’image de ton deployment (ex:
httpd:2.4→httpd:2.5-alpine) et observe le rolling update - Fais un rollback et vérifie que l’ancienne version est restaurée
- Essaie de scaler à 10 réplicas, puis redescends à 2
Exercice 4 — Explore l’architecture
- Liste les composants du control plane :
kubectl get pods -n kube-system - Identifie l’API Server, le Scheduler, etcd et le Controller Manager
- Exécute
kubectl api-resources | head -30pour voir les types de ressources disponibles - Utilise
kubectl get events -A --sort-by='.lastTimestamp'pour voir l’activité du cluster
🚀 Pratique en direct
Envie de tester immédiatement ? Lance le Playground DevOpsLab — un terminal Linux complet dans ton navigateur avec tous les outils pré-installés.
➡️ La suite : Dans le prochain chapitre, on plonge dans les Deployments avancés — stratégies de déploiement, health checks, resource management et bonnes pratiques de production. On continue ! 🚀
🖥️ Pratique sur ton propre serveur
Pour suivre Apprendre Kubernetes en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Série : Apprendre Kubernetes
1 / 12- 1 Pourquoi Kubernetes ? L'orchestration expliquée
- 2 Architecture K8s et premières commandes kubectl
- 3 Deployments : déployer et mettre à jour
- 4 Services : exposer tes applications
- 5 Volumes et stockage persistant
- 6 ConfigMaps et Secrets
- 7 RBAC : qui a accès à quoi
- 8 Network Policies et Pod Security
- 9 CNI et networking K8s en détail
- 10 Service Mesh : Istio et Linkerd
- 11 Helm : le package manager de K8s
- 12 Créer et publier son chart Helm
Sur cette page
Articles liés
Architecture K8s et premières commandes kubectl
Installe Kind, lance ton premier déploiement et maîtrise les commandes kubectl essentielles.
Deployments : déployer et mettre à jour
Maîtrise les Deployments Kubernetes : ReplicaSets, rolling updates, rollbacks et scaling horizontal.
Services : exposer tes applications
Expose tes applications avec les Services, le DNS interne, Ingress et les NetworkPolicies.