Chapitre 2 : Pods et Deployments¶
Objectifs du chapitre
- Décrire ce qu'est un Pod et les grandes étapes de son cycle de vie
- Expliquer le rôle des labels et des sélecteurs
- Expliquer la chaîne Deployment, ReplicaSet, Pods
- Décrire une mise à jour progressive (rolling update) et un retour arrière
- Acquis d'apprentissage visés : AA1, AA2
1. Le Pod¶
Le Pod est la plus petite unité que Kubernetes déploie et planifie. Il contient un ou plusieurs conteneurs qui partagent :
- la même adresse IP et le même espace de ports ;
- les mêmes volumes (chapitre 5).
Dans la grande majorité des cas, un Pod contient un seul conteneur. Les Pods à plusieurs conteneurs répondent à des besoins particuliers (chapitre 6).
Un Pod est éphémère : s'il est supprimé ou si son nœud tombe, il n'est pas réparé, il est remplacé par un nouveau Pod, avec un nouveau nom et une nouvelle adresse IP. C'est pourquoi on ne crée presque jamais de Pod isolé en production : on confie ce travail à un Deployment (section 4) et on utilise un Service pour obtenir une adresse stable (chapitre 3).
Cycle de vie¶
Le champ status.phase résume l'état d'un Pod.
| Phase | Signification |
|---|---|
Pending |
Le Pod est accepté, mais ses conteneurs ne sont pas encore démarrés (planification, téléchargement de l'image). |
Running |
Le Pod est placé sur un nœud et au moins un conteneur est en cours d'exécution. |
Succeeded |
Tous les conteneurs se sont terminés avec succès et ne seront pas relancés. |
Failed |
Tous les conteneurs sont terminés et au moins un a échoué. |
Unknown |
L'état ne peut pas être obtenu (par exemple, nœud injoignable). |
stateDiagram-v2
[*] --> Pending
Pending --> Running: image téléchargée, conteneur démarré
Running --> Succeeded: fin normale
Running --> Failed: fin en erreur
Succeeded --> [*]
Failed --> [*]
Le champ STATUS affiché par kubectl get pods est plus détaillé que la phase. Quelques valeurs à connaître pour le dépannage :
| Statut affiché | Cause fréquente |
|---|---|
ContainerCreating |
Image en cours de téléchargement, volume en cours de préparation |
ImagePullBackOff / ErrImagePull |
Nom ou tag d'image erroné, image inaccessible |
CrashLoopBackOff |
Le conteneur démarre, puis s'arrête en boucle : lire kubectl logs |
Completed |
Le conteneur s'est terminé normalement |
La politique de redémarrage (restartPolicy) indique ce que fait le kubelet quand un conteneur s'arrête : Always (valeur par défaut), OnFailure ou Never. Elle s'applique aux conteneurs du Pod, sur le même nœud : ce n'est pas le remplacement d'un Pod disparu.
2. Labels et sélecteurs¶
Un label est une paire clé-valeur attachée à un objet (app: web, tier: frontend). Les labels ne changent pas le comportement d'un objet : ils servent à le retrouver et à le regrouper.
Un sélecteur est une requête sur les labels. C'est le mécanisme qui relie les objets entre eux : un Deployment retrouve ses Pods, et un Service (chapitre 3) retrouvera les Pods à joindre.
kubectl get pods --show-labels
kubectl get pods -l app=web
kubectl get pods -l 'app=web,tier=frontend'
Attention
Un sélecteur qui ne correspond à aucun Pod, ou qui correspond à des Pods qui ne sont pas les bons, est l'une des erreurs les plus fréquentes. Choisissez des labels cohérents et distincts pour chaque application.
3. Le ReplicaSet¶
Un ReplicaSet garantit qu'un nombre donné de Pods identiques est toujours en fonctionnement. Il applique la boucle de réconciliation vue au chapitre 1 : si un Pod disparaît, il en crée un autre ; s'il y en a trop, il en supprime.
Il se compose de trois éléments : le nombre de réplicas souhaité, un sélecteur pour reconnaître ses Pods, et un modèle de Pod (template) pour en créer de nouveaux.
On manipule rarement un ReplicaSet directement : il est créé et géré par un Deployment.
4. Le Deployment¶
Un Deployment décrit l'état désiré d'une application sans état local : quelle image, combien de réplicas, comment mettre à jour. Il crée un ReplicaSet, qui crée les Pods.
flowchart TB
D["Deployment<br/>web (3 réplicas)"] --> RS["ReplicaSet<br/>web-7d9f..."]
RS --> P1["Pod web-7d9f...-abc12"]
RS --> P2["Pod web-7d9f...-def34"]
RS --> P3["Pod web-7d9f...-ghi56"]
Le nom des Pods reflète cette chaîne : <deployment>-<hash du modèle>-<suffixe aléatoire>.
Manifeste¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web # doit correspondre aux labels du modèle
template: # modèle de Pod
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.26-alpine
ports:
- containerPort: 80
Trois points à retenir :
spec.selectoretspec.template.metadata.labelsdoivent correspondre, sinon l'API refuse le Deployment ;- le sélecteur d'un Deployment ne peut plus être modifié après sa création ;
spec.templatea la même structure que la partiespecetmetadatad'un Pod.
Opérations courantes¶
| Besoin | Commande |
|---|---|
| Créer ou mettre à jour | kubectl apply -f web.yaml |
| Générer un squelette | kubectl create deployment web --image=nginx:1.26-alpine --dry-run=client -o yaml |
| Changer le nombre de réplicas | kubectl scale deployment web --replicas=5 |
| Changer l'image (rapide) | kubectl set image deployment/web web=nginx:1.27-alpine |
| Voir l'état | kubectl get deployment,replicaset,pods |
En pratique, modifiez de préférence le manifeste puis réappliquez-le : le fichier reste la source de vérité (approche déclarative).
5. Mises à jour progressives et retour arrière¶
Quand vous modifiez le modèle de Pod (par exemple l'image), le Deployment crée un nouveau ReplicaSet et déplace progressivement les Pods de l'ancien vers le nouveau. C'est le rolling update, la stratégie par défaut (RollingUpdate). Changer seulement le nombre de réplicas ne déclenche pas de mise à jour.
flowchart LR
A["RS v1 : 3 Pods<br/>RS v2 : 0 Pod"] --> B["RS v1 : 3 Pods<br/>RS v2 : 1 Pod"]
B --> C["RS v1 : 2 Pods<br/>RS v2 : 2 Pods"]
C --> D["RS v1 : 1 Pod<br/>RS v2 : 3 Pods"]
D --> E["RS v1 : 0 Pod<br/>RS v2 : 3 Pods"]
Deux paramètres règlent le rythme :
| Paramètre | Rôle | Valeur par défaut |
|---|---|---|
maxSurge |
Nombre de Pods supplémentaires autorisés pendant la mise à jour | 25 % |
maxUnavailable |
Nombre de Pods pouvant être indisponibles pendant la mise à jour | 25 % |
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # aucune baisse de capacité
Avec maxUnavailable: 0, Kubernetes ne supprime un ancien Pod qu'après avoir démarré un nouveau Pod. Pour que « prêt » ait un sens précis, Kubernetes utilisera les sondes de disponibilité, étudiées au chapitre 9.
L'autre stratégie, Recreate, supprime tous les anciens Pods avant de créer les nouveaux : elle provoque une coupure, mais convient quand deux versions ne doivent jamais coexister.
L'ancien ReplicaSet n'est pas supprimé : il est conservé à zéro Pod, ce qui permet le retour arrière.
| Besoin | Commande |
|---|---|
| Suivre la mise à jour | kubectl rollout status deployment/web |
| Voir l'historique | kubectl rollout history deployment/web |
| Revenir à la version précédente | kubectl rollout undo deployment/web |
| Relancer les Pods sans changer l'image | kubectl rollout restart deployment/web |
À retenir
- Un Pod est éphémère : s'il disparaît, il est remplacé, pas réparé.
- Les labels identifient les objets ; les sélecteurs les retrouvent.
- Deployment → ReplicaSet → Pods : on décrit le Deployment, les deux autres suivent.
- Une modification du modèle de Pod déclenche un rolling update ; l'ancien ReplicaSet est conservé pour le retour arrière.
maxSurgeetmaxUnavailablerèglent le compromis entre vitesse et disponibilité.- Premier réflexe de diagnostic :
get,describe(section Events),logs.
Pour vérifier votre compréhension¶
Pourquoi ne déploie-t-on pas directement des Pods isolés en production ?
Un Pod isolé n'est pas recréé s'il disparaît (suppression, panne du nœud). Un Deployment, via son ReplicaSet, maintient en permanence le nombre de Pods demandé.
Quel est le rôle du sélecteur d'un Deployment ?
Il indique quels Pods appartiennent au Deployment (via leurs labels). Il doit correspondre aux labels du modèle de Pod.
Vous passez replicas de 3 à 5. Un nouveau ReplicaSet est-il créé ?
Non. Seule une modification du modèle de Pod (image, par exemple) crée un nouveau ReplicaSet. Ici, le ReplicaSet existant crée 2 Pods supplémentaires.
Avec 3 réplicas, maxSurge: 1 et maxUnavailable: 0, combien de Pods existent au maximum pendant la mise à jour, et combien sont disponibles au minimum ?
Au maximum 4 Pods (3 + 1) ; au minimum 3 Pods disponibles, donc aucune baisse de capacité.
Un Pod est en ImagePullBackOff. Où chercher la cause ?
Dans kubectl describe pod <nom>, section Events : elle indique l'erreur de téléchargement (nom ou tag d'image incorrect, image inaccessible).