Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Rolling Updates et Rollbacks Kubernetes : mises à jour progressives

16 min de lecture

logo kubernetes

Comment mettre à jour une application en production avec un risque d’interruption minimal ? Kubernetes propose les rolling updates : vos nouveaux Pods démarrent progressivement pendant que les anciens sont supprimés. Si quelque chose se passe mal, un rollback déclenche un nouveau déploiement vers une révision précédente.

Ce guide vous montre comment configurer des mises à jour progressives fiables et revenir en arrière si nécessaire.

Prérequis : Deployments Kubernetes et kubectl configuré.

  • Déclencher une rolling update avec kubectl set image ou en modifiant le manifeste
  • Suivre la progression avec kubectl rollout status
  • Configurer la stratégie de déploiement (maxSurge, maxUnavailable)
  • Détecter un rollout bloqué avec progressDeadlineSeconds
  • Effectuer un rollback vers une version précédente
  • Consulter et annoter l’historique des révisions

Quand vous modifiez le Pod template (.spec.template) d’un Deployment, Kubernetes :

  1. Crée un nouveau ReplicaSet pour la nouvelle version
  2. Augmente progressivement le nouveau ReplicaSet
  3. Attend que les nouveaux Pods deviennent Ready, puis Available (si minReadySeconds est défini)
  4. Réduit l’ancien ReplicaSet au fur et à mesure
  5. Considère le rollout complet quand toutes les nouvelles réplicas sont disponibles et qu’aucune ancienne ne tourne

La façon la plus rapide de mettre à jour l’image :

Fenêtre de terminal
kubectl set image deployment/mon-app conteneur=image:nouvelle-version

Exemple :

Fenêtre de terminal
kubectl set image deployment/nginx-rolling nginx=nginx:1.25

Changez l’image dans votre fichier YAML :

deployment.yaml
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.25 # Anciennement 1.24

Puis appliquez :

Fenêtre de terminal
kubectl apply -f deployment.yaml
Fenêtre de terminal
kubectl edit deployment/mon-app

Modifiez l’image dans l’éditeur qui s’ouvre, puis sauvegardez.

Fenêtre de terminal
kubectl rollout status deployment/nginx-rolling

Sortie :

Waiting for deployment "nginx-rolling" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-rolling" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-rolling" successfully rolled out
Fenêtre de terminal
kubectl get pods -l app=nginx-rolling -w

Vous verrez les nouveaux Pods apparaître (ContainerCreatingRunning) et les anciens disparaître (Terminating).

Fenêtre de terminal
kubectl get rs -l app=nginx-rolling

Sortie :

NAME DESIRED CURRENT READY AGE
nginx-rolling-64757d479 0 0 0 5m # Ancien
nginx-rolling-7bf8c77b47 3 3 3 30s # Nouveau

L’ancien ReplicaSet reste (DESIRED=0) pour permettre un rollback.

deployment-strategy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-rolling
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Combien de Pods en plus pendant l'update
maxUnavailable: 1 # Combien de Pods peuvent être indisponibles
progressDeadlineSeconds: 600 # Timeout pour détecter un rollout bloqué
minReadySeconds: 10 # Attendre 10s après Ready avant de continuer
selector:
matchLabels:
app: nginx-rolling
template:
metadata:
labels:
app: nginx-rolling
spec:
containers:
- name: nginx
image: nginx:1.25
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
ParamètreValeur par défautDescription
maxSurge25%Nombre de Pods supplémentaires créés pendant l’update (au-delà de replicas)
maxUnavailable25%Nombre maximal de Pods pouvant être indisponibles pendant l’update

maxUnavailable contrôle combien de Pods peuvent être indisponibles (pas juste “non-Running”). Un Pod peut être Running sans être Ready ni Available — c’est la disponibilité qui compte, pas l’état Running.

ValeurEffet
maxUnavailable: 11 Pod peut être indisponible pendant l’update
maxUnavailable: 25%25% des Pods peuvent être indisponibles (arrondi à l’inférieur)
maxUnavailable: 0Aucun Pod ne doit devenir indisponible — rollout plus prudent mais plus lent

