Tous les articles
·Ingénierie·9 min

Déploiements blue-green et canary : zéro downtime, risque maîtrisé

Blue-green, canary, rolling update : trois stratégies de déploiement qui changent radicalement le rapport au risque en production. Ce qu'elles font, comment les implémenter, et quand choisir l'une plutôt que l'autre.

Pousser du code en production le vendredi soir sans stresser : c'est le genre de confort que les stratégies de déploiement avancées rendent possible. Blue-green, canary, rolling update ne sont pas des buzzwords DevOps. Ce sont des réponses concrètes à un problème réel : comment livrer sans casser, et comment récupérer vite quand quelque chose se passe mal malgré tout.

Tableau de bord de monitoring avec métriques de déploiement en temps réel
Un déploiement canary bien instrumenté se pilote en temps réel via les métriques de taux d'erreur et de latence.

Le problème que ces stratégies résolvent

Un déploiement classique remplace l'ancienne version par la nouvelle d'un coup. Si la nouvelle version a un bug critique, 100 % des utilisateurs sont impactés immédiatement. Le rollback prend du temps, les logs sont pollués, et l'incident a déjà produit ses effets.

Les stratégies avancées découpent ce moment en plusieurs étapes contrôlées. L'idée centrale est toujours la même : ne jamais exposer 100 % du trafic à une version non validée en conditions réelles.

Rolling update : le point de départ

Avant de parler de blue-green et canary, il faut connaître le rolling update, qui est la stratégie par défaut de Kubernetes. C'est le minimum viable.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kreio-api
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # au plus 1 pod supplémentaire pendant la transition
      maxUnavailable: 0  # aucun pod indisponible à tout moment
  template:
    spec:
      containers:
        - name: api
          image: ghcr.io/kreio/api:v2.1.0

Kubernetes remplace les pods un par un. Avec maxUnavailable: 0, le trafic n'est jamais interrompu. C'est simple, c'est suffisant pour beaucoup de cas, mais ça a une limite importante : la v1 et la v2 coexistent pendant la transition. Si le schéma de base de données a changé, ou si un contrat d'API a été modifié de façon non rétrocompatible, on a un problème.

StratégieCoexistence versionsRollbackCoût infraComplexité
Rolling updateOui, pendant la transitionLentMinimalFaible
Blue-greenNonImmédiat×2Moyenne
CanaryOui, contrôléeProgressif+10-20 %Haute

Blue-green : le rollback en une commande

Le déploiement blue-green maintient deux environnements identiques en permanence : blue (la version en production) et green (la prochaine version). Le trafic pointe vers l'un ou l'autre via un service Kubernetes ou un load balancer. Le basculement est instantané.

# service.yaml — pointe vers blue ou green via le label selector
apiVersion: v1
kind: Service
metadata:
  name: kreio-api
spec:
  selector:
    app: kreio-api
    slot: blue   # ← changer en "green" pour basculer
  ports:
    - port: 80
      targetPort: 3000
# deployment-green.yaml — environnement green prêt mais pas encore actif
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kreio-api-green
spec:
  replicas: 4
  template:
    metadata:
      labels:
        app: kreio-api
        slot: green
    spec:
      containers:
        - name: api
          image: ghcr.io/kreio/api:v2.2.0

Le workflow de déploiement en pratique :

# 1. Déployer la nouvelle version sur green (sans toucher au trafic)
kubectl apply -f deployment-green.yaml

# 2. Attendre que tous les pods green soient prêts
kubectl rollout status deployment/kreio-api-green

# 3. Lancer les smoke tests sur l'environnement green
curl -f https://green.kreio.fr/api/healthz

# 4. Basculer le trafic (modification du label selector)
kubectl patch service kreio-api \
  -p '{"spec":{"selector":{"slot":"green"}}}'

# 5. Si problème : rollback en une commande
kubectl patch service kreio-api \
  -p '{"spec":{"selector":{"slot":"blue"}}}'

Le rollback est instantané parce que blue est toujours là, intact, avec la version précédente. On ne reconstruit rien, on redirige le trafic.

Intégration dans GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4

      - name: Build and push image
        run: |
          docker build -t ghcr.io/kreio/api:${{ github.sha }} .
          docker push ghcr.io/kreio/api:${{ github.sha }}

      - name: Deploy to green slot
        run: |
          kubectl set image deployment/kreio-api-green \
            api=ghcr.io/kreio/api:${{ github.sha }}
          kubectl rollout status deployment/kreio-api-green --timeout=120s

      - name: Smoke tests
        run: |
          sleep 10
          curl -f https://green.kreio.fr/api/healthz || exit 1

      - name: Switch traffic to green
        run: |
          kubectl patch service kreio-api \
            -p '{"spec":{"selector":{"slot":"green"}}}'

      - name: Promote green to blue
        run: |
          kubectl set image deployment/kreio-api-blue \
            api=ghcr.io/kreio/api:${{ github.sha }}

