Tous les articles

Journal

Ce qu'un cluster Kubernetes demande la semaine d'après la mise en production

Le 11 décembre 2024, un service de télémétrie a saturé tous les plans de contrôle Kubernetes d'OpenAI pendant 4 h 22, après un test de préproduction réussi. Voici ce qu'un cluster réclame chaque semaine, et ce que la mise en production ne teste jamais.

Le 11 décembre 2024, tous les services d'OpenAI ont été dégradés ou indisponibles pendant 4 h 22. La cause, dans les mots de leur post-mortem : « une nouvelle configuration de service de télémétrie qui a généré de façon inattendue une charge massive sur l'API Kubernetes de grands clusters, saturant le plan de contrôle et cassant la découverte de services par DNS ». Le changement avait été déployé la veille en préproduction et testé sans incident ; cinquante-trois minutes séparent sa fusion sur la branche principale du début de l'impact. La remise en service fut lente pour une raison qui mérite d'être lue deux fois : les ingénieurs avaient identifié le service fautif mais ne pouvaient plus atteindre le plan de contrôle pour le retirer, puisque c'est lui que ce service saturait.

Un post-mortem ne prouve rien sur votre cluster, et celui-ci décrit des clusters de plusieurs milliers de nœuds que presque personne n'exploite. Ce qu'il établit est un mécanisme : le coût de l'appel d'API croissait avec la taille du cluster, propriété qu'aucune préproduction ne pouvait révéler. Render en a publié six jours plus tard l'analyse générale : le serveur d'API n'est pas requis pour résoudre le DNS, mais il l'est pour l'initialiser, si bien qu'un plan de contrôle saturé empêche CoreDNS de redémarrer ; Render suppose ce mécanisme chez OpenAI sans l'affirmer, et nous le citons avec la même prudence.

Ce qu'un cluster coûte quand plus personne ne le regarde est un autre sujet, et nous y reviendrons. Cet article s'intéresse à ce que son exploitation exige : les pannes qui n'existent qu'en production et l'entretien que personne n'a inscrit à sa feuille de route.

Cinq pannes que le tutoriel ne montre pas

Une préproduction valide un comportement, pas une échelle, ni une durée, ni une concurrence. La moitié des propriétés d'un cluster n'existent qu'à sa taille réelle, et la compétence Kubernetes n'y change rien. Voici les cinq pannes que nous rencontrons le plus souvent, dans cet ordre et non par gravité.

1. Les 502 à chaque déploiement. La documentation décrit la course sans détour : en même temps que le kubelet entame l'arrêt du pod, le plan de contrôle évalue s'il faut le retirer des objets EndpointSlice. Le processus reçoit son SIGTERM pendant que ce retrait se propage à kube-proxy, au contrôleur d'entrée et aux caches des clients ; toute requête arrivant dans cette fenêtre atteint un listener en cours de fermeture. Le correctif est un preStop qui attend le délai de propagation, avec la subtilité que les recettes ratent : il est décompté à l'intérieur des 30 secondes de terminationGracePeriodSeconds, pas ajouté.

2. La limite CPU qui dégrade au lieu de protéger. Le noyau applique limits.cpu par quota CFS, sur une fenêtre de 100 ms par défaut. Une limite d'un cœur vaut 100 ms de temps CPU par fenêtre de 100 ms, tous threads confondus : une application à huit threads épuise son quota en 12,5 ms de temps mural, puis reste suspendue. On observe une latence en marches d'escalier, un CPU moyen à 25 % et aucune alerte, parce que c'est la moyenne que les tableaux de bord affichent. Il faut distinguer les deux cas : la limite mémoire, elle, est nécessaire, car elle s'applique par OOM kill. Notre règle : des requests partout, une limite mémoire partout, une limite CPU seulement là où l'on facture ou l'on arbitre un voisin bruyant. C'est une règle d'exploitation, pas une prescription : une politique uniforme se paie dans un sens comme dans l'autre, et l'effet du quota sur les charges sensibles à la latence se mesure avant de trancher.

