Comment les priorités des pods dans Kubernetes ont causé des temps d'arrêt chez Grafana Labs

Noter. trad.: Nous présentons à votre attention des détails techniques sur les raisons du récent temps d'arrêt du service cloud maintenu par les créateurs de Grafana. Il s'agit d'un exemple classique de la façon dont une fonctionnalité nouvelle et apparemment extrêmement utile, conçue pour améliorer la qualité de l'infrastructure... peut causer des dommages si l'on ne prend pas en compte les nombreuses nuances de son application dans les réalités de la production. C’est formidable quand apparaissent des matériaux comme celui-ci qui vous permettent d’apprendre non seulement de vos 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 provoqué des 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 touchés par la panne. Notre travail consiste à fournir les outils de surveillance dont vous avez besoin, et nous comprenons que ne pas les avoir disponibles peut vous rendre la vie plus difficile. Nous prenons cet incident extrêmement au sérieux. Cette note explique ce qui s'est passé, comment nous avons réagi et ce que nous faisons pour garantir que cela ne se reproduise plus.

Préhistoire

Le service Grafana Cloud Hosted Prometheus est basé sur Cortex — Projet CNCF visant à créer un service Prometheus multi-locataire, évolutif horizontalement et hautement disponible. L'architecture Cortex est constituée d'un ensemble de microservices individuels, chacun remplissant sa propre fonction : réplication, stockage, requêtes, etc. Cortex est en développement actif et ajoute constamment de nouvelles fonctionnalités et améliore les performances. Nous déployons régulièrement de nouvelles versions de Cortex sur les clusters afin que les clients puissent profiter de ces fonctionnalités. Heureusement, Cortex peut être mis à jour sans temps d'arrêt.

Pour des mises à jour transparentes, le service Ingester Cortex nécessite une réplique Ingester supplémentaire pendant le processus de mise à jour. (Noter. trad.: Ingérer - le composant de base du Cortex. Son travail consiste à collecter un flux constant d'échantillons, à les regrouper en morceaux Prometheus et à les stocker dans une base de données comme DynamoDB, BigTable ou Cassandra.) Cela permet aux anciens ingesteurs de transmettre les données actuelles aux nouveaux ingesters. Il convient de noter que les Ingesters sont exigeants en ressources. Pour qu'ils fonctionnent, il faut disposer de 4 cœurs et de 15 Go de mémoire par pod, soit 25% de la puissance de traitement et de la mémoire de la machine de base dans le cas de nos clusters Kubernetes. En général, nous avons généralement beaucoup plus de ressources inutilisées dans le cluster que 4 cœurs et 15 Go de mémoire, nous pouvons donc facilement faire tourner ces ingesteurs supplémentaires lors des mises à niveau.

Cependant, il arrive souvent qu'en fonctionnement normal, aucune machine ne dispose de ces 25 % de ressources inutilisées. Oui, nous ne nous efforçons même pas : le CPU et la mémoire seront toujours utiles pour d'autres processus. Pour résoudre ce problème, nous avons décidé d'utiliser Priorités des pods Kubernetes. L'idée est de donner aux ingesteurs une priorité plus élevée que les autres microservices (sans état). Lorsque nous devons exécuter un Ingester (N+1) supplémentaire, nous déplaçons temporairement d’autres pods plus petits. Ces pods sont transférés vers des ressources libres sur d'autres machines, laissant un « trou » suffisamment grand pour exécuter un Ingester supplémentaire.

Le jeudi 18 juillet, nous avons déployé quatre nouveaux niveaux de priorité dans nos clusters : critique, haut, moyenne и faible. Ils ont été testés sur un cluster interne sans trafic client pendant environ une semaine. Par défaut, les pods sans priorité spécifiée sont reçus moyenne priorité, la classe a été définie pour les ingérants avec haute priorité. Critique était réservé au monitoring (Prometheus, Alertmanager, node-exporter, kube-state-metrics, etc.). Notre configuration est ouverte et vous pouvez consulter le PR ici.

Crash

Le vendredi 19 juillet, l'un des ingénieurs a lancé un nouveau cluster Cortex dédié pour un gros client. La configuration de ce cluster n'incluait pas les nouvelles priorités de pods, donc tous les nouveaux pods se voyaient attribuer une priorité par défaut : moyenne.

Le cluster Kubernetes ne disposait pas de suffisamment de ressources pour le nouveau cluster Cortex et le cluster Cortex de production existant n'a pas été mis à jour (les ingesteurs ont été laissés sans haute priorité). Puisque les Ingesters du nouveau cluster avaient par défaut moyenne priorité, et les pods existants en production fonctionnaient sans priorité du tout, les Ingesters du nouveau cluster ont remplacé les Ingesters du cluster de production Cortex existant.

ReplicaSet pour l'Ingester expulsé dans le cluster de production a détecté le pod expulsé et en a créé un nouveau pour conserver le nombre de copies spécifié. Le nouveau pod a été attribué par défaut moyenne priorité, et un autre « ancien » Ingester en production a perdu ses ressources. Le résultat fut processus d'avalanche, ce qui a entraîné le déplacement de tous les pods des clusters de production Ingester for Cortex.

Les ingesteurs sont avec état et stockent les données des 12 heures précédentes. Cela nous permet de les compresser plus efficacement avant de les écrire dans un stockage à long terme. Pour y parvenir, Cortex répartit les données entre les séries à l'aide d'une table de hachage distribuée (DHT) et réplique chaque série sur trois ingesteurs en utilisant la cohérence du quorum de style Dynamo. Cortex n'écrit pas de données sur les ingesteurs désactivés. Ainsi, lorsqu'un grand nombre d'Ingesters quittent le DHT, Cortex ne peut pas assurer une réplication suffisante des entrées, et celles-ci plantent.

Détection et correction

Nouvelles notifications Prometheus basées sur le « budget d'erreur » (basé sur le budget d'erreur — les détails apparaîtront dans un prochain article) a commencé à tirer la sonnette d'alarme 4 minutes après le début de l'arrêt. Au cours des cinq minutes suivantes, nous avons effectué des diagnostics et mis à l'échelle le cluster Kubernetes sous-jacent pour héberger à la fois les clusters de production nouveaux et existants.