La dernière étape « promote green to blue » met à jour blue avec la nouvelle version une fois le basculement validé. La prochaine release utilisera blue comme slot actif et green comme slot de staging.

Canary : exposer progressivement

Le déploiement canary expose une fraction du trafic à la nouvelle version et augmente ce pourcentage progressivement selon les métriques observées. Si le taux d'erreur ou la latence dégradent, on stoppe et on rollback. Sinon, on monte à 100 %.

# deployment-canary.yaml — 1 pod canary pour 9 pods stable
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kreio-api-canary
spec:
  replicas: 1   # 1 pod = ~10 % du trafic si stable en a 9
  template:
    metadata:
      labels:
        app: kreio-api
        track: canary
    spec:
      containers:
        - name: api
          image: ghcr.io/kreio/api:v2.3.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kreio-api-stable
spec:
  replicas: 9
  template:
    metadata:
      labels:
        app: kreio-api
        track: stable
    spec:
      containers:
        - name: api
          image: ghcr.io/kreio/api:v2.2.0

Le Service sélectionne les deux deployments via le label app: kreio-api, sans distinction de track. Kubernetes répartit le trafic proportionnellement au nombre de pods.

Pour un contrôle plus fin (ex : envoyer exactement 5 % vers canary indépendamment du nombre de pods), on utilise Argo Rollouts ou un service mesh comme Istio qui pondèrent le trafic au niveau du proxy.

# argo-rollout.yaml — progression automatique avec analyse des métriques
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: kreio-api
spec:
  strategy:
    canary:
      steps:
        - setWeight: 5    # 5 % du trafic vers la nouvelle version
        - pause: { duration: 5m }
        - setWeight: 20
        - pause: { duration: 10m }
        - setWeight: 50
        - pause: { duration: 10m }
        - setWeight: 100
      analysis:
        templates:
          - templateName: error-rate
        startingStep: 1
        args:
          - name: service-name
            value: kreio-api

Ce que le monitoring doit couvrir pendant un déploiement

Une stratégie de déploiement sans observabilité est une stratégie aveugle. Les métriques à surveiller en temps réel pendant le basculement ou la montée en charge canary :

# Métriques Prometheus à monitorer via Grafana pendant le déploiement
- Taux d'erreur HTTP 5xx par version (label "track: canary" vs "stable")
- Latence p95 et p99 par version
- Taux de succès des health checks
- Nombre de redémarrages de pods (CrashLoopBackOff)
- Saturation CPU/mémoire par version

Un dashboard Grafana avec ces cinq métriques segmentées par version permet de détecter une régression en moins de deux minutes après le début du déploiement.

Gestion des migrations de base de données

C'est le point le plus souvent mal géré. Une migration qui supprime une colonne ou renomme un champ casse immédiatement la version précédente si elle est encore active. Avec blue-green ou canary, les deux versions coexistent : la migration doit être rétrocompatible.

Le pattern expand/contract en trois phases :

-- Phase 1 (release N) : ajouter la nouvelle colonne, garder l'ancienne
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);

-- Phase 2 (release N) : dual-write dans le code applicatif
-- L'application écrit dans "name" ET "full_name" pendant la transition

-- Phase 3 (release N+1) : lire depuis "full_name", backfill terminé
UPDATE users SET full_name = name WHERE full_name IS NULL;

-- Phase 4 (release N+2) : supprimer l'ancienne colonne en sécurité
ALTER TABLE users DROP COLUMN name;

Chaque phase est déployée séparément. Aucune migration ne casse la version précédente. C'est plus lent, mais c'est ce qui permet de rollback à tout moment sans perte de données.

Choisir la bonne stratégie selon le contexte

Rolling update convient quand la nouvelle version est rétrocompatible, que le budget infra est limité et que quelques minutes de rollback sont acceptables.

Blue-green convient quand on a besoin d'un rollback instantané, que l'environnement doit être validé en isolation avant basculement, et que le coût d'une double infrastructure est acceptable.

Canary convient quand on déploie sur un service à fort trafic, que l'équipe a une culture de l'observabilité en place (métriques, alertes, dashboards), et qu'on veut valider le comportement réel en production sur un échantillon avant d'aller plus loin.

Ce qu'on en retient

Les stratégies de déploiement avancées répondent à un besoin simple : livrer en production sans prendre de risque inutile. Rolling update est le socle minimal, blue-green donne un rollback instantané, canary permet de valider en conditions réelles sans exposer tous les utilisateurs.

La vraie difficulté n'est pas technique : c'est la discipline autour des migrations rétrocompatibles et de l'observabilité. Sans ces deux fondations, même la meilleure stratégie de déploiement ne protège pas d'un incident.

Sources

  1. Kubernetes Deployment Strategies — Documentation officielle
  2. Argo Rollouts — Canary et blue-green avec analyse automatique
  3. Parallel Change (Expand/Contract) — Martin Fowler