3. etcd, si vous exploitez votre propre plan de contrôle. Le quota de base est de 2 GiB dans les versions courantes, mais il dépend de --quota-backend-bytes et de la version : vérifiez le vôtre plutôt que de supposer cette valeur. Au dépassement, etcd passe le cluster en mode maintenance où seules les lectures et les suppressions sont acceptées : plus de création de pod, plus de mise à jour de statut, plus de renouvellement de bail. Le cluster reste en ligne, mais il est paralysé. Second temps, moins connu : la compaction libère de l'espace pour etcd, pas pour le système de fichiers ; il faut défragmenter membre par membre, chacun indisponible pendant l'opération. Le vrai sujet n'est pas la sauvegarde, que tout le monde a, c'est la restauration dans un cluster neuf, que presque personne n'a exécutée.

4. L'absence de PodDisruptionBudget. kubectl drain respecte les PodDisruptionBudgets que vous avez déclarés, et seulement ceux-là : sans PDB, le drain évince d'un coup toutes les répliques co-localisées sur un nœud, ce que l'étalement par défaut autorise : il existe bien, à maxSkew: 3 sur l'hôte, mais en whenUnsatisfiable: ScheduleAnyway, un vœu et non une contrainte — valeurs par défaut du planificateur, à revérifier sur votre version. Le cas le plus grave est un PDB qui n'autorise aucune éviction volontaire : le drain ne termine jamais et transforme une maintenance d'une heure en incident de nuit.

5. La sonde de vivacité qui fabrique la panne qu'elle prétend guérir. Sous charge, la sonde HTTP passe derrière la même file que le trafic applicatif. Par défaut, timeoutSeconds: 1, failureThreshold: 3, periodSeconds: 10 : trente secondes de latence dégradée suffisent à faire tuer un pod sain, dont la charge part sur les survivants, qui dépassent à leur tour. La documentation porte l'avertissement : une implémentation incorrecte « peut conduire à des pannes en cascade ». Les deux sondes ne répondent pas à la même question : la vivacité décide s'il faut redémarrer le conteneur, la disponibilité s'il peut recevoir du trafic. Corollaire : une sonde de vivacité qui vérifie la base de données transforme une panne de base en redémarrage simultané de tous les pods.

Kubernetes évolue sans attendre

Kubernetes maintient les trois dernières versions mineures, environ quatorze mois chacune. Au 28 septembre 2026 : 1.37 publiée le 26 août 2026, 1.36 le 22 avril 2026, 1.35 le 17 décembre 2025, et tout ce qui précède en fin de vie amont. Ces numéros et ces dates vieillissent en quelques mois ; relisez la liste des versions au moment de planifier l'opération, pas au moment de lire cet article. Ce n'est pas une information de veille, c'est un abonnement : deux à trois mises à niveau du plan de contrôle par an, chacune suivie d'un roulement de nœuds et précédée d'un contrôle des API dépréciées dans vos manifestes et dans ceux de vos opérateurs.

L'année 2026 en a donné la démonstration. Le 11 novembre 2025, le projet annonçait la retraite de ingress-nginx en mars 2026 : plus de version, plus de correctif de bug, plus de correctif de sécurité. La déclaration du Steering Committee et du Security Response Committee, le 29 janvier 2026, ne laisse aucun doute : « rester sur Ingress NGINX après sa retraite vous laisse, vous et vos utilisateurs, vulnérables à une attaque. Aucune des alternatives disponibles n'est un remplacement direct. » Le composant équipait environ la moitié des environnements cloud native (télémétrie Datadog, donc base installée), et une ou deux personnes le maintenaient sur leur temps libre. Personne n'avait inscrit « remplacer le contrôleur d'entrée » à sa feuille de route 2026, et la moitié du marché a eu quatre mois.

