Rolling Update : Comment Déployer Sans Tout Mettre Hors Service d’un Coup
Imaginez la situation : votre application tourne sur cinq serveurs, tous en train de servir des utilisateurs. Vous devez déployer une nouvelle version contenant un correctif critique. L’approche traditionnelle consisterait à arrêter tous les serveurs, déployer la nouvelle version, puis tout redémarrer. Mais cela signifie une interruption de service. Chaque utilisateur verrait une page d’erreur ou un indicateur de chargement qui ne se termine jamais.
Cette méthode peut fonctionner pour des outils internes utilisés par une poignée de personnes à 3 heures du matin. Mais pour une application en production avec de vrais utilisateurs, tout arrêter d’un coup n’est pas envisageable. Vous avez besoin d’un moyen de mettre à jour le logiciel sans que tout le monde en ressente l’impact simultanément.
Le Problème : Déploiements Tout-ou-Rien
Lorsque vous remplacez toutes les instances de votre application au même moment, vous créez une fenêtre où rien ne sert le trafic. Même si le déploiement lui-même ne prend que quelques secondes, ces secondes peuvent signifier une perte de revenus, des utilisateurs frustrés ou des transactions échouées. Pour les applications qui nécessitent une haute disponibilité, cette fenêtre est inacceptable.
Le problème fondamental est que vous traitez tous vos serveurs comme une seule entité. Vous les arrêtez ensemble, vous les mettez à jour ensemble, et vous les redémarrez ensemble. Tout problème avec la nouvelle version affecte tous les utilisateurs en même temps. Si le déploiement échoue, vous vous précipitez pour restaurer l’ancienne version pendant que les utilisateurs voient déjà des erreurs.
La Solution : Remplacer une Instance à la Fois
Au lieu de tout mettre à jour en une fois, vous pouvez mettre à jour vos serveurs un par un. Voici comment cela fonctionne :
Le diagramme de séquence suivant montre comment un équilibreur de charge coordonne la mise à jour entre les instances :
- Vous avez cinq serveurs qui exécutent la version 1.0 de votre application.
- Vous retirez un serveur du service.
- Vous déployez la version 2.0 sur ce serveur.
- Vous vérifiez que la nouvelle version fonctionne correctement.
- Vous remettez ce serveur en service.
- Vous passez au serveur suivant et répétez l’opération.
À tout moment pendant ce processus, quatre serveurs exécutent encore l’ancienne version, et un serveur exécute la nouvelle version. Les utilisateurs qui tombent sur le serveur mis à jour reçoivent la nouvelle version. Ceux qui tombent sur les autres serveurs reçoivent l’ancienne version. Personne ne voit d’erreur car aucun serveur n’est complètement arrêté.
Cette approche s’appelle un rolling update (mise à jour progressive). Le nom vient de la façon dont la mise à jour « roule » sur vos instances les unes après les autres, comme une vague qui traverse un champ. Une instance est toute unité où votre application s’exécute : un serveur physique, une machine virtuelle ou un conteneur.
Pourquoi les Health Checks sont Essentiels
Un rolling update ne fonctionne que si vous pouvez déterminer si la nouvelle version s’exécute correctement avant de mettre à jour l’instance suivante. C’est là que les health checks entrent en jeu.
Un health check est un mécanisme simple qui teste si une instance est prête à recevoir du trafic. Il s’agit généralement d’un point d’accès comme /health ou /ready qui renvoie une réponse de succès lorsque l’application fonctionne normalement. Votre système d’orchestration – que ce soit Kubernetes, un équilibreur de charge ou un outil de déploiement personnalisé – vérifie ce point d’accès avant d’envoyer du trafic vers l’instance.
Si le health check échoue après le déploiement de la nouvelle version, le rolling update s’arrête. L’instance problématique peut être restaurée à l’ancienne version, et le reste de vos serveurs reste intact. Vous avez limité l’impact à une seule instance et à un petit sous-ensemble d’utilisateurs.
Sans health checks, vous avancez à l’aveugle. Vous pourriez mettre à jour les cinq serveurs avant de réaliser que la nouvelle version plante au démarrage. À ce moment-là, tous les utilisateurs sont affectés.
Quand les Rolling Updates Fonctionnent Bien
Les rolling updates sont idéaux pour les changements rétrocompatibles. Ce sont des changements où les versions ancienne et nouvelle peuvent fonctionner côte à côte sans problème. Exemples :
- Ajouter de nouvelles instructions de journalisation
- Corriger un bug mineur qui ne modifie pas les formats de données
- Modifier les couleurs ou le texte de l’interface utilisateur
- Ajouter un nouveau point d’accès API que personne n’utilise encore
- Mettre à jour une dépendance qui ne change pas le comportement
Étant donné que les instances anciennes et nouvelles s’exécutent simultanément pendant la mise à jour, la rétrocompatibilité est essentielle. Si la nouvelle version attend des données dans un format différent, ou communique avec d’autres services en utilisant un protocole différent, vous obtiendrez des erreurs lorsque les instances anciennes et nouvelles tenteront de travailler ensemble.
Les Compromis
Les rolling updates sont simples et ne nécessitent pas d’infrastructure supplémentaire. Vous utilisez les mêmes serveurs que vous avez déjà. Pas besoin de créer un environnement parallèle ou de provisionner une capacité supplémentaire. Vos coûts d’infrastructure restent les mêmes pendant la mise à jour.
L’inconvénient est la vitesse. Les rolling updates prennent du temps car vous devez attendre que chaque instance soit mise à jour et vérifiée. Si vous avez cinquante serveurs et que chacun prend une minute à déployer et à vérifier, votre mise à jour prend près d’une heure. Pour les correctifs de sécurité urgents, cela peut être trop lent.
Une autre limitation est la visibilité. Lorsqu’un rolling update introduit un problème, l’impact se propage progressivement. Certains utilisateurs voient le problème, d’autres non. Cela rend plus difficile l’isolation de la cause racine par rapport à des stratégies où vous pouvez clairement séparer les utilisateurs affectés des utilisateurs non affectés.
Une Checklist Pratique
Avant de mettre en œuvre un rolling update, assurez-vous d’avoir ces éléments de base en place :
- Point d’accès de health check : Votre application doit exposer un moyen fiable de vérifier qu’elle fonctionne.
- Rétrocompatibilité : La nouvelle version doit fonctionner aux côtés de l’ancienne version pendant la transition.
- Plan de rollback : Sachez comment restaurer une seule instance si le health check échoue.
- Supervision : Surveillez les taux d’erreur et les temps de réponse pendant la mise à jour pour détecter les problèmes tôt.
- Nombre suffisant d’instances : Les rolling updates fonctionnent mieux avec au moins trois instances. Avec seulement deux, vous perdez la moitié de votre capacité pendant la mise à jour.
Ce qu’il Faut Retenir
Les rolling updates sont la stratégie de déploiement par défaut pour la plupart des applications modernes car ils résolvent le problème fondamental de la mise à jour de logiciels sans interruption de service. L’idée est simple : ne remplacez pas tout d’un coup. Remplacez une instance, vérifiez qu’elle fonctionne, puis passez à la suivante. Cette approche maintient votre application disponible tout au long de la mise à jour et limite l’impact en cas de problème.
Pour les petits changements rétrocompatibles, les rolling updates sont souvent tout ce dont vous avez besoin. Ils sont simples, rentables et largement pris en charge par les plateformes d’orchestration de conteneurs comme Kubernetes et les outils de déploiement cloud. Mais pour les changements plus risqués – migrations de base de données, changements de protocole ou refontes majeures de fonctionnalités – vous pourriez avoir besoin de plus de contrôle. C’est là que des stratégies comme les déploiements blue-green ou les canary releases entrent en jeu. Mais c’est un sujet pour un autre article.