Comment les priorités des pods dans Kubernetes ont causé une interruption chez Grafana Labs

Note de traduction.: Nous vous prĂ©sentons des dĂ©tails techniques sur les raisons de la rĂ©cente interruption du service cloud, gĂ©rĂ© par les crĂ©ateurs de Grafana. C'est un exemple classique de la façon dont une nouvelle fonctionnalitĂ©, apparemment trĂšs utile, conçue pour amĂ©liorer la qualitĂ© de l'infrastructure
 peut causer des dommages si les nombreux aspects de son utilisation en production ne sont pas pris en compte. Il est remarquable d'avoir des matĂ©riaux comme celui-ci, qui permettent d'apprendre non seulement de ses propres erreurs. Les dĂ©tails sont dans la traduction de ce texte du vice-prĂ©sident produit de Grafana Labs.

Comment les prioritĂ©s des pods dans Kubernetes ont causĂ© un temps d'arrĂȘt chez Grafana Labs

Le vendredi 19 juillet, le service Hosted Prometheus dans Grafana Cloud a cessé de fonctionner pendant environ 30 minutes. Je présente mes excuses à tous les clients qui ont souffert de cette panne. Notre objectif est de fournir les outils nécessaires à la surveillance, et nous comprenons que leur indisponibilité complique votre vie. Nous prenons cet incident trÚs au sérieux. Dans cette note, nous expliquons ce qui s'est passé, comment nous avons réagi et ce que nous faisons pour éviter que cela ne se reproduise.

Contexte

Le service Grafana Cloud Hosted Prometheus est basĂ© sur Cortex — un projet CNCF visant Ă  crĂ©er un service Prometheus Ă©volutif horizontalement, hautement disponible et multi-tenant. L'architecture Cortex se compose d'un ensemble de microservices distincts, chacun remplissant sa propre fonction : rĂ©plication, stockage, requĂȘtes, etc. Cortex est en dĂ©veloppement actif, avec constamment de nouvelles fonctionnalitĂ©s et une performance amĂ©liorĂ©e. Nous dĂ©ployons rĂ©guliĂšrement de nouvelles versions de Cortex dans les clusters afin que nos clients puissent bĂ©nĂ©ficier de ces fonctionnalitĂ©s - heureusement, Cortex peut ĂȘtre mis Ă  jour sans temps d'arrĂȘt.

Pour des mises Ă  jour sans temps d'arrĂȘt, le service Ingester de Cortex nĂ©cessite une rĂ©plique supplĂ©mentaire de l'Ingester pendant le processus de mise Ă  jour. (Note de traduction.: Ingester — le composant de base de Cortex. Sa tĂąche est de collecter un flux constant d'Ă©chantillons, de les regrouper en chunks Prometheus et de les stocker dans une base de donnĂ©es comme DynamoDB, BigTable ou Cassandra.) Cela permet aux anciens Ingester d'envoyer les donnĂ©es actuelles aux nouveaux Ingester. Il convient de noter que les Ingester sont gourmands en ressources. Pour leur fonctionnement, il est nĂ©cessaire de disposer de 4 cƓurs et de 15 Go de mĂ©moire par pod, c'est-Ă -dire 25 % de la puissance processeur et de la mĂ©moire de la machine de base dans le cas de nos clusters Kubernetes. En gĂ©nĂ©ral, nous avons souvent beaucoup plus de ressources inutilisĂ©es dans le cluster que les 4 cƓurs et 15 Go de mĂ©moire, nous pouvons donc facilement dĂ©ployer ces Ingester supplĂ©mentaires pendant les mises Ă  jour.

Cependant, il arrive souvent qu'aucune des machines n'ait ces 25 % de ressources non utilisées pendant le fonctionnement normal. Et nous ne cherchons pas à en avoir : le CPU et la mémoire seront toujours utiles pour d'autres processus. Pour résoudre ce problÚme, nous avons décidé de tirer parti de Kubernetes Pod Priorities. L'idée est d'attribuer aux Ingester une priorité plus élevée qu'aux autres microservices (sans état). Quand nous avons besoin de déployer un Ingester supplémentaire (N+1), nous déplaçons temporairement d'autres pods plus petits. Ces pods sont déplacés vers des ressources libres sur d'autres machines, laissant suffisamment de « trou » pour lancer l'Ingester supplémentaire.

Le jeudi 18 juillet, nous avons dĂ©ployĂ© quatre nouveaux niveaux de prioritĂ© dans nos clusters : critique, un, moyenne et basse. Ils ont Ă©tĂ© testĂ©s sur un cluster interne sans trafic client pendant environ une semaine. Par dĂ©faut, les pods sans prioritĂ© dĂ©finie avaient moyenne la prioritĂ©, une classe avec haute prioritĂ© a Ă©tĂ© attribuĂ©e aux Ingester. Critique Ă©tait rĂ©servĂ© Ă  la surveillance (Prometheus, Alertmanager, node-exporter, kube-state-metrics, etc.). Notre config est ouverte et le PR peut ĂȘtre consultĂ© ici.

Incident

Le vendredi 19 juillet, un des ingĂ©nieurs a lancĂ© un nouveau cluster Cortex dĂ©diĂ© pour un client majeur. La configuration de ce cluster n'incluait pas les nouvelles prioritĂ©s des pods, donc toutes les nouvelles pods se voyaient assignĂ©es la prioritĂ© par dĂ©faut — moyenne.

Le cluster Kubernetes manquait de ressources pour le nouveau cluster Cortex, et le cluster de production Cortex existant n'avait pas Ă©tĂ© mis Ă  jour (les Ingester sont restĂ©s sans haute prioritĂ©). Étant donnĂ© que les Ingester du nouveau cluster avaient par dĂ©faut moyenne la prioritĂ©, tandis que les pods existants en production ne disposaient d'aucune prioritĂ©, les Ingester du nouveau cluster ont Ă©cartĂ© les Ingester du cluster de production Cortex existant.

Le ReplicaSet pour l'Ingester évincé dans le cluster de production a détecté un pod évincé et a créé un nouveau pod pour maintenir le nombre de répliques défini. Le nouveau pod a été attribué par défaut moyenne une priorité, et un autre Ingester "ancien" dans la production a perdu des ressources. Le résultat a été un processus en cascade, qui a conduit à l'éviction de tous les pods avec Ingester pour les clusters de production de Cortex.

Les Ingester sont persistants et conservent des données pendant les 12 heures précédant. Cela nous permet de les compresser plus efficacement avant de les écrire dans un stockage à long terme. Pour cela, Cortex shard les données par séries, utilisant une table de hachage distribuée (DHT), et réplique chaque série sur trois Ingester avec une cohérence de quorum de style Dynamo. Cortex n'écrit pas de données dans les Ingester qui sont déconnectés. Ainsi, lorsque de nombreux Ingester quittent le DHT, Cortex ne peut pas assurer une réplication suffisante des enregistrements, et ceux-ci "échouent".

Détection et résolution

Les nouvelles alertes Prometheus basĂ©es sur le "budget d'erreurs" (error-budget-based — des dĂ©tails apparaĂźtront dans un futur article) ont commencĂ© Ă  tirer la sonnette d'alarme quatre minutes aprĂšs le dĂ©but de la dĂ©connexion. Au cours des cinq minutes suivantes, nous avons diagnostiquĂ© et amplifiĂ© le cluster Kubernetes sous-jacent pour hĂ©berger Ă  la fois les nouveaux et les anciens clusters de production.

Encore cinq minutes plus tard, les anciens Ingester ont réussi à écrire leurs données, tandis que les nouveaux ont démarré, et les clusters Cortex étaient à nouveau accessibles.

Dix minutes supplĂ©mentaires ont Ă©tĂ© nĂ©cessaires pour diagnostiquer et corriger des erreurs de type out-of-memory (OOM) des serveurs proxy inverses d'authentification situĂ©s devant Cortex. Les erreurs OOM Ă©taient causĂ©es par une augmentation dĂ©couragĂ©e du QPS (considĂ©rant que c'Ă©tait dĂ» Ă  des requĂȘtes excessivement agressives venant des serveurs Prometheus du client).