Ce qui ne marche pas, et ce qui marche

Ce qui ne marche pas : la revue d'architecture unique avant la mise en production. Elle trie les décisions au moment où l'on en sait le moins, et ne revient jamais. Ce qui marche est ennuyeux, et c'est le même triptyque que pour les coûts : un propriétaire, un rendez-vous, une mesure. Une personne nommée, du temps réservé à chaque mise à niveau et une liste écrite des décisions qu'on ne peut plus défaire. L'exercice de restauration etcd appartient à ce rendez-vous, pas à la documentation.

Faut-il un cluster ?

Nous exploitons des clusters Kubernetes et c'est une expertise que nous vendons. Nous ne recommandons pas Kubernetes par défaut. Un cluster managé peut toutefois convenir à une petite équipe si ses développeurs savent déjà l'exploiter. Certaines offres managées proposent même une expérience proche du serverless : le fournisseur alloue et met à l'échelle les ressources des pods à partir de leurs besoins déclarés. Cela réduit la gestion des nœuds, sans supprimer les choix d'architecture ni le besoin de compétence Kubernetes. Aucune source neutre ne chiffre l'exploitation d'un cluster en jours-homme ; ce qui suit est notre estimation, dérivée du rythme amont et de nos missions. Parc managé, sans état, sans multi-tenant : 2 à 4 jours-homme par mois hors incident. Avec du stateful, plusieurs équipes et des environnements par branche : 4 à 8. Auto-géré, où vous possédez etcd, les certificats et le système des nœuds : 8 à 15, un plancher que le rythme amont fixe plus que votre trafic. Ce sont nos ordres de grandeur et non une norme : la charge réelle dépend de l'état du système, des exigences de disponibilité, du nombre d'équipes qui déploient et de ce que le fournisseur garde à sa charge. Ce coût d'exploitation se mesure en temps humain, pas en euros de facture, et c'est pourquoi il reste invisible jusqu'à l'incident.

Votre situationVerdict
Moins de dix services longue durée, une équipe qui déploie, le tout tient sur deux à quatre machinesPas forcément. Deux VM, systemd et un reverse proxy suffisent souvent ; un cluster managé reste pertinent si l'équipe a déjà la compétence Kubernetes et que le besoin le justifie.
Charge en rafales, pas d'état à garder, personne pour l'astreinteNon. Des conteneurs serverless.
Trois équipes ou plus qui déploient indépendamment, vingt à trente unités déployablesOui. L'orchestration coûte moins que la coordination humaine qu'elle remplace.
Charges de tailles inégales à empaqueter, ou du batch et du GPU à ordonnancerOui. Seul cas où le bin-packing rembourse à lui seul l'exploitation.
La même plateforme doit tourner sur cloud public, sur site et en cloud souverainOui, et c'est la meilleure raison.

Kubernetes est portable comme API ; une installation Kubernetes ne l'est pas. La dépendance au fournisseur vient de ses composants spécifiques : contrôleur d'entrée, pilote CSI, modèle d'identité et autoscaler de nœuds. Ces éléments doivent figurer dans tout plan de sortie et font partie des premiers points à tester.

Décider s'il faut ce cluster, et qui en porte l'exploitation, fait partie de ce qu'on peut déléguer à une direction technique, et de ce qu'on ne peut pas. Ce qu'il faut demander à qui exploite votre cluster, en revanche, ne tient pas en une certification. Plutôt : « montrez-moi la liste écrite des décisions de ce cluster qu'on ne peut plus défaire, et la date de sa dernière relecture. » Une équipe qui produit la liste a compris ce qu'elle exploite. Une équipe qui répond que tout est réversible n'a pas encore eu sa montée de version.

Sources

Prêt à reprendre la main sur votre technologie ?

Dites-nous où vous bloquez. Une vraie personne lit chaque message et répond sous 48 h ouvrées, avec une première piste concrète.

Nous contacter