Après cinq minutes supplémentaires, les anciens Ingesters ont réussi à écrire leurs données, les nouveaux ont démarré et les clusters Cortex sont redevenus disponibles.

Dix minutes supplémentaires ont été consacrées au diagnostic et à la correction des erreurs de manque de mémoire (MOO) provenant des proxys inverses d'authentification situés devant Cortex. Les erreurs MOO ont été causées par une multiplication par dix du QPS (nous pensons en raison de demandes trop agressives des serveurs Prometheus du client).

effets

Le temps d'arrêt total était de 26 minutes. Aucune donnée n'a été perdue. Les intégrateurs ont réussi à charger toutes les données en mémoire dans un stockage à long terme. Pendant l'arrêt, les serveurs clients Prometheus ont été supprimés en mémoire tampon (à distance) enregistrements utilisant nouvelle API écriture_distante basé sur WAL (écrit par Callum Styan de Grafana Labs) et a répété les écritures ayant échoué après le crash.

Comment les priorités des pods dans Kubernetes ont provoqué des temps d'arrêt chez Grafana Labs
Opérations d'écriture du cluster de production

résultats

Il est important de tirer les leçons de cet incident et de prendre les mesures nécessaires pour éviter qu’il ne se reproduise.

Avec le recul, nous n'aurions pas dû définir la valeur par défaut moyenne priorité jusqu'à ce que tous les Ingesteurs en production aient reçu haut une priorité. De plus, il fallait s'en occuper à l'avance élevé priorité. Tout est réglé maintenant. Nous espérons que notre expérience aidera d'autres organisations envisageant d'utiliser les priorités de pod dans Kubernetes.

Nous ajouterons un niveau supplémentaire de contrôle sur le déploiement de tout objet supplémentaire dont les configurations sont globales au cluster. Désormais, ces changements seront évalués bоplus de gens. De plus, la modification à l'origine du crash a été considérée comme trop mineure pour un document de projet distinct : elle n'a été abordée que dans un problème GitHub. Désormais, toutes ces modifications apportées aux configurations seront accompagnées d'une documentation de projet appropriée.

Enfin, nous automatiserons le redimensionnement du proxy inverse d'authentification pour éviter la surcharge du MOO dont nous avons été témoins, et examinerons les paramètres par défaut de Prometheus liés au repli et à la mise à l'échelle pour éviter des problèmes similaires à l'avenir.

L'échec a également eu des conséquences positives : après avoir reçu les ressources nécessaires, Cortex s'est automatiquement rétabli sans intervention supplémentaire. Nous avons également acquis une expérience précieuse en travaillant avec Grafana Loki - notre nouveau système d'agrégation de journaux - qui a permis de garantir que tous les ingesteurs se comportaient correctement pendant et après la panne.

PS du traducteur

A lire aussi sur notre blog :

Source: habr.com

Ajouter un commentaire