Stratégies de déploiement sans temps d'arrêt : assurez le fonctionnement de votre application pendant les mises à jour

Mettez en œuvre des déploiements sans temps d'arrêt avec des stratégies bleu-vert, continu et canari. Couvre les migrations de bases de données, les vérifications de l'état et les modèles de restauration automatisés.

E
ECOSIRE Research and Development Team
|16 mars 20268 min de lecture1.6k Mots|

Stratégies de déploiement sans temps d'arrêt : gardez votre application en cours d'exécution pendant les mises à jour

Les temps d'arrêt planifiés coûtent aux entreprises en moyenne 5 600 $ par minute. Pourtant, 43 % des entreprises continuent de mettre leurs applications hors ligne pendant les déploiements. Le déploiement sans temps d'arrêt n'est pas un luxe : c'est une attente. Les clients, les moteurs de recherche et les partenaires d'intégration pénalisent tous les applications qui se déconnectent, même brièvement.

Ce guide couvre les trois principales stratégies de déploiement sans temps d'arrêt, les techniques de migration de bases de données qui préservent la disponibilité et les mécanismes de restauration automatisés.

Points clés à retenir

  • Le déploiement bleu-vert est la stratégie la plus sûre : restauration instantanée en ramenant le trafic vers la version précédente
  • Les migrations de bases de données doivent être rétrocompatibles --- l'ancienne version de l'application doit fonctionner avec le nouveau schéma
  • Les contrôles de santé et les sondes de préparation empêchent d'acheminer le trafic vers des pods qui ne sont pas prêts à être servis.
  • La restauration automatisée basée sur la surveillance du taux d'erreur réduit le temps moyen de récupération à moins de 2 minutes.

Comparaison des stratégies

StratégieComplexitéVitesse de restaurationCoût des infrastructuresIdéal pour
Bleu-vertFaibleInstantané (secondes)2x pendant le déploiementApplications critiques, déploiements peu fréquents
Mise à jour continueMoyenProcès-verbal1,25x pendant le déploiementKubernetes, déploiements fréquents
CanariÉlevéRapide (secondes)1,05x pendant le déploiementTrafic élevé, sensible au risque
Indicateurs de fonctionnalitésMoyenInstantané1xDéploiement progressif des fonctionnalités

Déploiement bleu-vert

Architecture

Load Balancer
    |
    |--- [ACTIVE] Blue environment (v2.0.0) <-- receives 100% traffic
    |
    |--- [IDLE] Green environment (v2.1.0) <-- deployed, tested, waiting

Au déploiement :

  1. Déployez la version 2.1.0 dans l'environnement inactif (vert)
  2. Effectuez des tests de fumée contre le vert
  3. Basculez l'équilibreur de charge sur le vert
  4. Le bleu devient inactif (disponible pour une restauration instantanée)

Implémentation avec Nginx

# /etc/nginx/conf.d/app.conf
upstream blue {
    server 10.0.1.10:3000;
    server 10.0.1.11:3000;
}

upstream green {
    server 10.0.2.10:3000;
    server 10.0.2.11:3000;
}

# Active environment - change this during deployment
map $host $active_upstream {
    default blue;  # Change to 'green' to switch
}

