Comment nous avons construit email.eu · Partie 5 sur 7

Une infrastructure reconstructible depuis un seul dépôt

Un cluster Kubernetes, une poignée de machines autonomes, tout en OpenTofu, et des déploiements qui sont des commits git. Pourquoi la moitié démodée de notre conception est délibérée, et quatre règles d'infrastructure qui tiennent sans exception.

Il existe un genre d'article d'infrastructure qui énumère un service mesh, trois fournisseurs d'observabilité, une histoire de bascule multi-cloud et une équipe plateforme, et se termine par « et voilà comment nous servons 4 000 utilisateurs ». Ce n'est pas cet article. Notre infrastructure est conçue pour être ennuyeuse, et cet ennui est porteur. Partie 5 de la série.

Tout tourne chez OVHcloud en France, ce qui, comme l'explique la partie 1, n'était pas un hasard. À l'intérieur, la plateforme a exactement deux formes.

Deux formes de calcul

Un cluster Kubernetes fait tourner la couche de coordination : la console sur app.email.eu, le site public, la page de statut, nos sondes et les tâches planifiées qui gardent la plateforme en ordre. Ce sont les composants que nous déployons souvent, et le cluster nous donne mises à jour progressives, auto-réparation et mise à l'échelle horizontale simple là où nous en avons besoin. À côté d'eux tournent nos bases Postgres, gérées par un opérateur, avec répliques et pooler de connexions, ce que la partie 4 a abordé sous l'angle des pannes.

Des machines virtuelles autonomes font tourner les piliers lourds : messagerie, stockage de fichiers, chat, réunions, édition de documents. C'est la moitié démodée de la conception, et elle est délibérée. Ces produits gardent un état, sont gourmands en disque et veulent des identités réseau stables ; l'adresse IP d'un serveur de messagerie fait partie de sa réputation. Ils se mettent à jour à leur propre rythme, pas au nôtre. Et les garder sur des machines distinctes garde les pannes distinctes : une mauvaise journée pour le serveur de fichiers est physiquement incapable d'affamer le serveur de messagerie en mémoire. Kubernetes achète sa magie avec une couche d'indirection que nous préférons ne pas glisser sous une file de courrier.

Le test que nous appliquons est simple. Ce composant gagne-t-il à être replacé automatiquement, ou préférerions-nous savoir exactement sur quelle machine il se trouve à trois heures du matin quand quelque chose cloche ? Les choses web passent le premier test. La messagerie passe le second.

Tout est du code

L'ensemble du parc, cluster, machines, DNS, répartiteurs, est déclaré dans OpenTofu, l'outil open source d'infrastructure-as-code, dans un seul dépôt. Les machines se configurent depuis des scripts rejouables, si bien que « monter un nœud de messagerie » n'est pas une page de wiki avec des étapes, mais un script qui produit le même résultat à chaque fois. Si une machine mourait irrémédiablement, nous la recréerions depuis le dépôt et non de mémoire.

Les secrets suivent le même principe avec une nuance : ils vivent chiffrés dans le dépôt (chiffrement age, clés détenues par des humains, jamais en clair dans git), et l'outillage de déploiement refuse d'appliquer quoi que ce soit si les secrets locaux ont divergé de la source de vérité chiffrée. Ce garde-fou existe parce que « quel portable a les bonnes variables » est la façon dont les équipes ont de gros accidents.

Les déploiements sont des commits git. Notre CI auto-hébergée sur ci.email.eu (la règle des fournisseurs européens vaut aussi pour l'infrastructure de compilation) construit chaque changement en une image étiquetée du commit exact qui l'a produite, et ces étiquettes sont immuables : une étiquette ne peut jamais se mettre discrètement à signifier autre chose. Mais compiler n'est pas livrer. Rien n'atteint la production parce que du code a été fusionné. Un déploiement est son propre commit d'une ligne, écrit et poussé par un humain, qui change l'image que la production exécute ; le pipeline applique exactement cette référence et attend que le déploiement soit sain. Cela a préservé les deux propriétés qui nous importaient quand déployer était une personne lançant un script : chaque déploiement est une décision humaine délibérée, et l'historique des déploiements est simplement l'historique git, si bien que revenir en arrière consiste à annuler un commit.

Les règles que nous suivons

Aucune de ces règles n'est exotique. Leur valeur tient à leur caractère absolu : elles tiennent quand vous êtes fatigué, quand vous êtes sûr, et quand vous êtes pressé, c'est-à-dire exactement quand elles sont nécessaires.

Pourquoi un client devrait s'en soucier

Parce que l'ennui capitalise en votre faveur. Moins de pièces mobiles signifie moins de modes de défaillance inédits, et une plateforme reconstructible depuis un seul dépôt signifie que notre scénario de catastrophe ne dépend de la mémoire de personne. Quand un fournisseur vous éblouit avec son architecture, il est légitime de demander qui paie l'excitation. Notre réponse est que personne ne devrait, nous l'avons donc retirée.

Ensuite, la partie 6 : comment nous surveillons tout cela, pourquoi notre page de statut affiche les mêmes chiffres que ceux qui nous alertent, et ce que nous avons construit pour les jours où quelque chose casse quand même.