Filetable· Article 2 sur 3
Déployer en pleine journée : deux versions, une base, des onglets ouverts
Pendant quelques minutes, l'ancienne et la nouvelle version tournent côte à côte sur la même base. Et un onglet ouvert peut rester sur l'ancienne pendant des jours.
6 min de lectureRead in English
Filetable se met à jour souvent, en pleine journée, pendant que des clients travaillent. Personne ne doit perdre une saisie, voir une erreur ou devoir recharger à cause d'un déploiement.
Pourquoi Kubernetes
Filetable tourne en Suisse, sur un cluster Kubernetes managé. Kubernetes, l'orchestrateur de conteneurs open source né chez Google et confié à la CNCF, fait une chose très bien : on lui décrit l'état voulu (quelle image, combien de copies, quelles ressources) et il s'arrange pour l'atteindre, puis le maintenir. Un conteneur plante, il le relance. Une machine disparaît, il déplace le travail. Un gros lot de documents arrive, on ajoute des workers en changeant un chiffre.
Pour un déploiement, il remplace les pods un par un : un nouveau est prêt avant qu'un ancien parte, et le trafic passe de l'un à l'autre sans coupure. Mais Kubernetes ne sait rien de la compatibilité entre versions : pendant le déploiement, deux versions tournent en même temps, et c'est à l'application de le supporter.
Déploiement progressif
N et N+1 côte à côte : quelques minutesLe défi. Pendant quelques minutes, l'ancienne et la nouvelle version partagent une base que la nouvelle a déjà migrée. Et l'onglet ouvert hier exécute encore l'ancien JavaScript : il parle au nouveau serveur pendant des heures, parfois des jours.
Trois règles, dans les deux sens
Tout repose sur une discipline simple : chaque version doit fonctionner à côté de la précédente, sur la même base. Et dans les deux sens, car un retour arrière remet l'ancienne version devant des données écrites par la nouvelle.
Chaque version fonctionne à côté de la précédente
- 01
N+1 lit tout ce que N écrit
Ce qui la casse : Une migration de données ponctuelle : les lignes que N écrit après elle lui échappent.
- 02
N lit tout ce que N+1 écrit
Ce qui la casse : Une nouvelle valeur dans une liste fermée : l'ancienne version ne sait pas la lire.
- 03
Le schéma migré accepte toutes les requêtes de N
Ce qui la casse : Une colonne renommée : chaque écriture de N nomme encore l'ancienne, et échoue.
Un changement qui casse une règle se fait donc en plusieurs déploiements. C'est le schéma classique expand / contract : d'abord ajouter, puis basculer, et seulement à la fin retirer. Renommer une colonne, une seule ligne de SQL, en demande quatre :
Expand → contract
- AvantEn baseamount_textLe code écritamount_textLe code litamount_text
- Déploiement 1expandajouter, écrire les deuxEn baseamount_textamount_centsLe code écritamount_textamount_centsLe code litamount_text
- Déploiement 2datarecopier, puis lire la nouvelleEn baseamount_textamount_centsLe code écritamount_textamount_centsLe code litamount_cents
- Déploiement 3expandne plus écrire l'ancienneEn baseamount_textamount_centsLe code écritamount_centsLe code litamount_cents
- Déploiement 4contractsupprimer l'ancienneEn baseamount_centsLe code écritamount_centsLe code litamount_cents
Un pod qui part proprement
Ne couper personne, c'est aussi soigner la sortie de chaque pod. Kubernetes le retire du trafic, mais la gateway met un instant à l'apprendre : le pod doit continuer de servir un peu, puis finir ce qu'il a commencé, téléchargements compris, avant de s'éteindre.
Un pod qui s'arrête
- 1Retiré du trafic
Kubernetes ne lui envoie plus rien, mais la gateway met un instant à l'apprendre : il continue de servir.
- 2SIGTERM
Plus de nouvelle connexion. Les requêtes en vol finissent, téléchargements compris, puis le processus sort.
- 3SIGKILL
Seulement pour ce qui tournerait encore à la fin du délai de grâce.
Une connexion inactive, des deux côtés
L'onglet resté sur l'ancienne version
Un serveur se remplace en quelques minutes ; un onglet ouvert, non. À chaque échange, le serveur et l'onglet se disent donc de quelle version ils viennent. Le plus souvent, l'écart est sans danger.
Ce que l'onglet apprend du serveur
Nouvelle version, toujours compatible
Bannière discrète. L'onglet continue de fonctionner ; on recharge quand on veut.
Nouvelle version, incompatible
Dialogue bloquant. Rechargement automatique, jamais pendant qu'on tape.
Dans ce cas, une bannière discrète propose de recharger, quand on veut. Dans le cas rare où la nouvelle version casse l'ancienne, un dialogue bloque la page : mieux vaut l'arrêter que laisser quelqu'un taper ce qui ne pourra pas être enregistré.
Cette version de Filetable n’est plus compatible
Filetable a été mis à jour d’une manière que cette page ne peut pas suivre, et les modifications faites ici ne peuvent plus être enregistrées. Rechargez la page pour continuer avec la nouvelle version.
Sinon, elle se rechargera d’elle-même sous peu — jamais pendant que vous tapez.
onglet · version Aserveur · version B· compatible
Ce que j'en retiens
- Zéro coupure, c'est un contrat de compatibilité, pas un réglage de Kubernetes.
- Ajouter, puis retirer plus tard. Un ajout coûte un déploiement ; un renommage, quatre.
- Penser aux onglets ouverts : ce sont les plus vieux clients de l'application.
- Bloquer vaut mieux que perdre. Quand une écriture ne peut plus passer, le dire avant que quelqu'un tape.