Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1216 minIntermédiaire

Stratégies de déploiement : blue-green, canary et rollback

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • comparer les stratégies de déploiement et choisir la bonne ;
  • mettre en place un blue-green ou un canari simple avec Nginx ;
  • utiliser un interrupteur de fonctionnalité ;
  • revenir en arrière vite et dans le bon ordre après un incident.

4 exercices corrigés1 schéma

Une stratégie de déploiement est la manière de remplacer l'ancienne version d'une application par la nouvelle en production : d'un seul coup, instance par instance, en basculant entre deux environnements (blue-green) ou en exposant d'abord une petite partie des utilisateurs (canary). Elle détermine la coupure de service, le risque pris et la vitesse du retour arrière (rollback). Ce chapitre compare ces stratégies, présente les interrupteurs de fonctionnalité, puis détaille comment revenir en arrière quand un déploiement se passe mal.

Recréation : arrêter, puis démarrer

La stratégie la plus simple : on arrête l'ancienne version, puis on démarre la nouvelle. C'est ce que fait docker compose up -d dans le script du chapitre 11.

  • Avantage : simple, une seule version tourne à la fois, aucune question de compatibilité entre versions.
  • Inconvénient : une coupure, de quelques secondes à quelques minutes, et un retour arrière qui demande un nouveau redémarrage.
  • Quand : une application interne, déployée hors des heures de travail ; un projet de BTS.

Déploiement progressif (rolling update)

L'application tourne sur plusieurs instances derrière un répartiteur de charge (load balancer). On remplace les instances une par une : on en retire une du répartiteur, on la met à jour, on vérifie qu'elle répond, on la remet, puis on passe à la suivante.

  • Avantage : pas de coupure, pas de matériel en plus.
  • Inconvénient : pendant le déploiement, les deux versions servent des utilisateurs en même temps ; elles doivent être compatibles (même API, même schéma de base). Un retour arrière refait le même chemin à l'envers, instance par instance.
  • Quand : c'est la stratégie par défaut de Kubernetes (réglages maxSurge et maxUnavailable d'un Deployment) et de Docker Swarm.

Bleu-vert (blue-green)

On maintient deux environnements de production identiques, le bleu et le vert. Un seul reçoit le trafic. On déploie la nouvelle version sur celui qui est au repos, on le teste tranquillement, puis on bascule tout le trafic d'un coup en changeant la configuration du répartiteur.

Sur un seul serveur, avec Nginx en frontal, le bleu peut écouter sur le port 3001 et le vert sur le port 3002. La bascule consiste à changer une ligne et à recharger Nginx, sans coupure :

nginx
# /etc/nginx/conf.d/sorbier-frais-upstream.conf
upstream sorbier_frais {
    server 127.0.0.1:3002;   # vert, en service ; le bleu (3001) garde l'ancienne version
}
bash
sudo nginx -t && sudo systemctl reload nginx   # vérifie la configuration, puis la recharge sans couper les connexions
  • Avantage : bascule instantanée, et retour arrière instantané : on rebascule vers l'environnement précédent, toujours démarré.
  • Inconvénient : deux environnements à maintenir (le double de ressources pendant le déploiement), et la base de données est généralement partagée : le nouveau schéma doit rester compatible avec l'ancienne version, d'où les migrations par expansion puis contraction (les migrations).
  • Quand : une application où une coupure coûte cher et où l'on veut un retour arrière en quelques secondes.

Canari (canary)