Conséquences

La durée totale de l'indisponibilité a été de 26 minutes. Aucune donnée n'a été perdue. Les Ingester ont réussi à charger toutes les données en mémoire dans le stockage à long terme. Pendant la déconnexion, les serveurs Prometheus des clients ont mis en mémoire tampon les (remote) enregistrements via la nouvelle API remote_write basée sur le WAL (créée par Callum Styan de Grafana Labs) et ont réitéré les enregistrements échoués aprÚs la panne.

Comment les prioritĂ©s des pods dans Kubernetes ont causĂ© un temps d'arrĂȘt chez Grafana Labs
Les opérations d'écriture du cluster de production

Conclusions

Il est important de tirer des leçons de cet incident et de prendre les mesures nécessaires pour éviter sa récurrence.

En repensant à cela, il convient de reconnaßtre que nous n'aurions pas dû définir par défaut moyenne la priorité tant que tous les Ingester étaient en production un en priorité. De plus, il aurait fallu prévoir à l'avance leur haute priorité. Maintenant, tout est corrigé. Nous espérons que notre expérience aidera d'autres organisations envisageant d'utiliser des priorités de pods dans Kubernetes.

Nous ajouterons un niveau de contrĂŽle supplĂ©mentaire sur le dĂ©ploiement de tout objet supplĂ©mentaire dont la configuration est globale au cluster. À l'avenir, de tels changements seront Ă©valuĂ©s pardeun plus grand nombre de personnes. En outre, la modification qui a conduit Ă  l'Ă©chec Ă©tait jugĂ©e trop insignifiante pour un document de projet distinct — elle n'a Ă©tĂ© discutĂ©e que dans un problĂšme GitHub. DorĂ©navant, tous les changements de configuration similaires seront accompagnĂ©s d'une documentation de projet appropriĂ©e.

Enfin, nous automatiserons le redimensionnement du serveur proxy inverse d'authentification pour éviter les OOM lors de la surcharge, que nous avons vécue, et analyserons les paramÚtres par défaut de Prometheus liés au rollback et au scaling, afin d'éviter à l'avenir des problÚmes similaires.

L'Ă©chec que nous avons rencontrĂ© a Ă©galement eu des consĂ©quences positives : ayant Ă  disposition les ressources nĂ©cessaires, Cortex s'est automatiquement rĂ©tabli sans intervention supplĂ©mentaire. Nous avons Ă©galement acquis une expĂ©rience prĂ©cieuse avec Grafana Loki — notre nouveau systĂšme d'agrĂ©gation de logs — qui a permis de s'assurer que tous les Ingester se comportaient correctement pendant et aprĂšs l'Ă©chec.

P.S. de l'auteur

Lisez aussi dans notre blog :

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster