...

Visualisation de la surveillance PSI sous Linux avec Grafana : bien comprendre et surveiller la pression sur les ressources

Je montre comment linux psi les collecter avec Prometheus et les afficher dans Grafana afin de mesurer la pression exercée sur le processeur, la mémoire et les E/S en termes de temps d'attente réel. Cela me permet d'identifier Goulots d'étranglement dès le début, affectez-les à des cgroups ou à des conteneurs et déclenchez, si nécessaire, des mesures correctives automatisées.

Points centraux

  • Indicateurs PSI: « some/full » pour le processeur, la mémoire, les E/S et les moyennes mobiles
  • Focus sur les cgroups: une vision spécifique aux conteneurs et aux services, plutôt qu'une vision uniquement globale
  • Déclencheur d'alerte: Utilisation des événements liés aux seuils avec poll/epoll
  • Grafana: Tableaux présentant les tendances, les pics et les N principaux responsables
  • Meilleures pratiques: seuils, plages horaires, corrélation avec les métriques du système

Le PSI en bref : considérer la pression comme un temps d'attente réel

PSI répond à la question suivante : combien temps réel Les tâches attendent en vain le CPU, la RAM ou les E/S. Les fichiers se trouvent sous /proc/pressure/{cpu,memory,io,irq} offrent deux points de vue : some indique les phases au cours desquelles certaines tâches sont en attente, full indique les moments où toutes les tâches non inactives sont bloquées. J'évalue ces deux valeurs séparément, car some apparaît plus tôt et full met en évidence les véritables temps d'arrêt. De plus, j'utilise avg10, avg60 et avg300, afin de distinguer les fluctuations à court terme des tendances à plus long terme. Concernant la croissance au total- Je me rends compte à quel point la pression s'est accumulée depuis le départ et où Points chauds sont couchés.

PSI à l'échelle du système vs. PSI au niveau du cgroup : choisir le bon niveau

Je fais délibérément la distinction entre les valeurs de pression globales et la vue par cgroup. Les fichiers situés sous /proc/pressure/ présentent le système dans son ensemble, tandis que cgroup v2 offre en outre cpu.pressure, memory.pressure et io.pressure par groupe. Dans les environnements de conteneurs, cela me permet d’organiser proprement les pods, les services ou glanage . Cette classification évite de tâtonner : au lieu de devoir deviner, je repère immédiatement la source du problème au sein du groupe. Sur les hôtes multi-locataires, je sépare ainsi les charges partagées et dédiées et je gère Limites ciblés.

Vérifier les prérequis : activer le noyau, PSI et cgroup v2

Avant de collecter des indicateurs, je m'assure que la plateforme est adaptée :

  • Version du noyau: PSI est disponible à partir de Linux 4.20. Je vérifie avec uname -r et je vérifie via zcat /proc/config.gz | grep CONFIG_PSI, si la prise en charge est intégrée au code source.
  • Indicateur de durée PSI: Certaines distributions prennent en charge le drapeau de démarrage facultatif psi = 1, afin d'activer pleinement PSI. Je l'utilise si nécessaire et je vérifie que /proc/pressure/* fournit du contenu.
  • cgroup v2: Pour la vue par service/conteneur, j'utilise la hiérarchie unifiée. Je vérifie avec mount | grep cgroup2 et j'attends un cgroup2-Mount (souvent /sys/fs/cgroup). S'il manque, je l'active via le paramètre du noyau systemd.unified_cgroup_hierarchy=1 (Redémarrage nécessaire).
  • Autorisations: Les exportateurs sur l'hôte doivent disposer de droits de lecture sur /proc/pressure/* et, le cas échéant, sur /sys/fs/cgroup/*/*.pressure. Dans les conteneurs, je monte ces chemins en lecture seule.

Utiliser les déclencheurs PSI : réagir automatiquement au lieu de se contenter d'observer

Outre les séries chronologiques, je présente également des événements via sondage ou epoll en définissant des seuils et des plages horaires dans les fichiers PSI. Dès que la pression sur les ressources dépasse la valeur limite définie pour la plage, un événement se déclenche et je mets en place des mesures correctives. Il peut s'agir d'un pod supplémentaire, d'un vidage du cache ou d'une limitation temporaire d'un Tâches par lots . Dans les unités Systemd, j'associe directement cette réaction aux services et je limite les temps de latence. Ainsi, la surveillance devient un outil de contrôle, et pas seulement un moyen de Afficher.

Dans la pratique, j'utilise un programme « Watcher » compact qui gère les *pression*-fichiers, via write() un déclencheur (some ou full (y compris le seuil et la fenêtre en µs) puis traitée avec epoll qui attend les événements de manière bloquante. Cela me permet d'économiser des cycles de sondage et de réagir de manière déterministe. Je prolonge volontairement la durée des fenêtres (par exemple, de 10 à 30 s) afin de filtrer les transitoires, et je fais la distinction selon les ressources : mémoire réagit de manière plus sensible que io, CPU doit être plus net pour pouvoir tirer.

Exporter PSI vers Prometheus : agents, métriques, étiquettes

Pour les séries chronologiques, je collecte les données PSI à l'aide d'un exportateur dédié ou j'intègre les valeurs dans des agents existants tels que le Exportateur de nœuds. Il est essentiel d'utiliser des étiquettes cohérentes pour l'hôte, le cgroup et le conteneur afin que les requêtes dans Grafana puissent filtrer correctement les données. Dans Kubernetes, j'utilise également les métriques cAdvisor et Kubelet pour *_pression_*_temps_d'attente_en_secondes_total, afin que les niveaux des nœuds, des pods et des conteneurs restent alignés. Pour les hôtes classiques, je lis /proc/pressure/* directement et dans le dossier some et full sur des noms de métriques distincts. Un guide d'intégration des agents vous aidera à démarrer, par exemple à l'adresse Configurer Node Exporter.

Les variantes d'Exporter en détail : Node, cgroup et Kubernetes

J'utilise différentes méthodes en fonction du contexte :

  • Exportateur de nœuds (Niveau hôte) : J'active le pression-Collector (s'il n'est pas activé par défaut), par exemple via --collector.pressure. Il fournit des indicateurs tels que node_pressure_cpu_some_avg10, node_pressure_memory_full_avg60 et node_pressure_io_waiting_seconds_total{state="some|full"}. Ces dernières conviennent pour rate()-Analyses et Top-N.
  • Exportateur cgroup personnalisé (Niveau service/conteneur) : pour une vue très détaillée, je consulte /sys/fs/cgroup//{cpu,memory,io}.pressure et génère des indicateurs tels que cgroup_pressure_memory_waiting_seconds_total{state="full",cgroup="..."} ainsi que les avg10/60/300‑Gauges. Je normalise le chemin du cgroup en tant qu’étiquette (cgroup) ou dossier sur service/conteneur Étiquettes.
  • Kubernetes: Au niveau des nœuds, Prometheus effectue un scraping node-exporter. Pour la vue « Conteneurs », j'utilise un exportateur DaemonSet avec hostPID : true et les montages en lecture seule de /sys/fs/cgroup et /proc, afin de pouvoir consulter les fichiers cgroup de l'hôte. Je m'appuie également sur les métriques Kubelet/cAdvisor, dans la mesure où elles fournissent les totaux PSI ; les étiquettes espace de noms, pod et conteneur Je reste cohérent à cet égard.

Ce qui m'aide, c'est une Stratégie de marque: instance (nom d'hôte ou nom de nœud), cgroup (chemin d'), espace de noms/pod/conteneur (pour les K8) ainsi que état (some/full) et ressource (CPU/mémoire/io/irq). Cela me permet d'agréger fortement les données tout en effectuant un zoom approfondi.

Tâches Prometheus, règles d'enregistrement et exemples de requêtes

Pour obtenir des analyses claires, j'utilise deux modèles : les jauges de pourcentage (avg10/60/300) et dérivés rate()- Valeurs sur le *_nombre_total_de_secondes_d'attente_*‑compteurs.

  • Scrape: 15 secondes, c'est un bon début. Une durée plus courte augmente la charge, ce qui permet d'obtenir avg10 mais rarement une valeur ajoutée.
  • Règles d'enregistrement: Je calcule des séries chronologiques dérivées afin de simplifier les tableaux de bord et les alertes :
    • record : psi : node_memory_full : avg60 = avg_over_time(node_pressure_memory_full_avg10[60s])
    • record : psi : node_io_full : rate5m = rate(node_pressure_io_waiting_seconds_total{state="full"}[5m])
    • record : psi : cgroup_memory_full : rate5m = somme par (cgroup) (rate(cgroup_pressure_memory_waiting_seconds_total{state="full"}[5m]))

Avec PromQL, je crée des vues classiques :

  • Tendance des hébergeurs: node_pressure_memory_full_avg60 au fil du temps, par nœud.
  • Les N principaux responsables: topk(5, psi:cgroup_memory_full:rate5m) affiche les cgroups les plus bruyants.
  • Impact sur la latence: (augmentation(http_request_duration_seconds_sum[5m]) / augmentation(http_request_duration_seconds_count[5m])) contre node_pressure_io_full_avg60 établir, afin d'identifier des corrélations.
  • Reconnaître les plateaux: clamp_min(psi : node_io_full : rate5m, 0,0) sous forme de carte thermique par nœud.

Tableaux de bord Grafana : mettre en évidence les tendances et identifier les points sensibles

