Le scale-to-zero ne sait pas compter jusqu'à un
Le conseil était toujours le même. Votre trafic d'authentification arrive par pics. Votre cluster Kubernetes reste la plupart du temps silencieux. Azure Container Apps redescend à zéro et ne vous facture que ce que vous utilisez. Vous payez en permanence pour un cluster qui passe la majeure partie de sa vie à attendre.
Nous avons pris cela suffisamment au sérieux pour chiffrer correctement la migration. Puis nous l'avons abandonnée. Pas à cause du coût de la transition, ni à cause des démarrages à froid, bien que les démarrages à froid seuls auraient suffi. Nous l'avons abandonnée parce que le vocabulaire de la plateforme manque un nombre, et c'est le seul nombre qui intéresse réellement notre cœur d'authentification.
Le serverless compte jusqu'à zéro et jusqu'à N
Les runtimes à scale-to-zero connaissent deux nombres. Zéro, quand personne n'appelle. N, quand il y a des appels, avec N qui flotte selon la demande. Pour le traitement de requêtes sans état, ce vocabulaire est parfait, c'est pourquoi le conseil semble si juste. La plupart des backends web ont vraiment cette forme : chaque requête indépendante, chaque instance jetable, un trafic nul méritant une facture nulle.
La façade publique d'un système d'authentification ressemble également à cela. Points de terminaison de jetons, pages de connexion, JWKS. Sans état, en pics, compatible avec la mise en cache.
En dessous se trouve une couche qui n'est rien de tout cela.
Le nombre est un
Sous les points de terminaison, notre backplane exécute une couche de coordination. À tout moment, exactement une réplique détient le bail de leadership du cluster (un bail blob désormais, plus du gossip, mais c'est une histoire pour un autre article) et exécute les tâches singleton : le balayage de rétention, la passe de livraison des webhooks, le travail où deux exécutants simultanés signifient des effets de bord déclenchés en double et où zéro exécutant signifie que des choses, silencieusement, ne se produisent jamais.
Le nombre dont cette couche a besoin est un. Pas zéro quand il y a peu d'activité. Pas N en charge. Un, détenu en permanence, avec un transfert vérifiable lorsque le détenteur meurt. Le scale-to-zero n'a aucun moyen de dire « un, toujours ». Il peut dire « au moins un tant qu'il y a du trafic », ce qui est une promesse différente, et la différence entre ces deux promesses est exactement le mode de défaillance que l'élection de leader existe précisément pour prévenir.
C'est pourquoi le graphique d'utilisation nous mentait. Un cluster d'authentification silencieux n'est pas en train de ne rien faire. Il détient un bail, garde les clés de signature au chaud et se tient prêt à répondre à la prochaine validation de jeton en moins de dix millisecondes. Silencieux et inactif sont des états différents, et les tableaux de bord de facturation ne vous montrent que l'un des deux.
Vous pouvez le simuler, et c'est pire
Vous pouvez forcer « exactement un » sur un runtime serverless. Fixez le nombre minimum de répliques à un et vous avez acheté un serveur toujours actif sur une plateforme dont tout l'instinct est de vous retirer les instances silencieuses. Chaque événement de mise à l'échelle, chaque redémarrage initié par la plateforme, chaque bascule de révision devient une question de leadership dont vous ne choisissez pas le moment. Nous nous battrions contre le comportement fondamental du runtime pour préserver le nôtre, pour toujours, en payant pour ce privilège.
Et l'échec retombe sur la personne la plus mal placée. La requête qui paie un démarrage à froid est un humain en train d'essayer de se connecter. « Votre connexion a été lente parce que notre service d'authentification dormait » n'est pas une phrase à mettre en production.
La facture avait une solution ennuyeuse
Et l'argent qui a tout déclenché ? Un planificateur et un SKU ont suffi. Le cluster de développement se désalloue maintenant lorsque personne ne l'utilise, et le pool de nœuds est passé à un SKU moins cher. Un paragraphe, c'est tout ce que cela mérite, et c'est justement le point : « arrêter de payer pour l'inactivité » est un objectif, pas une architecture, et la majeure partie de cet objectif était atteignable avec une modification de configuration au lieu d'un changement de plateforme.
Le test de forme
La règle que nous avons retenue : faire correspondre le runtime à la forme réelle de la charge de travail, et non à son graphique de trafic. Le serverless récompense ce qui est sans état et intermittent. Il punit tout ce qui doit tenir un rôle continu et exclusif, et un cœur d'authentification qui protège les clés de signature et élit qui exécute les tâches destructrices est l'exemple le plus pur de ce second type que nous connaissions.
Nous ne sommes pas contre le serverless. Une grande partie de notre surface sans état s'y porterait très bien. Mais la couche qui doit compter jusqu'à exactement un reste sur une infrastructure ennuyeuse, toujours active et inspectable.
Cette couche est aussi précisément ce que vous cessez d'exploiter lorsque vous confiez l'authentification à Authagonal au lieu de faire tourner la backplane vous-même.