Projet personnel
Volta : une plateforme Kubernetes construite de zéro sur OpenStack
Le problème
L’infrastructure cloud cache son coût physique. Un pod qui consomme 40 W ressemble exactement à un pod qui en consomme 4 : même tableau de bord, même coche verte, même ligne de facture noyée dans un agrégat. La capacité finit dimensionnée à l’intuition, et « il faudrait optimiser ça » reste une opinion, parce que ce qu’on optimise n’est jamais mesuré.
Volta comble cet écart à petite échelle. Le projet construit une plateforme complète à partir de rien, puis y ajoute le signal qui manque à la plupart des plateformes : les watts et les grammes de CO2eq attribués à chaque charge, à côté de ce qu’elle coûte réellement.
Deux contraintes
- Tout se détruit et se reconstruit. Une étape qui ne survit pas à un cycle complet de destruction et de reconstruction n’est pas finie.
- Chaque mesure annonce sa marge d’erreur. Une consommation mesurée dans une machine virtuelle est une estimation, et le dépôt le dit partout où il en rapporte une.
Survolez ou sélectionnez une brique pour en lire le détail.
Où en est le projet
La première phase est terminée. La plateforme se construit avec make up et se détruit avec make down : réseau privé et état chiffré, trois nœuds dans trois zones de disponibilité joignables par un bastion, cluster k3s amorcé en un seul apply, entrée HTTPS par un répartiteur Octavia, Traefik et cert-manager, Argo CD qui livre tout le cluster depuis le dépôt, Prometheus et Grafana. La CI vérifie chaque changement sans détenir aucun secret.
La sauvegarde est prouvée, et son périmètre est dit : Velero sauvegarde le namespace monitoring, avec l’historique de Prometheus, et sa restauration a été rejouée le 28 octobre, en trois minutes environ.
Reste la seconde phase : la consommation de chaque pod, un modèle carbone, des tableaux de bord décrits en code, et une optimisation mesurée avant et après. Mesurée dans une machine virtuelle, sans accès aux compteurs du processeur, la consommation sera une estimation, avec sa marge d’erreur.
Les décisions
Cinq décisions structurent la plateforme, chacune consignée dans un ADR avec les options écartées et pourquoi.
- k3s autogéré plutôt que Kubernetes managé : le service managé d’Infomaniak est moins cher et meilleur pour la production, mais l’amorçage du cluster fait partie de ce que le dépôt démontre. Un serveur par zone, etcd intégré : perdre une zone coûte un membre, pas le quorum.
- L’état dans Swift, sans verrou : la couche S3 de la plateforme refuse l’écriture conditionnelle qu’un verrou demande ; un seul opérateur et des plans enregistrés en tiennent lieu.
- Un bastion comme seule porte : aucun nœud n’a d’adresse publique, et la machine exposée ne fait pas partie du cluster.
- OpenTofu hors du cluster, Argo CD dedans : chaque ressource a un seul propriétaire.
- Construire depuis le poste, vérifier en CI : make up et make down tournent sur le poste ; la CI vérifie chaque changement, ne détient aucun secret, et chaque action y est épinglée à un commit.
Ce qui a cassé
Le dépôt tient la liste de ses pannes : la façon dont une plateforme tombe et se relève en dit plus sur elle que ce qu’elle fait un bon jour. Trois exemples.
Un verrou que la plateforme ne peut pas prendre. Avec le verrouillage de l’état activé, la planification échouait avant de commencer. OpenTofu prend ce verrou par une écriture conditionnelle, et Swift 2.30.1, qui sert l’API S3 ici, répond à toute écriture conditionnelle par 501 NotImplemented. Swift l’accepte à partir de la version 2.36.0 ; d’ici là, l’état n’a pas de verrou.
Une règle sur main qui laissait passer une pull request en échec. La règle qui protégeait main avait été enregistrée sans ses vérifications obligatoires. Une pull request de test, avec une clé en double dans les valeurs de Traefik, a échoué à ses vérifications et a été fusionnée quand même : Argo CD a fait de Traefik un Deployment à un seul réplica pendant six minutes, jusqu’au revert. Les vérifications sont désormais obligatoires.
Une destruction qui a oublié la moitié de la plateforme. make down a expiré sur l’interface du routeur. Deux serveurs, le bastion et le répartiteur de charge tournaient encore, sans demande de suppression, mais n’étaient plus dans l’état : il était passé de 91 à 43 Ko dès la première écriture de la destruction. Ils ont été supprimés à la main. La cause n’est pas trouvée ; ce qui reste est désormais listé après chaque destruction.