Mise à jour rapide (priorité à la vitesse) :

strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%

Mise à jour prudente (priorité à la disponibilité) :

strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0

Ce paramètre définit le délai après lequel Kubernetes considère que le rollout n’avance plus :

spec:
progressDeadlineSeconds: 600 # 10 minutes

Si le rollout n’a pas progressé pendant cette durée (pas de nouveau Pod Ready/Available), le contrôleur marque le Deployment comme failed dans son statut.

Vérifier le statut :

Fenêtre de terminal
kubectl describe deployment/nginx-rolling | grep -A 5 "Conditions"

Sortie si bloqué :

Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
Fenêtre de terminal
kubectl rollout status deployment/nginx-rolling --timeout=5m

La commande retourne un code d’erreur si le rollout échoue ou dépasse le timeout.

Pour certains cas très spécifiques, vous pouvez forcer un arrêt complet avant de recréer :

spec:
strategy:
type: Recreate

Un rollback déclenche un nouveau rollout vers une révision précédente. Ce n’est pas un basculement instantané — Kubernetes applique la même stratégie de rolling update pour revenir en arrière.

Fenêtre de terminal
kubectl rollout undo deployment/nginx-rolling

Sortie :

deployment.apps/nginx-rolling rolled back
Fenêtre de terminal
kubectl get deployment nginx-rolling -o jsonpath='{.spec.template.spec.containers[0].image}'
Fenêtre de terminal
kubectl rollout history deployment/nginx-rolling

Sortie :

REVISION CHANGE-CAUSE
1 Initial deployment
2 Upgrade vers nginx 1.25 pour CVE-2024-xxxx
3 <none>
Fenêtre de terminal
kubectl rollout undo deployment/nginx-rolling --to-revision=1
Fenêtre de terminal
kubectl rollout history deployment/nginx-rolling --revision=2

Pour garder une trace des raisons de chaque déploiement, annotez avec kubernetes.io/change-cause :

Fenêtre de terminal
kubectl annotate deployment/nginx-rolling \
kubernetes.io/change-cause="Upgrade vers nginx 1.25 pour CVE-2024-xxxx"

Ou définissez l’annotation dans le manifeste :

metadata:
annotations:
kubernetes.io/change-cause: "Upgrade vers nginx 1.25 pour CVE-2024-xxxx"

Par défaut, Kubernetes conserve 10 révisions (anciens ReplicaSets). Pour économiser de l’espace :

spec:
revisionHistoryLimit: 5
Fenêtre de terminal
kubectl rollout pause deployment/nginx-rolling

Utile pour :

  • Faire plusieurs modifications avant de reprendre (évite des rollouts intermédiaires)
  • Investiguer un problème sans que le rollout continue
Fenêtre de terminal
kubectl rollout resume deployment/nginx-rolling

Si vous modifiez à nouveau le Deployment pendant qu’un rollout est en cours, Kubernetes :

  1. Crée un nouveau ReplicaSet pour la dernière version
  2. Commence à abandonner le rollout précédent
  3. Scale down le ReplicaSet de la version intermédiaire

Exemple :

Fenêtre de terminal
# Rollout en cours vers v2
kubectl set image deployment/app app=image:v2
# Avant que v2 soit complètement déployé, vous changez pour v3
kubectl set image deployment/app app=image:v3

Kubernetes va progressivement abandonner v2 et passer directement à v3.

SituationRéglage conseillé
Priorité à la disponibilitémaxUnavailable: 0, maxSurge faible, readinessProbe, minReadySeconds
Priorité à la rapiditémaxSurge élevé (50%+), maxUnavailable non nul
Cluster contraint en ressourcesRolling update conservateur, maxSurge faible, éviter le surge
Application fragile au démarragereadinessProbe stricte, minReadySeconds élevé, progressDeadlineSeconds adapté
Déploiement bleu-vertmaxSurge: 100%, maxUnavailable: 0 (double temporaire des ressources)
Migration incompatibleStratégie Recreate ou StatefulSet

Sans readinessProbe, Kubernetes risque de considérer un Pod disponible trop tôt, ce qui peut dégrader le rollout et exposer des Pods non réellement prêts au trafic.