Le nom vient des canaris que les mineurs emportaient au fond des galeries : l'oiseau, plus sensible, signalait le gaz avant les hommes. On déploie la nouvelle version sur une petite partie de l'infrastructure, qui reçoit une petite part du trafic (1 %, 5 %, 10 %). On compare ses indicateurs (taux d'erreurs, temps de réponse) à ceux de l'ancienne version. Si tout va bien, on augmente progressivement la part (25 %, 50 %, 100 %) ; sinon, on retire le canari, et seule une petite partie des utilisateurs a été touchée.

Avec Nginx, des poids sur les serveurs de l'upstream suffisent pour un premier canari :

nginx
upstream sorbier_frais {
    server 127.0.0.1:3001 weight=9;   # ancienne version : 9 requêtes sur 10
    server 127.0.0.1:3002 weight=1;   # canari : 1 requête sur 10, soit 10 %
}
  • Avantage : le risque est limité à une fraction des utilisateurs, et la décision repose sur des mesures réelles.
  • Inconvénient : il faut une supervision fine, capable de comparer les deux versions, et un routage du trafic pondéré ; les deux versions coexistent longtemps.
  • Quand : des applications à fort trafic, où les mesures sont significatives. Les outils comme Argo Rollouts (Kubernetes) automatisent les paliers et le retour arrière selon les indicateurs.
Blue-greenrépartiteurbleuv2.3vertv2.4, testé100 %basculebase uniqueRetour arrière : rebasculer.Canaryrépartiteurv2.390 % du traficcanari v2.410 % du traficindicateurs bons :10 % → 50 % → 100 %erreurs en hausse :retrait du canariDécision sur des mesures réelles.
Blue-green bascule tout le trafic d'un coup entre deux environnements ; canary expose d'abord une petite part des utilisateurs

Comparer les stratégies

StratégieCoupureRessources en plusVersions simultanéesVitesse du retour arrièreComplexité
RecréationOui, courteAucuneNonLente (redéploiement)Très faible
ProgressiveNonFaibles (une instance de plus)Oui, pendant le déploiementMoyenneMoyenne
Bleu-vertNonUn environnement completNon (bascule franche)ImmédiateMoyenne
CanariNonFaiblesOui, longtempsRapide (retrait du canari)Élevée (supervision, routage)

Les interrupteurs de fonctionnalité

Un interrupteur de fonctionnalité (feature flag, feature toggle) est une condition dans le code, pilotée par la configuration, qui active ou désactive une fonctionnalité sans redéployer :

js
if (await drapeaux.estActif('export-pdf', utilisateur)) {
  routeur.get('/notes/:id/pdf', exporterPdf);
}

Ils séparent le déploiement de la mise à disposition : le code de l'export PDF part en production désactivé, avec les autres changements ; on l'active ensuite pour l'équipe comptable seulement, puis pour tout le monde. Si un problème apparaît, on coupe l'interrupteur en quelques secondes : c'est un retour arrière de la fonctionnalité, sans toucher au reste.

UsageExemple
Lancement progressifActiver l'export PDF pour 10 % des utilisateurs, puis 100 %
Coupe-circuit (kill switch)Désactiver l'appel au service de géolocalisation s'il est en panne
Fusion de code inachevéLe travail en cours est fusionné tous les jours sur main, mais reste invisible
Test A/BComparer deux versions d'un écran

Des outils libres (Unleash, GrowthBook) et le standard ouvert OpenFeature fournissent les interrupteurs, leur interface d'administration et leur historique. Un simple réglage dans la configuration suffit pour commencer. Le revers : chaque interrupteur ajoute un if ; on le supprime du code une fois la fonctionnalité stabilisée, sinon ils s'accumulent en dette technique.

Revenir en arrière : le rollback

Un retour arrière (rollback) remet en service la dernière version qui fonctionnait. Quand la production va mal après un déploiement, la règle est simple : d'abord rétablir le service, ensuite comprendre. On ne débogue pas en direct sur la production.

MéthodeCommentDuréeRemarque
Redéployer l'image précédentedeployer.sh sha-3f9c2e1 (ou le workflow ci-dessous)Une à deux minutesLa méthode de base, possible parce que chaque image est étiquetée et conservée
Rebasculer (bleu-vert)Remettre l'ancien environnement dans le répartiteurQuelques secondesL'ancien environnement doit être resté démarré
Retirer le canariRemettre son poids à 0Quelques secondesSeule une partie du trafic a été touchée
Couper un interrupteurDésactiver la fonctionnalitéQuelques secondesSi le problème est limité à cette fonctionnalité
Bouton de la plateforme ou de GitLabRollback (PaaS), Re-deploy d'un environnement (GitLab)Une à deux minutesMême principe : redéployer un artefact précédent
git revert puis pipelineUn commit qui annule le commit fautif, testé et déployé normalementLe temps du pipeline (10 à 20 minutes)Plus lent, mais tracé ; à faire après le retour arrière immédiat, pour que main ne contienne plus le défaut

Un workflow de retour arrière, lancé à la main avec la version voulue :

yaml
name: Retour arrière

on:
  workflow_dispatch:
    inputs:
      version:
        description: Étiquette de l'image à redéployer, par exemple sha-3f9c2e1
        required: true
        type: string
      environnement:
        description: Environnement cible
        type: choice
        options: [recette, production]
        default: production

permissions:
  contents: read

jobs:
  rollback:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environnement }}
    steps:
      - name: Vérifier l'étiquette
        env:
          VERSION: ${{ inputs.version }}
        run: |
          [[ "$VERSION" =~ ^(sha-[0-9a-f]{7}|[0-9]+\.[0-9]+\.[0-9]+)$ ]] || { echo "Étiquette invalide"; exit 1; }
      - name: Préparer la connexion SSH
        env:
          SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
          KNOWN_HOSTS: ${{ vars.DEPLOY_KNOWN_HOSTS }}
        run: |
          install -m 700 -d ~/.ssh
          printf '%s\n' "$SSH_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts
      - name: Redéployer
        env:
          VERSION: ${{ inputs.version }}
          DEPLOY_HOST: ${{ vars.DEPLOY_HOST }}
        run: ssh "deploy@$DEPLOY_HOST" "MIGRER=non /opt/sorbier-frais/deployer.sh $VERSION"

