Des applis qui se suicident quand elles deviennent obsolètes

Oct 16, 2023 min read

Lorsqu’on parle de mise en production d’une nouvelle version d’application, beaucoup d’équipes ont encore une floppée d’actions manuelles.

Avec un bon vieux plan de mise en prod, un pilote gère la montée de version, intervenant pour pousser une à une les nouvelles briques. Celà peut prendre une heure, une journée, voire plus, avec une durée variant sensiblement en cas de problème. On veut en général faire la mise à jour de la plateforme entière, qu’on ait 3 ou 180 applications à déployer.

L’erreur.

Quelle erreur. Quelle erreur de choisir de considérer toutes nos applications comme un seul bloc. On le fait souvent pour donner un fameux numéro de version à cette plateforme. On redéploie ce qui n’a pas changé, générant des risques inutiles d’erreur, tout ça pour mettre à jour un numéro. On se crée un travail monstrueux pour rien.

Aujourd’hui il existe le concept de micro-service. Tout le monde, ou presque l’a assimilé. Mais pourquoi diable déployer ensemble tous ces micro-services ? Souvent à cause d’un mauvais design. Ils sont interdépendants. On est passé d’un design ancien monolithique à un design de monolithe distribué.  Belle affaire.

Je dois mettre à jour une application, je commence où ?

Alors comment peut-on simplifier tout celà ? En rendant nos micro-services indépendants. Ils doivent avoir un cycle de mise à jour qui leur est propre. Ceci n’empêche évidemment pas de synchroniser la mise en prod de plusieurs composants participants ensemble à une fonctionnalité plus globale. On peut aussi déployer des fonctionnalités dormantes, déployées mais non-activées, et qui le seront rendues effectives toutes les briques seront prêtes.

Simplifier, c’est un gain de temps à long terme.

En simplifiant, on réduit les risques. On réduit le risques d’introduire des régressions sur des composants qui n’ont théoriquement pas subit de changement. On oublie également cette version globale qui obnubile beaucoup de release managers. On leur préférera des versions par micro-service, qui n’évolueront que lorsque celà sera parfaitement nécessaire.

Une fois celà fait, les mises en production deviennent un non-événement. Pas de cérémonie particulière, peu de personnes impliquées. Celà va vite. C’est efficace. En cas de pépins, le rollback est simplissime. Les compatibilités avec le reste de la plateforme et la nouvelle version sont pensées à l’avance et la plateforme dans sa globalité reste homogène au fur et à mesure que ses briques évoluent.

Ça commence à s’en approcher, n’est-ce pas ?

Pourquoi désormais attendre pour mettre en production ? Plus besoin d’empiler un certain nombre de features pour les lancer toutes ensemble dans le grand bain. Si nos tests sont fiables et optimisés, on peut remplacer une grosse mise en production d’un composant par quantité de plus petites, chacune comportant un risque moindre d’erreur. On diminue encore la complexité d’un rollback et le risque de la mise à jour.

C’est là où nous en arrivont à ce qui vous amène ici.

Bien surveiller ses applications

Je fais une petite aparté sur le monitoring. Toutes les plateformes d’avant-production et de production doivent être parfaitement surveillées. Des flux continus de métriques doivent alimenter des bases de données qui nous serviront à déterminer si nos composants se comportent correctement et si nos mises à jour n’ont pas fait augmenter les taux d’erreur ou dégradé les performances. C’est un prérequis à ce qui suit.

La surveillance des applications est essentielle pour automatiser leur cycle de vie

Je reprends, donc.

L’automatisation, la vraie

Dès lors que nos mises en production se font au fil de l’eau, que nos composants se mettent à jour grâce à notre chaîne d’intégration, avec des tests fiables qui nous assurent pleinement que nos composants sont opérationnels, et que notre production est suivie par des métriques, est-il nécessaire d’avoir quelqu’un pour appuyer sur le bouton ?

Et bien non. C’est là tout l’intérêt de cette simplification. La chaîne d’intégration va déclencher automatiquement la mise en production. En d’autres termes, la dernière action humaine aura été le push du développeur qui mettra à jour son code sur le serveur. Sa modification passera plusieurs étapes de test, avec même potentiellement des passages en plateforme de test à grande échelle, puis si les voyants sont tous au vert, la mise en production. Le rollback éventuel en cas de problème sera lui-même automatique, avec avertissement du développeur pour qu’il corrige son code avant de le re-soumettre.

Alors pourquoi l’application se suiciderait-elle ? Tout simplement que dans des environnements comme ceux d’aujourd’hui avec kubernetes, on se retrouve avec un nombre souvent énorme d’instances de la même application, souvent éparpillés sur des serveurs différents, datacenter différents, voire continents différents. Kubernetes (et d’autres) ont pour seule consigne de maintenir le nombre de ces instances au nombre désiré. Et donc si certaines se suicident en détectant qu’elles ne sont plus dans la bonne version, le système les échangera immédiatement contre une version à jour…

kubernetes est principalement là pour assurer le nombre des instances d’application à chaque instant

Il faudra évidemment veiller à ce que toutes les instances ne choisissent pas de se suicider en même temps. Un système de jetons, dont le nombre sera le nombre maximum d’instances que l’on peut renouveller en même temps, sera mis en place. Chaque instance réservera un jeton pour se terminer, et les nouvelles viendront le rendre. Un simple Key/value store du type redis ou consul peuvent être les garants de ces jetons.

Point de vue personnel sur la méthode

Je privilégie toujours l’autonomisation des instances applicatives. Leur laisser l’initiative de leur changements permet d’avoir une intelligence globale sans action humaine. Celà permet également une mise à l’échelle rapide et simplifiée. Certains diront qu’ils perdent le contrôle sur ce qui tourne en production. C’est faux. Un automatisme mis en place avec le concours de toutes les parties prenantes sera toujours plus efficient que de faire cycliquement un grand nombre d’actions manuelles.

Tout ce qui est décrit dans cette article peut paraître utopique pour certains, considérant leur quotidien. Mais il n’y a rien de magique. Ce niveau est atteignable dans la plupart des cas. Automatiser permet de s’améliorer itérativement. À chaque nouvelle erreur sa correction, et donc l’assurance qu’elle ne revienne pas. Chaque dépendance supprimée entre deux applications, c’est une problématique en moins pour les prochaines mises en ligne.

La plupart du temps, ceux qui disent que c’est impossible se donnent des excuses et se cachent derrière leur petit doigt….

Simplifier permet d’automatiser.

L’automatisation amène de la qualité.

La qualité libère du temps pour produire des fonctionnalités.

-|