spec:
containers:
- name: app
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 3
failureThreshold: 3

Attendez quelques secondes après le Ready avant de continuer le rollout :

spec:
minReadySeconds: 10 # Le Pod doit être Ready pendant 10s avant d'être considéré Available

Détectez automatiquement les rollouts bloqués :

spec:
progressDeadlineSeconds: 600 # 10 minutes
Fenêtre de terminal
kubectl annotate deployment/app \
kubernetes.io/change-cause="Upgrade vers v2.1 - fix bug #1234"
spec:
revisionHistoryLimit: 5 # Pas 0, sinon pas de rollback possible
Anti-patternProblèmeSolution
Pas de readinessProbePods exposés avant d’être prêtsConfigurer une probe réaliste
revisionHistoryLimit: 0Impossible de faire un rollbackGarder au moins 3-5 révisions
Rollback sur Deployment pauséÉchoueReprendre d’abord avec resume
Supposer “zéro downtime” garantiLe rollout dépend de la config et des ressourcesConfigurer stratégie + probes + tests
Utiliser Recreate pour la persistanceInterruption de service, pas de garantie d’ordreUtiliser un StatefulSet
Modifier le selector après créationImmutable en apps/v1Recréer le Deployment si nécessaire
Enchaîner les apply sans vérifierRollover peut créer de la confusionAttendre rollout status entre les déploiements
SymptômeCause probableSolution
Rollout bloqué à “Waiting”Nouveaux Pods pas ReadyVérifier les logs et les probes
ProgressDeadlineExceededRollout n’avance plus depuis X secondesInvestiguer les Pods, éventuellement rollback
Pods en CrashLoopBackOffErreur dans la nouvelle imageRollback immédiat
Rollout très lentmaxUnavailable: 0 + ressources limitéesAugmenter maxSurge ou les ressources
Historique viderevisionHistoryLimit: 0Augmenter la limite
Rollback échoueDeployment pausékubectl rollout resume d’abord
Anciens Pods qui ne disparaissent pasterminationGracePeriodSeconds trop longRéduire ou vérifier que l’app gère SIGTERM
Fenêtre de terminal
kubectl describe pod nom-du-pod | grep -A 10 "Conditions"
kubectl logs nom-du-pod --previous
Fenêtre de terminal
kubectl describe deployment/nginx-rolling | grep -A 20 "Events"
Fenêtre de terminal
kubectl get deployment nginx-rolling -o jsonpath='{.status.conditions[*].type}'
  1. Déclencher une rolling update

    Fenêtre de terminal
    kubectl set image deployment/app app=image:v2
  2. Suivre la progression

    Fenêtre de terminal
    kubectl rollout status deployment/app
  3. Consulter l’historique

    Fenêtre de terminal
    kubectl rollout history deployment/app
  4. Rollback

    Fenêtre de terminal
    kubectl rollout undo deployment/app
    # Ou vers une révision spécifique
    kubectl rollout undo deployment/app --to-revision=2
  5. Vérifier les ReplicaSets

    Fenêtre de terminal
    kubectl get rs
    kubectl describe deployment/app
  6. Piège courant

    kubectl scale ne crée pas de nouvelle révision. Seules les modifications du Pod template déclenchent un rollout.

  1. Rolling update = mise à jour progressive avec interruption minimale si bien configurée
  2. Seules les modifications du Pod template déclenchent une nouvelle révision
  3. maxSurge et maxUnavailable valent 25% par défaut
  4. maxUnavailable: 0 = aucun Pod indisponible, mais nécessite plus de ressources
  5. progressDeadlineSeconds détecte les rollouts bloqués
  6. Un rollback déclenche un nouveau rollout vers une ancienne révision — ce n’est pas instantané
  7. Impossible de rollback un Deployment pausé — reprendre d’abord
  8. revisionHistoryLimit: 0 = pas de rollback possible
  9. Toujours configurer des readinessProbes et minReadySeconds
  10. Pour un vrai canary avec contrôle du trafic, utilisez Argo Rollouts ou un service mesh

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn