TP12 : Kubernetes pour les nuls
Objectif du TP
- Comprendre pourquoi Kubernetes existe et en quoi il diffère de Compose et Swarm.
- Connaître les ressources fondamentales : Pod, Deployment, Service, ConfigMap, Secret.
- Déployer, scaler et mettre à jour une application sur Kubernetes via Docker Desktop.
- Lire et écrire des manifestes YAML Kubernetes.
Rendu attendu
- Notes dans votre carnet répondant aux questions posées.
- Captures montrant votre Deployment actif (
kubectl get all). - Captures montrant votre Service accessible dans le navigateur.
- Fichiers
deployment.yamletservice.yamlfonctionnels.
Questions d'ouverture
- Si vous maîtrisez déjà Docker Compose et Swarm, pourquoi apprendre Kubernetes ?
- Quand une startup a-t-elle vraiment besoin de Kubernetes ? Quand est-ce trop tôt ?
- Quelle différence entre un Pod Kubernetes et un conteneur Docker ?
Focus : Kubernetes en 5 phrases
- Kubernetes (K8s) est un orchestrateur de conteneurs open-source créé par Google, devenu le standard de l'industrie.
- Là où Docker Compose gère une machine locale et Swarm un cluster simple, Kubernetes gère des clusters complexes à grande échelle.
- Tout est déclaratif : vous décrivez l'état désiré dans des fichiers YAML, Kubernetes s'assure que la réalité y correspond en permanence.
- Kubernetes s'auto-répare : si un Pod crash, il est redémarré ; si un Node tombe, les Pods sont recréés ailleurs.
- Kubernetes est la norme cloud : AWS (EKS), GCP (GKE), Azure (AKS) l'utilisent tous.
Comparaison : Compose vs Swarm vs Kubernetes
| Critère | Docker Compose | Docker Swarm | Kubernetes |
|---|---|---|---|
| Portée | 1 machine locale | Cluster multi-nœuds | Cluster multi-nœuds |
| Complexité | Faible | Moyenne | Élevée |
| Auto-réparation | Non | Oui (basique) | Oui (avancé) |
| Scaling | Manuel | Manuel + service scale | Automatique (HPA) |
| Secrets | .env / Docker Secrets |
Docker Secrets | Kubernetes Secrets |
| Rolling update | Non | Oui | Oui |
| Stratégies de déploiement | Non | Rolling uniquement | Rolling, Blue-Green, Canary |
| Courbe d'apprentissage | Facile | Moyenne | Élevée |
| Adoption industrie | Dev/local | Faible | Très élevée |
Quand choisir quoi ?
- Compose : développement local, prototype, stack simple sur une seule machine.
- Swarm : cluster basique, équipes qui veulent rester proches de Docker, migration progressive.
- Kubernetes : production cloud à grande échelle, résilience critique, équipes DevOps dédiées.
Les concepts clés de Kubernetes
Le Cluster
Un cluster Kubernetes se compose de deux types de machines :
- Control Plane (master) : le cerveau du cluster. Gère le scheduling, surveille l'état du cluster, expose l'API.
- Worker Nodes : les machines qui font tourner vos applications.
flowchart LR
subgraph cluster["Cluster K8s"]
subgraph controlPlane["Control Plane"]
api["API Server"]
scheduler["Scheduler"]
etcd["etcd"]
end
subgraph worker1["Worker 1"]
podA["Pod A"]
podB["Pod B"]
end
subgraph worker2["Worker 2"]
podC["Pod C"]
podD["Pod D"]
end
api --> scheduler
api --> etcd
scheduler -. planifie .-> podA
scheduler -. planifie .-> podB
scheduler -. planifie .-> podC
scheduler -. planifie .-> podD
end
Via Docker Desktop, tout cela tourne en local dans une VM interne — vous avez un cluster à un seul nœud.
Pod
Le Pod est la plus petite unité déployable dans Kubernetes. Il contient un ou plusieurs conteneurs qui partagent le même réseau et le même stockage.
En pratique : un Pod = un conteneur (dans la grande majorité des cas). Vous ne créez presque jamais de Pod directement.
Deployment
Le Deployment est l'équivalent d'un service Swarm. Il décrit : - Quelle image utiliser - Combien de réplicas (Pods) maintenir - Comment mettre à jour (rolling update, rollback)
C'est la ressource que vous utiliserez le plus souvent.
Service
Un Service expose vos Pods sur le réseau. Sans Service, les Pods ne sont pas accessibles.
Types de Services :
| Type | Description |
|---|---|
ClusterIP |
Accessible uniquement depuis le cluster (par défaut) |
NodePort |
Accessible depuis l'extérieur via un port fixe sur chaque nœud |
LoadBalancer |
Crée un load balancer cloud (AWS ELB, GCP Load Balancer...) |
Namespace
Un Namespace isole des groupes de ressources dans un même cluster. Utile pour séparer plusieurs équipes ou environnements (dev/staging/prod) sur le même cluster.
kubectl get namespaces
# NAME STATUS
# default Active ← vos ressources vont ici par défaut
# kube-system Active ← composants internes de K8s
# kube-public Active ← ressources publiques du cluster
ConfigMap et Secret
- ConfigMap : configuration non sensible (variables d'environnement, fichiers de config). Équivalent à
.envmais géré par Kubernetes. - Secret : configuration sensible encodée en base64. Équivalent aux Docker Secrets.
Mise en pratique
1. Activer Kubernetes dans Docker Desktop
- Ouvrez Docker Desktop.
- Allez dans Setting (icône engrenage) -> Kubernetes.
- Cochez Enable Kubernetes.
- Cliquez Apply & Restart.
- Attendez que Kubernetes soit en état Running (indicateur vert en bas à gauche de Docker Desktop).
Vérifiez l'installation :
# Version du client et du serveur
kubectl version
# Informations sur le cluster
kubectl cluster-info
# Liste des nœuds (vous devriez en voir un : docker-desktop)
kubectl get nodes
Attention - Kubernetes via Docker Desktop peut prendre 2-3 minutes au premier démarrage. - Si
kubectln'est pas trouvé :brew install kubectlsur macOS. - Si le contexte pointe ailleurs :kubectl config use-context docker-desktop
2. Premier Deployment
2.1. Créer les fichiers YAML
Créez un dossier k8s-tp/ et à l'intérieur un fichier deployment.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-app
labels:
app: mon-app
spec:
replicas: 3 # 3 instances de notre application
selector:
matchLabels:
app: mon-app # Sélectionne les Pods ayant ce label
template: # Template utilisé pour créer chaque Pod
metadata:
labels:
app: mon-app # Label appliqué aux Pods (doit correspondre au selector)
spec:
containers:
- name: app
image: nginx:alpine # Image Docker à utiliser
ports:
- containerPort: 80
resources: # Bonne pratique : toujours définir des limites
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "200m"
Comprendre le YAML : -
apiVersion: version de l'API Kubernetes utilisée pour cette ressource. -kind: type de ressource (Deployment, Service, Pod, ConfigMap...). -metadata: informations sur la ressource (nom, labels, namespace). -spec: description de l'état désiré.
2.2. Appliquer le manifeste
# Appliquer le fichier (créer ou mettre à jour)
kubectl apply -f deployment.yaml
# Voir le Deployment
kubectl get deployments
# Voir les Pods créés
kubectl get pods
# Vue détaillée avec nœud et IP
kubectl get pods -o wide
# Tout voir d'un coup
kubectl get all
2.3. Diagnostiquer si ça ne démarre pas
# Logs d'un Pod
kubectl logs <pod-name>
# Décrire un Pod (très utile pour voir les événements et erreurs)
kubectl describe pod <pod-name>
# Exécuter un shell dans un Pod
kubectl exec -it <pod-name> -- sh
# Voir les événements du cluster
kubectl get events --sort-by='.lastTimestamp'
Question : Dans
kubectl get pods, que représentent les colonnesREADY,STATUS, etRESTARTS? Quelle valeur indique qu'un Pod fonctionne normalement ?
3. Exposer avec un Service
Sans Service, vos Pods sont inaccessibles depuis l'extérieur. Créez service.yaml :
apiVersion: v1
kind: Service
metadata:
name: mon-app-service
spec:
type: NodePort # Accessible depuis l'extérieur du cluster
selector:
app: mon-app # Cible les Pods ayant le label "app: mon-app"
ports:
- protocol: TCP
port: 80 # Port du Service dans le cluster
targetPort: 80 # Port du conteneur
nodePort: 30080 # Port exposé sur le nœud (doit être entre 30000-32767)
kubectl apply -f service.yaml
kubectl get services
# Tester depuis le navigateur ou la ligne de commande
curl http://localhost:30080
Question : Expliquez la différence entre
port,targetPortetnodePort. Faites un schéma.Parallèle avec Docker : Un Service
NodePortest l'équivalent d'une règleports: - "30080:80"dans Compose. Le ServiceClusterIP(défaut) est l'équivalent d'un service exposé uniquement sur le réseau interne Docker.
4. Scaling
# Scaler via kubectl (mode impératif)
kubectl scale deployment mon-app --replicas=5
# Vérifier
kubectl get pods
kubectl get deployment mon-app
# Revenir à 2 réplicas
kubectl scale deployment mon-app --replicas=2
Ou modifiez directement deployment.yaml et réappliquez :
Testez l'auto-réparation :
# Supprimer manuellement un Pod
kubectl delete pod <un-pod-name>
# Observer : Kubernetes en recrée un automatiquement
kubectl get pods -w # -w = watch (Ctrl+C pour arrêter)
Concept clé : Kubernetes est déclaratif et cherche en permanence à faire correspondre la réalité à ce que vous avez déclaré. Si vous supprimez un Pod, le Deployment en recrée un pour revenir à
replicas: 5. C'est le reconciliation loop.Question : Que se passe-t-il si vous déclarez
replicas: 0? Quelle utilité pratique cela a-t-il ?
5. Mise à jour et Rollback
5.1. Rolling Update
Modifiez l'image dans deployment.yaml :
kubectl apply -f deployment.yaml
# Observer la mise à jour progressive
kubectl rollout status deployment/mon-app
# Voir l'historique des révisions
kubectl rollout history deployment/mon-app
Kubernetes met à jour les Pods progressivement (un par un par défaut) en maintenant toujours des Pods disponibles pendant la transition.
5.2. Rollback
# Revenir à la révision précédente
kubectl rollout undo deployment/mon-app
# Revenir à une révision spécifique
kubectl rollout undo deployment/mon-app --to-revision=1
# Vérifier l'état après rollback
kubectl rollout status deployment/mon-app
kubectl get pods
Question : Comment Kubernetes garde-t-il trace des anciennes versions pour pouvoir faire un rollback ? Consultez
kubectl rollout history deployment/mon-app --revision=1.
6. ConfigMaps et Secrets
6.1. ConfigMap
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: "production"
APP_PORT: "3000"
APP_NAME: "Mon Application"
kubectl apply -f configmap.yaml
kubectl get configmap app-config
kubectl describe configmap app-config
Utiliser dans un Deployment :
containers:
- name: app
image: my-app:v1
envFrom:
- configMapRef:
name: app-config # Injecte toutes les clés comme variables d'environnement
6.2. Secret Kubernetes
# Créer un secret depuis la ligne de commande
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=supersecret
kubectl get secrets
kubectl describe secret db-credentials # La valeur n'est pas affichée
Ou en YAML (valeurs encodées en base64) :
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4= # echo -n "admin" | base64
password: c3VwZXJzZWNyZXQ= # echo -n "supersecret" | base64
Utiliser dans un Deployment :
containers:
- name: app
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
Attention Les Secrets Kubernetes sont encodés en base64, pas chiffrés. Toute personne ayant accès au cluster peut les lire. Pour une véritable sécurité en production, utilisez Sealed Secrets, HashiCorp Vault ou les solutions natives du cloud (AWS Secrets Manager, GCP Secret Manager).
7. Les commandes kubectl essentielles
| Commande | Description |
|---|---|
kubectl get pods |
Liste les pods du namespace courant |
kubectl get pods -o wide |
Liste avec nœud et IP |
kubectl get all |
Tous les objets du namespace |
kubectl get pods -n kube-system |
Pods dans un namespace spécifique |
kubectl describe pod <name> |
Détails et événements d'un pod |
kubectl logs <pod> |
Logs d'un pod |
kubectl logs -f <pod> |
Logs en temps réel |
kubectl exec -it <pod> -- sh |
Shell interactif dans un pod |
kubectl apply -f fichier.yaml |
Créer ou mettre à jour une ressource |
kubectl delete -f fichier.yaml |
Supprimer une ressource décrite dans un fichier |
kubectl delete pod <name> |
Supprimer un pod (le Deployment le recrée) |
kubectl scale deployment <n> --replicas=N |
Scaler un deployment |
kubectl rollout status deployment/<n> |
Statut d'un déploiement en cours |
kubectl rollout undo deployment/<n> |
Rollback vers la version précédente |
kubectl rollout history deployment/<n> |
Historique des révisions |
kubectl get events |
Événements du cluster |
kubectl config get-contexts |
Lister les contextes (clusters configurés) |
kubectl config use-context <name> |
Changer de cluster |
8. Nettoyage
# Supprimer les ressources créées
kubectl delete -f deployment.yaml
kubectl delete -f service.yaml
# Ou supprimer par nom
kubectl delete deployment mon-app
kubectl delete service mon-app-service
# Vérifier que tout est supprimé
kubectl get all
Conclusion
- Kubernetes est l'orchestrateur de référence pour la production cloud-native, plus puissant que Swarm mais plus complexe.
- Tout est déclaratif : vous décrivez l'état voulu dans des fichiers YAML,
kubectl applyfait le reste. - Les ressources fondamentales sont : Pod (unité de base), Deployment (gestion des réplicas et mises à jour), Service (exposition réseau), ConfigMap (configuration), Secret (données sensibles).
- Le reconciliation loop est au cœur de Kubernetes : si la réalité ne correspond pas à ce que vous avez déclaré, Kubernetes la corrige automatiquement.
- Pour les petits projets et le développement local, Docker Compose reste la solution la plus simple. Kubernetes prend tout son sens à partir du moment où vous gérez plusieurs services sur plusieurs machines en production.