server {
    listen 443 ssl;
    server_name app.example.com;

    location / {
        proxy_pass http://$active_upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Script de déploiement

#!/bin/bash
set -e

CURRENT=$(cat /etc/nginx/active-env)  # "blue" or "green"
TARGET=$( [ "$CURRENT" = "blue" ] && echo "green" || echo "blue" )

echo "Current: $CURRENT, deploying to: $TARGET"

# Deploy to inactive environment
ssh "deploy@$TARGET-1" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"
ssh "deploy@$TARGET-2" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"

# Wait for health checks
for i in 1 2; do
  echo "Checking $TARGET-$i health..."
  for attempt in $(seq 1 30); do
    if curl -sf "http://$TARGET-$i:3000/health" > /dev/null; then
      echo "$TARGET-$i is healthy"
      break
    fi
    sleep 2
  done
done

# Run smoke tests
pnpm test:smoke --base-url "http://$TARGET-1:3000"

# Switch traffic
sed -i "s/default $CURRENT/default $TARGET/" /etc/nginx/conf.d/app.conf
nginx -s reload
echo "$TARGET" > /etc/nginx/active-env

echo "Traffic switched to $TARGET. Rollback: change active-env back to $CURRENT"

Mise à jour continue

Les mises à jour progressives remplacent les instances de manière incrémentielle, garantissant ainsi qu'une certaine capacité est toujours disponible.

Mise à jour continue de Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Create 1 extra pod during update
      maxUnavailable: 0   # Never reduce below desired replicas
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:v2.1.0
          readinessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 15
            periodSeconds: 10

Le processus de mise à jour continue avec maxSurge: 1 et maxUnavailable: 0 :

  1. Créez 1 nouveau pod avec la v2.1.0 (6 pods au total : 5 anciens + 1 nouveau)
  2. Attendez que la nouvelle sonde de préparation du pod réussisse
  3. Terminez 1 ancien pod (5 pods : 4 anciens + 1 nouveau)
  4. Créez un autre nouveau pod (6 pods : 4 anciens + 2 nouveaux)
  5. Répétez jusqu'à ce que tous les pods soient v2.1.0

Déploiement Canary

Répartition du trafic

# Istio VirtualService for canary routing
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api-canary
spec:
  hosts:
    - api.example.com
  http:
    - route:
        - destination:
            host: api-stable
            port:
              number: 3001
          weight: 95
        - destination:
            host: api-canary
            port:
              number: 3001
          weight: 5

Déploiement progressif de Canary

PhasesTrafic aux CanariesDuréeCritères de réussite
11%10 minutesTaux d'erreur <0,1%, latence <500 ms
25%30 minutesTaux d'erreur <0,1%, latence <500 ms
325%1 heureTaux d'erreur <0,5%, latence <1s
450%2 heuresTaux d'erreur <0,5%, latence <1s
5100%Déploiement completStable pendant 24 heures

Migrations de bases de données sans temps d'arrêt

Le plus grand défi du déploiement sans temps d’arrêt réside dans les modifications du schéma de base de données. L'ancienne version de l'application doit fonctionner avec le nouveau schéma, et vice versa.

Le modèle d'expansion-contrat

Phase 1 : Développer (déployer le changement de schéma)

-- Add new column (nullable, no default)
ALTER TABLE orders ADD COLUMN shipping_method VARCHAR(50);

L'ancien code d'application ignore la nouvelle colonne. Le nouveau code d’application écrit dans les anciennes et les nouvelles colonnes.

Phase 2 : Migrer les données

-- Backfill existing data
UPDATE orders SET shipping_method = 'standard' WHERE shipping_method IS NULL;

Phase 3 : Contrat (code de déploiement qui utilise exclusivement la nouvelle colonne)

Après que toutes les instances d'application utilisent la nouvelle colonne :

-- Make column required
ALTER TABLE orders ALTER COLUMN shipping_method SET NOT NULL;
ALTER TABLE orders ALTER COLUMN shipping_method SET DEFAULT 'standard';

Modèles de migration dangereux

ModèleRisqueAlternative sûre
Renommer la colonneCasse l'ancien codeAjouter une nouvelle colonne, migrer, supprimer l'ancienne
Supprimer la colonneCasse l'ancien codeArrêtez d'utiliser, puis passez à la prochaine version
Ajouter une colonne NOT NULLTableau des serruresAjouter nullable, remplir, modifier en NOT NULL
Changer le type de colonneVerrouille la table, interrompt les requêtesAjouter une nouvelle colonne avec un nouveau type, migrer
Ajouter un index uniqueVerrouille la table sur les grandes tablesCREATE INDEX CONCURRENTLY

Restauration automatisée

Restauration basée sur le taux d'erreur

#!/bin/bash
# post-deploy-monitor.sh

DEPLOY_TIME=$(date +%s)
MONITOR_DURATION=300  # 5 minutes
ERROR_THRESHOLD=0.02  # 2%

while [ $(($(date +%s) - DEPLOY_TIME)) -lt $MONITOR_DURATION ]; do
  ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query?query=rate(http_requests_total{status=~'5..'}[2m])/rate(http_requests_total[2m])" | jq -r '.data.result[0].value[1]')

  if (( $(echo "$ERROR_RATE > $ERROR_THRESHOLD" | bc -l) )); then
    echo "ERROR: Rate $ERROR_RATE exceeds threshold $ERROR_THRESHOLD"
    echo "Initiating rollback..."
    kubectl rollout undo deployment/api
    exit 1
  fi

  sleep 15
done

echo "Deployment healthy for $MONITOR_DURATION seconds"

Questions fréquemment posées

Par quelle stratégie devrions-nous commencer ?

Commencez par le déploiement bleu-vert. C'est le plus simple à mettre en œuvre, il permet une restauration instantanée et fonctionne avec n'importe quelle architecture d'application. Les mises à jour progressives sont préférables pour les environnements Kubernetes comportant de nombreux réplicas. Les déploiements Canary sont destinés aux applications à fort trafic pour lesquelles vous souhaitez valider les modifications avec un trafic réel avant le déploiement complet.

Comment gérer les tâches en arrière-plan de longue durée pendant le déploiement ?

Utilisez un arrêt progressif. Lorsqu'un pod reçoit un signal de fin, arrêtez d'accepter de nouvelles tâches, terminez les tâches en cours (avec un délai d'attente), puis arrêtez-vous. Dans Kubernetes, configurez terminationGracePeriodSeconds pour laisser suffisamment de temps à l'exécution des tâches. Pour les tâches qui prennent plus de temps que le délai de grâce, utilisez une file d'attente de tâches (Redis, RabbitMQ) qui réessaye les tâches ayant échoué sur les travailleurs survivants.

Qu'en est-il des connexions WebSocket pendant le déploiement ?

Les connexions WebSocket durent longtemps et doivent être gérées avec soin. Lors d'une mise à jour continue, les connexions existantes sur l'ancien pod restent actives jusqu'à la fin du pod. Les clients doivent implémenter une logique de reconnexion automatique. Pour les déploiements bleu-vert, basculez les nouvelles connexions vers le nouvel environnement tout en permettant aux connexions existantes de s'écouler sur l'ancien environnement avec un délai d'attente.

Comment tester les déploiements sans temps d'arrêt ?

Exécutez un test de charge pendant le déploiement. Utilisez k6 ou un outil similaire pour générer un trafic continu, puis déclenchez un déploiement. Recherchez d’éventuelles erreurs, une latence accrue ou des connexions interrompues pendant le basculement. Consultez notre guide de test de charge pour plus de détails sur la mise en œuvre.


Ce qui vient ensuite

Un déploiement sans temps d'arrêt est une condition préalable à des versions fréquentes et fiables. Combinez-le avec automatisation CI/CD pour le pipeline de déploiement complet et surveillance pour la vérification post-déploiement.

Contactez ECOSIRE pour obtenir des conseils en stratégie de déploiement, ou explorez notre guide DevOps pour obtenir la feuille de route complète de l'infrastructure.


Publié par ECOSIRE – aider les entreprises à se déployer sans interruption.

E

Rédigé par

ECOSIRE Research and Development Team

Création de produits numériques de niveau entreprise chez ECOSIRE. Partage d'analyses sur les intégrations Odoo, l'automatisation e-commerce et les solutions d'entreprise propulsées par l'IA.

Discutez sur WhatsApp