Dans Grafana, j'affiche séparément la charge du processeur, de la mémoire et des E/S, respectivement pour some et full sous forme de graphiques distincts. Les jauges à barres me fournissent l'état actuel, tandis que les panneaux de séries chronologiques mettent en évidence les pics et les plateaux. Pour l'analyse des causes, j'utilise les vues « Top-N » par cgroup, conteneur ou pod, et je passe de là aux panneaux de détail. La combinaison de avg10, avg60 et avg300, afin d'éviter les surcharges dues à de brèves pointes. Ceux qui souhaitent anticiper la conception de tableaux de bord trouveront des idées utiles concernant le Grafana et Prometheus Stack.

Les alertes dans la pratique : règles, fenêtres, escalade

Je m'en tiens à un modèle en deux étapes : avertissement pour les signaux précoces, Critique pour un goulot d'étranglement permanent. À titre d'exemple, je mets :

  • Mémoire
    • Avertissement : node_pressure_memory_full_avg60 > 0,01 pendant 10 à 30 s
    • Critique : node_pressure_memory_full_avg60 > 0,05 pendant ≥ 60 s
  • E/S
    • Avertissement : rate(node_pressure_io_waiting_seconds_total{state="some"}[5m]) > 0,02
    • Critique : node_pressure_io_full_avg60 > 0,02 pendant ≥ 120 s
  • CPU
    • Avertissement : node_pressure_cpu_some_avg60 > 0,05
    • Critique : node_pressure_cpu_full_avg60 > 0,01 (parce que full (ce qui fait particulièrement mal ici)

Dans les annotations, je relie des contextes (Top-cgroups, débit, latence) et je lance des playbooks : Scale-Up, ajustement des limites, actions de cache, limitation des lots. En cas d'événements récurrents, je privilégie les décisions relatives à la capacité.

Seuils et alertes : choisir le bon créneau horaire

Je définis des seuils clairs pour chaque ressource et je fais la distinction entre les pannes graves et les pics de charge de courte durée. Par exemple, j'évalue mémoire pleine plus de 5 % pendant plus de 60 secondes sont considérés comme critiques, tandis que 1 à 2 % pendant plus de dix secondes ne déclenchent qu'un avertissement. Pour le CPU, je définis des limites plus strictes full, car les temps d'attente généralisés y ralentissent sensiblement le système. L'association avec des indicateurs de débit et de latence apporte une valeur ajoutée : lorsque la pression augmente et que les requêtes ralentissent, l'urgence s'accroît. Je configure toujours les alertes en fonction de plages horaires, et non de valeurs ponctuelles, afin d'éviter les fausses alertes dues à Bursts d'éviter.

Kubernetes : configuration de la collecte de données, droits d'accès et corrélation

Dans le cluster, je collecte les PSI de manière à ce que les niveaux coïncident :

  • Node-Exporter en tant que DaemonSet: Le « Standard-Scrape » par nœud fournit des valeurs PSI globales.
  • cgroup-Exporter en tant que Sidecar/DaemonSet: Lit les fichiers cgroup v2 de l'hôte, attribue des étiquettes en fonction de espace de noms/pod/conteneur. J'utilise le strict minimum de droits et de montages RO.
  • Kubelet/cAdvisor: J'active l'affichage des métriques pertinentes des conteneurs et j'interroge le point de terminaison Kubelet. Je conserve les clés de jointure des étiquettes (par exemple,. conteneur vs. container_name) cohérente, afin que les jointures PromQL fonctionnent sans problème.
  • Join avec des métriques de charge de travail: Je compare les données Pod-PSI aux latences des applications (par exemple, les métriques HTTP), aux dépassements de limites CPU et aux erreurs de mémoire. Cela me permet de déterminer si le problème provient des limites, de la planification ou de goulots d'étranglement au niveau du stockage.

Fichiers PSI, indicateurs clés et interprétation : aperçu succinct

Le tableau suivant récapitule les principaux fichiers, indicateurs clés et utilisations, afin de me permettre d'interpréter plus rapidement les données et de créer des tableaux de bord Grafana adaptés. Je m'en sers lors de l'analyse pour déterminer la prochaine étape : optimisation, mise à l'échelle ou dépannage. Les différences entre some et full ainsi que les trois fenêtres de moyenne. Cela me permet de classer les symptômes par ordre chronologique et de vérifier si la pression est localisée ou généralisée. La colonne „ Intervention “ permet de Classement.

Ressource Fichier Chiffres clés Signification Utilisation
CPU /proc/pressure/cpu some, full ; avg10/60/300 ; total Temps d'attente pour obtenir du temps de calcul disponible Hôtes surchargés, CPU trop sollicitéLimites
Mémoire /proc/pressure/memory some, full ; avg10/60/300 ; total Temps d'attente dû à Reclaim, Swap, niveau proche de OOM Manque de mémoire vive, pression sur le cache, défaillances Requêtes
E/S /proc/pressure/io some, full ; avg10/60/300 ; total Temps d'attente sur les périphériques de stockage/le système de fichiers Supports de données lents, pics de synchronisation, Flush-phases
IRQ /proc/pressure/irq some, full ; avg10/60/300 ; total Impression via le traitement des interruptions Charge du réseau, optimisation des pilotes, Affinity
cgroup */{cpu,memory,io}.pressure some, full ; avg10/60/300 ; total Pression par service/conteneur Recherche des causes profondes, ciblée Limites

En pratique : sécuriser efficacement l'hébergement et les piles WordPress

Sur les serveurs WordPress très sollicités, PHP-FPM, la base de données et la couche de mise en cache se disputent régulièrement la mémoire vive et les E/S, ce que je constate via mémoire et io je le vois tout de suite. Ça monte full En ce qui concerne la mémoire, j'optimise l'OpCache, j'augmente les tailles des pools de manière mesurée ou je réduis les plugins gourmands en ressources. En cas de pression sur les E/S, je vérifie les plans de requêtes, les paramètres de journalisation et l'écriture asynchrone. PSI par cgroup permet de déterminer si le goulot d'étranglement est causé par le serveur web, les workers ou la base de données. Ceux qui souhaitent approfondir le sujet trouveront des indications dans le Guide Linux-PSI, qui résume la mise en route et l'évaluation.

Planification des capacités et optimisation : des chiffres à l'action

J'associe les indicateurs PSI à l'utilisation du processeur, aux erreurs de page, au débit d'E/S et aux latences afin d'identifier les véritables causes. En cas de persistance mémoire pleine Je redimensionne la mémoire vive, j'optimise les paramètres de récupération ou je répartis les charges de travail. Affiche io complet En cas de longues files d'attente, j'augmente la profondeur des files d'attente, j'active des stratégies de « write-back » ou j'utilise des supports de stockage plus rapides. En cas de pression sur le processeur, je mesure en parallèle la longueur des files d'attente d'exécution, j'ajuste les classes de planification et je répartis les threads les plus sollicités. Je ne prends de décisions que lorsque les tendances dans le avg60 et avg300 rester cohérent et ne pas se contenter d'un simple Spike est disponible.

Dépannage et validation : de l'hôte au conteneur

En l'absence de valeurs PSI, je vérifie la version du noyau, CONFIG_PSI et, en option, le paramètre de démarrage psi = 1. Ensuite, je vérifie le contenu des fichiers sous /proc/pressure/* manuellement et comparez-les aux métriques d'Exporter. Dans cgroup v2, je contrôle également les *.pressure-fichiers dans les répertoires de groupe. Je teste les alertes à l'aide de générateurs de charge et j'observe la logique de réaction via epoll, afin de détecter rapidement les erreurs de configuration. Pour finir, je compare les tableaux de bord Grafana avec les journaux, les traces et les résultats du profileur, afin de garantir la fiabilité du diagnostic et des mesures correctives correspondent à.

Les obstacles typiques que je prévois :

  • Interaction entre les swap: Légère un peu de mémoireCes valeurs sont normales en cas de récupération agressive. La situation devient critique lorsque full augmente, tandis que les latences s'allongent.
  • Isolation et affinité des processeurs: Les cœurs « pinned » (isolés) peuvent, localement, CPU saturé générer, bien que l'hôte dispose encore de marge. Je vérifie irq-PSI supplémentaire si le réseau/stockage génère un nombre important d'interruptions.
  • Environnements virtuels: Dans les machines virtuelles, les valeurs PSI reflètent également l'influence de l'hyperviseur. Je mesure séparément les niveaux hôte et invité afin d'identifier clairement les cas de surengagement.
  • Coût de traitement: Le PSI en lui-même est peu coûteux, mais des intervalles de scraping trop courts augmentent la charge sur Prometheus. 15 s est souvent le compromis idéal.
  • Cardinalité des étiquettes: les chemins cgroup peuvent devenir trop longs. Je les réguler avec labeldrop/conserver et je ne cartographie que les niveaux que j'analyse (par exemple, le service plutôt que chaque cgroup de tâches éphémères).

En bref

PSI mesure les véritables temps d'attente sur le processeur, la mémoire vive et les E/S, ce qui indique clairement une pression sur les ressources. Grâce à l'exportation Prometheus et aux tableaux de bord Grafana, je crée une vue qui distingue les causes et identifie rapidement les points sensibles. La séparation entre some et full sans compter les fenêtres avg10/60/300 permet de prendre des décisions en toute confiance. Je configure des alertes en fonction de plages horaires, je les associe à des délais de latence et je contrôle les réactions automatiques via des déclencheurs. Je peux ainsi prendre des décisions éclairées en matière de capacité, résoudre les goulots d'étranglement à temps et assurer la continuité des services au quotidien réactif.

Derniers articles