Exécutez kubectl run nginx --image=nginx:1.27 et Kubernetes crée un seul Pod, nommé nginx. Supprimez-le avec kubectl delete pod nginx et il disparaît pour de bon — personne ne le remarque, personne ne le remplace. Un Pod est la plus petite unité déployable dans Kubernetes : un ou plusieurs conteneurs qui partagent un namespace réseau et un ensemble de volumes, planifiés ensemble sur un seul nœud.

Ce Pod isolé est une impasse en production. Si le conteneur qu’il contient plante, le kubelet le redémarre sur place. Si le nœud redémarre, ou si quelqu’un supprime le Pod, rien ne le recrée. Un Pod nu ne sait pas qu’il est censé continuer à exister.

Ce qu’un Deployment ajoute à un Pod

Un Deployment est un objet Kubernetes qui indique combien de copies d’un Pod doivent exister et comment déployer les changements sur elles. Vous arrêtez de gérer les Pods directement et vous décrivez l’état désiré ; une boucle de contrôle se charge de le rendre réel. C’est le même modèle de réconciliation qui est derrière tout le reste dans Kubernetes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web-app
          image: nginx:1.27
          ports:
            - containerPort: 80
1
2
kubectl apply -f web-app-deployment.yaml
kubectl get pods
1
2
3
4
NAME                       READY   STATUS    RESTARTS   AGE
web-app-7d9f8c7b86-4kxqz   1/1     Running   0          8s
web-app-7d9f8c7b86-9wj2p   1/1     Running   0          8s
web-app-7d9f8c7b86-x2p6t   1/1     Running   0          8s

Trois Pods, pas un seul, et aucun ne s’appelle web-app. Ce schéma de nommage (web-app-7d9f8c7b86-4kxqz) est le premier signe que quelque chose d’autre les gère.

replicas: 3 correspond à la même instruction que celle que vous donnez avec docker compose up --scale web=3 dans Docker Compose. La différence, c’est qu’ici un contrôleur continue à faire respecter ce nombre bien après la fin de l’exécution de la commande.

Comment un Deployment crée réellement les Pods : le ReplicaSet entre les deux

Un Deployment ne crée pas les Pods directement. Il crée un ReplicaSet, et c’est le ReplicaSet qui crée les Pods. Vous pouvez voir toute la chaîne :

1
2
3
kubectl get deployment web-app
kubectl get replicaset -l app=web-app
kubectl get pods -l app=web-app
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
web-app   3/3     3            3           2m

NAME                 DESIRED   CURRENT   READY   AGE
web-app-7d9f8c7b86   3         3         3       2m

NAME                       READY   STATUS    RESTARTS   AGE
web-app-7d9f8c7b86-4kxqz   1/1     Running   0          2m
web-app-7d9f8c7b86-9wj2p   1/1     Running   0          2m
web-app-7d9f8c7b86-x2p6t   1/1     Running   0          2m

Le nom du ReplicaSet est le nom du Deployment plus un hash du template de Pod (7d9f8c7b86) ; le nom de chaque Pod est le nom du ReplicaSet plus un suffixe aléatoire. kubectl describe pod web-app-7d9f8c7b86-4kxqz montre la relation directement, dans le champ Controlled By : ReplicaSet/web-app-7d9f8c7b86.

Supprimez l’un de ces Pods et le compteur descend à 2. En quelques secondes, un remplaçant apparaît. C’est le ReplicaSet qui remarque le manque et crée un nouveau Pod à partir du même template, pas le Deployment qui agit directement. Le ReplicaSet fait la surveillance. Le Deployment existe pour la seule chose qu’un ReplicaSet ne peut pas faire seul : remplacer un template de Pod progressivement plutôt que d’un coup.

Ce qu’un rollout fait aux ReplicaSets

Changez l’image et appliquez :

1
2
kubectl set image deployment/web-app web-app=nginx:1.27.1
kubectl rollout status deployment/web-app
1
2
3
Waiting for deployment "web-app" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "web-app" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "web-app" successfully rolled out

Derrière cette ligne de statut, le Deployment a créé un second ReplicaSet pour le nouveau template de Pod et l’a monté en charge tout en réduisant l’ancien. Avec la stratégie RollingUpdate par défaut sur 3 réplicas, cela revient à un Pod à la fois :

1
kubectl get replicaset -l app=web-app
1
2
3
NAME                 DESIRED   CURRENT   READY   AGE
web-app-7d9f8c7b86   0         0         0       6m
web-app-6b8f6d9c4d   3         3         3       40s

L’ancien ReplicaSet n’est pas supprimé. Il reste à zéro réplica, mais garde l’ancien template de Pod en mémoire. C’est ce qui rend le rollback rapide :

1
kubectl rollout undo deployment/web-app

Kubernetes remonte en charge l’ancien ReplicaSet et redescend le nouveau — sans reconstruction, sans nouveau pull d’une ancienne image si elle est encore en cache sur le nœud. kubectl rollout history deployment/web-app --revision=1 montre encore exactement quelle image exécutait cette révision.

Quand un Pod nu est le bon choix

Un Pod nu n’est pas une erreur dans tous les contextes, seulement dans la plupart :

  1. Un conteneur de diagnostic jetable que vous supprimerez dans cinq minutes : kubectl run debug --image=busybox -it --rm -- sh.
  2. Un Job ou un CronJob, qui crée des Pods via son propre contrôleur parce que le travail doit aller jusqu’à son terme plutôt que de rester actif.
  3. Inspecter ou étudier la spec du Pod elle-même, avant de l’envelopper dans quelque chose qui la gère.

Tout ce qui doit continuer à tourner après un plantage, une panne de nœud ou une mise à jour passe par un Deployment. Ou par un StatefulSet, pour les Pods qui ont besoin d’une identité stable et de leur propre stockage — un problème différent, et un objet différent. Écrivez le manifeste de Deployment par défaut et ne descendez à un Pod nu que dans les trois cas ci-dessus.

Pod, ReplicaSet et Deployment côte à côte

PodReplicaSetDeployment
Ce qu’il gèreConteneursPodsReplicaSets
Remplace une instance suppriméeNonOuiOui, via son ReplicaSet
Scale à N réplicasNonOuiOui
Rolling updatesNonNonOui
Rollback vers une version antérieureNonNonOui
Vous le créez directementRarementPresque jamaisNormalement

Comment vérifier si vos Pods ont un Deployment derrière eux

Exécutez ceci sur ce qui existe déjà dans votre cluster :

1
kubectl get deployment,replicaset,pod -l app=<votre-label>

Si seules des lignes de Pod reviennent, ce sont des Pods nus. C’est le manque à combler avant que le prochain drain de nœud n’emporte l’app avec eux.

Articles associés