MIGRER=non dit au script de ne pas lancer les migrations : l'ancienne version ne connaît pas les migrations les plus récentes, déjà appliquées, et certains outils (Knex, par exemple) refusent alors de s'exécuter, ce qui ferait échouer le retour arrière lui-même. L'environnement production garde ses règles : un retour arrière en production demande aussi une approbation. La valeur saisie passe par une variable d'environnement et est vérifiée avant usage, comme toute donnée fournie par une personne (l'injection de script).

Et la base de données ? Revenir à l'ancien code est facile ; revenir à l'ancien schéma l'est beaucoup moins. Les migrations « descendantes » (down) qui suppriment une colonne détruisent les données écrites entre-temps. D'où trois règles : des migrations compatibles avec la version précédente (expansion, puis contraction), une sauvegarde avant chaque migration en production, et la restauration de cette sauvegarde seulement en dernier recours, en sachant qu'elle efface tout ce qui a été saisi depuis (sauvegarde et PRA).

Après l'incident : le post-mortem

Une fois le service rétabli, l'équipe écrit un court post-mortem : la chronologie (déploiement à 14 h 02, premières erreurs à 14 h 05, retour arrière à 14 h 11), l'impact (combien d'utilisateurs, combien de temps), la cause, et surtout les actions pour que cela ne se reproduise pas : un test ajouté, un contrôle de santé plus complet, une étape de pipeline en plus. Il est sans reproche (blameless) : on cherche ce qui, dans le processus, a laissé passer l'erreur, pas un coupable. C'est la même démarche que la gestion des incidents d'ITIL (gestion des incidents) et que le retour d'expérience après un incident de sécurité (réponse aux incidents).

Exercices

Exercice 1 sur 4 Choisir une stratégie Réussi À revoir

Quelle stratégie de déploiement conseilles-tu dans chaque cas ? Justifie.

  1. L'application de réservation de salles d'un lycée, utilisée de 8 h à 18 h, sur un seul serveur.
  2. Le site marchand d'une enseigne, qui ne peut pas se permettre une seconde de coupure et veut pouvoir revenir en arrière instantanément ; elle dispose de deux serveurs identiques.
  3. Une application mobile bancaire avec deux millions d'utilisateurs, dont l'équipe veut vérifier sur de vraies mesures qu'une nouvelle version ne dégrade rien.
  4. Une API qui tourne sur un cluster Kubernetes avec six répliques.
Voir la réponseMasquer la réponse de l'exercice 1
  1. Recréation, le soir ou tôt le matin : quelques secondes de coupure hors des heures d'utilisation ne gênent personne, et c'est la stratégie la plus simple.
  2. Bleu-vert : un serveur sert le trafic, l'autre reçoit la nouvelle version ; la bascule et le retour arrière sont instantanés. Condition : des migrations compatibles avec les deux versions.
  3. Canari : une petite part du trafic d'abord, avec comparaison des taux d'erreurs et des temps de réponse ; avec deux millions d'utilisateurs, 1 % représente 20 000 personnes, assez pour des mesures fiables.
  4. Progressive (rolling update), la stratégie par défaut d'un Deployment Kubernetes : les six répliques sont remplacées par petits groupes, sans coupure.

Tu avais trouvé ?

Exercice 2 sur 4 Les poids d'un canari Réussi À revoir

  1. Avec weight=9 pour l'ancienne version et weight=1 pour le canari, quelle part du trafic reçoit le canari ? Sur 2 000 requêtes, combien en reçoit-il ?
  2. Le canari renvoie une erreur sur 3 % de ses requêtes, l'ancienne version sur 0,2 %. Combien d'erreurs chacune produit-elle sur ces 2 000 requêtes ? Que décides-tu ?
  3. L'équipe préfère quatre instances de l'ancienne version et une instance canari, toutes de poids 1. Quelle part reçoit le canari ?
Voir la réponseMasquer la réponse de l'exercice 2
  1. 1 / (9 + 1) = 10 %, soit 2 000 × 0,10 = 200 requêtes.
  2. Canari : 200 × 0,03 = 6 erreurs. Ancienne version : 1 800 × 0,002 = 3,6 erreurs en moyenne. En nombre, l'écart paraît faible, mais le taux du canari est 15 fois plus élevé (3 % contre 0,2 %) : on retire le canari (poids 0) et on analyse ses journaux avant toute nouvelle tentative.
  3. 1 / (4 + 1) = 20 %. Pour un premier palier, c'est beaucoup ; des poids (par exemple 19 et 1, soit 5 %) permettent un départ plus prudent.

Tu avais trouvé ?

Exercice 3 sur 4 Remettre le retour arrière dans l'ordre Réussi À revoir

À 14 h 05, après le déploiement de sha-b7e21f4 en production, la supervision signale que 40 % des enregistrements de notes de frais échouent. Remets ces actions dans l'ordre :

a. Écrire le post-mortem et ajouter un test qui reproduit le problème. b. Lancer le workflow « Retour arrière » avec sha-3f9c2e1. c. Ouvrir une pull request avec git revert du commit fautif, ou avec un correctif. d. Vérifier que le taux d'erreurs revient à la normale. e. Prévenir les utilisateurs et l'équipe qu'un incident est en cours. f. Analyser les journaux de la version sha-b7e21f4 pour trouver la cause.

Voir la réponseMasquer la réponse de l'exercice 3

e, b, d, f, c, a.

On prévient (e) et on rétablit le service tout de suite (b), sans chercher la cause d'abord. On vérifie que le retour arrière a fonctionné (d). Ensuite seulement, on analyse calmement (f), on corrige dans main par une pull request testée (c), et on tire les leçons (a). Prévenir et rétablir peuvent se faire en parallèle si deux personnes sont disponibles ; dans tous les cas, l'analyse attend que les utilisateurs ne soient plus bloqués.

Tu avais trouvé ?

Exercice 4 sur 4 Interrupteur ou retour arrière ? Réussi À revoir

La version 2.6 de sorbier-frais contient trois changements : une correction de calcul des indemnités, une nouvelle page de statistiques, et l'export PDF, livré derrière l'interrupteur export-pdf, activé pour le service comptable. Le lendemain, l'export PDF fait planter le serveur quand une note contient plus de 50 lignes. Que fais-tu, et pourquoi ne fais-tu pas un retour arrière vers la 2.5 ?

Voir la réponseMasquer la réponse de l'exercice 4

On coupe l'interrupteur export-pdf : la fonctionnalité fautive disparaît en quelques secondes, sans redéploiement. Un retour arrière vers la 2.5 retirerait aussi la correction du calcul des indemnités et la page de statistiques, qui fonctionnent. Ensuite, on corrige l'export dans une pull request (avec un test sur une note de plus de 50 lignes), on déploie une 2.6.1, et on réactive l'interrupteur pour le service comptable.

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Publier une version : SemVer, tags et releasesRevoir le sommaire du cours