URL: https://linuxfr.org/news/decouverte-de-l-outil-de-supervision-prometheus Title: Découverte de l’outil de supervision Prometheus Authors: yannig Davy Defaud, BAud, Benoît Sibaud, palm123, Nÿco, ZeroHeure, C138, dovik et Nicolas Casanova Date: 2017年12月31日T11:35:54+01:00 License: CC By-SA Tags: elasticsearch, grafana, debian, supervision et prometheus Score: 51 Par le passé, j’ai été un grand utilisateur de Nagios et ses différents _forks_. J’avais pour habitude de le coupler avec un PNP4Nagios pour obtenir de jolies courbes sur les métriques remontées par mes greffons de surveillance. J’ai également commencé à utiliser l’outil [Beats](https://www.elastic.co/fr/products/beats) d’Elastic. ![Prometheus](https://prometheus.io/assets/prometheus_logo_grey.svg) Pour diverses raisons, j’ai arrêté d’utiliser ces outils, pour passer sur une _stack_ très différente basée sur Prometheus et Grafana. ---- [Time series in Prometheus (SlideShare.net)](https://fr.slideshare.net/FabianReinartz/prometheus-storage-57557499) [Projet Prometheus](https://prometheus.io) [Téléchargement de Prometheus](https://prometheus.io/download/) ---- # Un peu de contexte # Pour diverses raisons, j’ai eu de nouveau à gérer la mise en place d’une surveillance pour des plates‐formes d’intégration ainsi que pour une plate‐forme servant principalement à faire du _benchmark_. Là encore, j’aurais pu ressortir mes scripts de suivi sous Nagios couplé à PNP4Nagios, me tourner vers un Cacti ou encore me mettre à Zabbix. Un autre candidat intéressant était la suite Beats d’Elastic. Sauf que tous ces outils ne m’emballaient pas et avaient tous un défaut : - Nagios, PNP4Nagios et Cacti étaient clairement vieillots (avec ça, je vais me faire des amis) ; - je ne connaissais pas Zabbix mais je n’avais pas envie de m’y mettre (même si l’on m’en avait dit du bien) ; - Enfin, même si Beats d’Elastic est relativement intéressant, j’ai de plus en plus tendance à trouver Elasticsearch lourdaud et grand consommateur de ressource (grâce notamment à la légèreté de Java). Bref, je trouvais que ces outils restaient en deçà de ce qu’on pourrait attendre d’une _stack_ de supervision moderne. Autre point relativement contraignant : une intégration toujours complexe à réaliser alors que la tendance est plutôt vers des outils de moins en moins intrusifs (je suis un grand consommateur d’Ansible pour cette raison). C’est donc dans cet état d’esprit que je m’apprêtais à mettre en place Beats d’Elasticsearch. Un peu par hasard, j’ai entendu parler de Prometheus et devant l’enthousiasme de la personne qui m’en parlait, j’ai décidé d’y jeter un coup d’œil. # Découverte de Prometheus : principe de fonctionnement # Avant de passer à la mise en place de Prometheus, attardons‐nous sur l’architecture de ce logiciel : ![https://prometheus.io/assets/architecture.svg](https://prometheus.io/assets/architecture.svg) Dans les éléments qui vont particulièrement nous intéresser, nous retiendrons les briques suivantes : - **Prometheus server** : c’est le moteur permettant de stocker les métriques collectées ; - **Jobs exporters** : il s’agit d’agents sur lesquels Prometheus viendra collecter les différentes métriques ; - **Web UI** : restitution des métriques à l’utilisateur ; - **Alertmanager** : gestionnaire d’envoi des alertes aux utilisateurs. ## Principe de fonctionnement du stockage Prometheus ## Prometheus utilise un stockage spécifique pour ses métriques. De ce stockage découlent les atouts et inconvénients de ce moteur. Avant la version 2, il existait trois formats v0, v1 et v2 (ce n’est plus le cas depuis la version 2). Dans la suite, nous reviendrons sur cette évolution et en quoi elle permet d’en retirer des avantages. Au niveau de ce stockage, certains aspects ne seront pas abordés comme, par exemple, la structure des tampons utilisés ou l’écriture sur disque. Si vous voulez une description un peu plus poussée, vous pouvez vous tourner vers la présentation de Fabian Reinartz : [_Time Series in Prometheus_](https://fr.slideshare.net/FabianReinartz/prometheus-storage-57557499) (sur _Slideshare.net_). Le format de cette base de données est spécifique ([série temporelle](https://fr.wikipedia.org/wiki/S%C3%A9rie_temporelle) ou [_time series_](https://en.wikipedia.org/wiki/Time_series) dans la langue de Shakespeare) et diffère de celui qu’on pourrait retrouver dans une base de données classique (SQL ou NoSQL). En effet, les données collectées ont des caractéristiques connues : - collecte de métrique à intervalle connu (toutes les 60 secondes) ; - similarité des données d’une collecte sur l’autre (généralement, l’espace disque des partitions sur un serveur ne change pas). Du fait de ces caractéristiques, Prometheus compresse les données en mémoire et sur disque. Il en résulte une bien meilleure utilisation des ressources mémoire, processeur et disque. ### Présentation des données à stocker ### Chaque collecte de métrique ramènera un groupe de métriques. Ces métriques seront toutes associées à une date stockée sous la forme d’un entier représentant le nombre de millisecondes écoulées depuis le 1^(er) janvier 1970. Chaque métrique sera représentée sous la forme d’un chiffre à virgule flottante de type `float64`. Ci‐dessous un exemple de valeurs que nous allons stocker dans le moteur Prometheus : | **Métrique** | **Horodatage** |**Valeur** | |:------------------:|-------------------:|------------:| |http_requests_total | 1434317560938 | 1500 | |http_requests_total | 1434317562939 | 1520 | |http_requests_total | 1434317564939 | 1531 | |http_requests_total | 1434317566945 | 1554 | ### Stockage par double delta ### Comme on peut le voir, les données ont comme caractéristiques d’être collectées à intervalles réguliers (ici, environ toutes les deux secondes) et d’avoir des valeurs proches d’une collecte à une autre. Afin de réduire la place prise par les données, il est possible de ne stocker que le delta de ces mesures. Ainsi, une première façon de réduire la place prise par ces données est de les stocker sous la forme d'un delta : |**Métrique** | **Delta horodatage** | **Valeur** | |:-------------------:|--------------------:|-----------:| |http_requests_total | 1434317560938 | 1500 | |http_requests_total | +2001 | +20 | |http_requests_total | +2000 | +22 | |http_requests_total | +2006 | +20 | Lors de la première mesure, l’horodatage consommera bien huit octets (un entier sur 64 bits). La donnée quant à elle consommera huit octets (Prometheus stocke toutes ses valeurs au format `float64`), soit 16 octets au total. Dans le cas de l’horodatage, le delta pourra être stocké sous forme d’un entier de longueur variable fonction du delta avec la valeur précédente. Pour le stockage de la métrique, le moteur fait appel à un [ou exclusif](https://fr.wikipedia.org/wiki/Fonction_OU_exclusif) (opération `XOR`) pour comparer l’ancienne et la nouvelle valeur. En fonction de ce résultat, le moteur stockera une représentation compressée de la différence constatée. Si ça n’est pas possible, le moteur utilisera une valeur sur huit octets. Mais en réalité, Prometheus fait appel à un stockage par double delta. Le principe est simple : pour la première mesure, il utilise un stockage brut, pour la seconde mesure, il fait la différence par rapport à la première mesure et toutes les autres mesures sont stockées par rapport au delta du delta de la valeur précédente. Ci‐dessous le stockage que nous obtenons avec le jeu de données : |**Métrique** | **Delta delta horodatage** | **Valeur** | |:------------------:|--------------------------:|-----------:| |http_requests_total | 1434317560938 | 1500 | |http_requests_total | +2001 | +20 | |http_requests_total | +-1 | ++2 | |http_requests_total | ++6 | +-2 | Sur une grande quantité de données, cet algorithme permet de réduire l’espace consommé pour arriver à une moyenne de l’ordre de 1,37 octet par échantillon de métrique (au lieu des 16 octets initiaux). ### Pour aller plus loin ### Cette technique de stockage par mots de longueurs variables est similaire à celle décrite dans un papier sur l’outil Gorilla (produit interne de FaceBook). Ci‐après, le lien vers le PDF de l’article en question : . # Prometheus server # Ce processus a en charge la collecte à intervalles réguliers de l’état des différents _exporters_. Il stocke les métriques collectées dans sa base de données et peut ensuite être interrogé au travers de son API (via HTTP). Un autre rôle du serveur Prometheus est d’évaluer à intervalles réguliers les définitions d’alertes. Ces dernières s’appuient sur l’état des métriques internes collectées. ## Installation du serveur Prometheus ## Les inconditionnels de Docker pourront lancer l’installation à l’aide de la commande suivante : docker run -p 9090:9090 prom/prometheus Pour les personnes ayant ~~toujours~~ recours à des machines système classiques, vous devrez récupérer l’archive de Prometheus à depuis le [site Web du projet](https://prometheus.io/download/). Vous aurez ensuite à : - décompresser l’archive avec la commande suivante : `tar xfvz prometheus-2.0.0.linux-amd64.tar.gz` - lancer Prometheus de la manière suivante : `./prometheus-2.0.0.linux-amd64/prometheus --config.file=prometheus-2.0.0.linux-amd64/prometheus.yml` La console Prometheus est maintenant joignable à l’URL suivante : `http://localhost:9090`. ## Configuration du serveur Prometheus ## Tel que vous l’avez lancé dans le précédent paragraphe, Prometheus sera configuré par défaut afin de scruter son propre état. Si vous souhaitez gérer sa configuration, vous aurez besoin d’alimenter un fichier au format [[YAML]]. Si ce fichier est disponible à l’emplacement `~/prometheus.yml`, vous devrez relancer votre conteneur Docker avec la commande suivante : `docker run -p 9090:9090 -v ~/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus` Pour un lancement classique, la commande sera la suivante : `./prometheus-2.0.0.linux-amd64/prometheus --config.file=~/prometheus.yml` # Jobs exporter # Autre élément important de l’architecture : les sources de données à collecter. Pour cela, Prometheus offre des _exporters_ prêts à l’emploi. Parmi ceux‐ci, le _node exporter_ est particulièrement intéressant. Ce dernier se charge d’exporter énormément de métriques système, que ça soit pour des machines physiques ou virtuelles. On y retrouve indifféremment : - les informations sur l’activité processeur (au processeur près) ; - la consommation de la ressource mémoire ; - l’activité des disques (% d’attente, nombre d’entrées‐sorties par seconde, nombre de mégaoctets par seconde en lecture et écriture) ; - l’activité des interfaces réseau ; - enfin, sur les machines physiques, des indications comme par exemple la température des processeurs. En réalité, il y a tellement de métriques à disposition (comme par exemple l’état de l’entropie du système) qu’il serait difficile de tout détailler. À noter qu’il existe également des _exporters_ pour certains produits connus du marché, comme par exemple **HAProxy**, **Apache** ou encore **MySQL**. L’installation d’un _node exporter_ se réalise en deux phases : - décompression des binaires sur la machine à superviser et lancement de l’agent ; - déclaration au niveau du serveur Prometheus de l’instance à scruter. ## Installation d'un node exporter ## ## Installation d’un node exporter ## L’installation est assez classique. Il faut tout d’abord récupérer l’archive de l’_exporter_ sur https://prometheus.io/download/ [[_lien direct_](https://github.com/prometheus/node_exporter/releases/download/v0.15.2/node_exporter-0.15.2.linux-amd64.tar.gz)]. Décompresser ensuite l’archive avec la commande suivante : `tar xfvz node_exporter-0.15.2.linux-amd64.tar.gz` Le node se lance ensuite de la manière suivante : `./node_exporter-0.15.2.linux-amd64/node_exporter` ## Configuration de Prometheus ## Une fois que le _node exporter_ est lancé, il est maintenant temps de l’indiquer à Prometheus. Afin que cet ajout soit le plus souple possible, ajouter la section suivante dans le fichier `prometheus.yml` (au niveau du champ `scrape_configs`) : ```yaml scrape_configs: [...] - job_name: 'node' file_sd_configs: - files: [ "/etc/prometheus/nodes/*.yml" ] [...] ``` Créez le répertoire jobs : `mkdir -p /etc/prometheus/nodes` Avec cette directive, Prometheus sera en mesure de scruter le contenu du répertoire **/etc/prometheus/nodes** et d'ajouter automatiquement à sa configuration tous les fichiers **.yml** qui y seront déposés. Dans le cas présent, ajoutez le fichier **/etc/prometheus/nodes/localhost.yml** avec le contenu suivant : ```yaml - targets: [ "localhost:9100" ] labels: # Vous pouvez ajouter ce que vous voulez pour taguer la machine host: "localhost" ``` Dès la création du fichier, Prometheus charge ce fichier et commence sa collecte. # Web UI : découverte de Grafana # Par défaut, Prometheus offre à l’utilisateur une interface de restitution. Mais cette dernière est assez rudimentaire (elle est surtout là pour de la mise au point). Les auteurs conseillent de s’appuyer sur l’interface Grafana qui est bien plus avancée de ce point de vue. ## Installation de Grafana ## Grafana est disponible au téléchargement à l’emplacement suivant : . Une fois Grafana téléchargé, l’installation se fait avec `yum` ou `dpkg`. Ci‐dessous l’instruction pour Debian : ```bash wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.6.3_amd64.deb sudo dpkg -i grafana_4.6.3_amd64.deb ``` Et la même chose pour Red Hat ou CentOS : ```bash wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.3-1.x86_64.rpm sudo yum localinstall grafana-4.6.3-1.x86_64.rpm ``` Il est également possible de récupérer une archive TAR compressée avec GZIP seule. En effet, comme Prometheus, Grafana est écrit en Go et, par conséquence, n’a pas de dépendance au niveau système. Une fois installé, il faut démarrer la console avec la commande suivante : `systemctl start grafana` L’utilisateur peut maintenant se connecter sur l’adresse URL de Grafana : `http://localhost:3000` Si vous souhaitez activer Grafana au démarrage, lancez la commande suivante : `systemctl enable grafana` ## Interfaçage avec Prometheus ## Une fois sur l’interface de Grafana, authentifiez‐vous en tant qu’administrateur (compte _admin_, mot de passe _admin_). Seconde étape : la configuration d’une source de données. Au niveau des champs, vous pourrez rentrer les valeurs suivantes : - Name : nom de la connexion (ex : Prometheus) ; - Type : choisir Prometheus ; - URL : rentrer `http://localhost:9090` ; - Access : laisser la valeur _proxy_. Laissez les autres champs à la valeur par défaut et cliquez sur _Add_. ## Ajout d’un dashboard ## La source de données est maintenant configurée. En revanche, il n’y a aucun tableau de bord. La bonne nouvelle est que vous en avez de nombreux disponibles prêts à l’emploi à l’adresse suivante : . Parmi ces tableaux de bords, **Node Exporter Full** permet de récupérer toutes les métriques remontées par les _nodes exporter_ de Prometheus. Il est consultable à l’adresse suivante : . L’installation est réalisée par l’écran d’importation de Grafana en saisissant l’identifiant du _dashboard_ (ici 1860). En cas de problème d’ouverture de flux (avec un serveur mandataire), il est possible de télécharger le _dashboard_ au format [[JSON]], pour ensuite le téléverser sur via interface de Grafana. Une fois le _dashboard_ créé, vous devriez obtenir les graphiques suivants : ![Capture d’écran du dashboard](https://grafana.com/api/dashboards/1860/images/1727/image) # Définition d’alertes # Tout est en place pour la collecte et la restitution des données. Il faut maintenant définir des alertes afin de les remonter auprès des différents opérateurs. Première chose, il faut modifier la configuration de Prometheus afin de lui faire charger des règles permettant de générer des alertes. Ci‐dessous la déclaration à rattacher au niveau du champ `global` : ```yaml # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: - /etc/prometheus/rules/node.rules.yml ``` Créez également le fichier `/etc/prometheus/rules/node.rules.yml` en y mettant les éléments suivants : - une variable `groups` avec une liste de règles ; - pour chaque règle les champs `name` et `rules` ; - pour chaque enregistrement de rules, la définition d’une alerte. Une alerte pourra faire appel à différents champs. Parmi ces derniers, vous pouvez retenir ceux‐ci : - le champ `alert`, avec le nom de cette dernière ; - le champ `expr`, avec une requête permettant de déclencher l’alerte ; - le champ `for`, pour indiquer au bout de combien de temps vous considérez que l’alerte est caractérisée ; - enfin, les champs `labels` et `annotations` peuvent apporter des informations supplémentaires sur l’alerte (nom du système de fichiers, nom du serveur, petite phrase pour donner une procédure permettant de rétablir le service, etc.). Ci‐dessous quelques exemples d’alertes pour une surveillance des machines : ```yaml groups: - name: Alerts nodes rules: - alert: DiskWillFillIn4Hours expr: predict_linear(node_filesystem_free{job="node"}[1h], 4 * 3600) < 0 for: 5m labels: severity: critical annotations: title: '{{ $labels.mountpoint }} is almost full on {{ $labels.instance }}: {{ $value | humanize }}%' - alert: NoDiskSpace expr: node_filesystem_avail{fstype=~"(ext.|xfs)",job="node"} / node_filesystem_size{fstype=~"(ext.|xfs)",job="node"} * 100 <= 1 for: 15m labels: severity: critical annotations: description: There's only 1% disk space left on host {{ $labels.instance }} title: 'No disk space left on {{ $labels.mountpoint }} on {{ $labels.instance }}: {{ $value | humanize }}%' - alert: HighInodeUsage expr: node_filesystem_files_free{fstype=~"(ext.|xfs)",job="node"} / node_filesystem_files{fstype=~"(ext.|xfs)",job="node"} * 100 <= 20 for: 15m labels: severity: critical annotations: description: '{{ $labels.mountpoint }} inodes are running low. Please consider removing file.' title: 'Free inodes on $labels.instance }} on mountpoint {{ $labels.mountpoint }} is at {{ $value | printf "%.2f" }}%' - alert: ExtremelyHighCPU expr: instance:node_cpu_in_use:ratio> 0.95 for: 2h labels: severity: critical annotations: description: 'CPU use percent is extremely high on {{ $labels.instance }} for the past 2 hours.' title: 'CPU use percent is extremely high on {{ $labels.instance }} for the past 2 hours.' - alert: HighCPU expr: instance:node_cpu_in_use:ratio> 0.8 for: 2h labels: severity: critical annotations: description: 'CPU use percent is extremely high on {{ $labels.instance }} for the past 2 hours.' title: 'CPU use percent is high on {{ $labels.instance }} for the past 2 hours.' ``` En se rendant dans la console de Prometheus sur le lien _Alerts_, vous obtiendrez toutes les alertes définies et la liste des _exporters_ en erreur. ![Exemple d’alerte dans la console Prometheus](https://coreos.com/sites/default/files/inline-images/prometheus-etcd-03.png) # Alertmanager # Ce processus aura en charge de restituer auprès des équipes en charge des serveurs l’arrivée de nouveaux événements. ## Installation Tout comme pour la partie serveur de Prometheus, vous pouvez démarrer le gestionnaire d’alertes avec la commande : `docker run -p 9093:9093 prom/alertmanager` Pour les autres, vous allez devoir : - récupérer l’archive d’alertmanager (actuellement en version 0.13.0) : `wget https://github.com/prometheus/alertmanager/releases/download/v0.13.0/alertmanager-0.13.0.linux-amd64.tar.gz` - décompressez‐la avec la commande suivante : `tar xfvz alertmanager-0.13.0.linux-amd64.tar.gz` - enfin, le lancement du gestionnaire d'alerte se fait avec les commandes suivantes : `cd ./alertmanager-0.13.0.linux-amd64 ./alertmanager --config.file=simple.yml` Le fichier `simple.yml` est un exemple de configuration. ## Configuration du gestionnaire d’alertes Le gestionnaire d’alertes est très ouvert au niveau de ses capacités de communication. Vous pouvez envoyer des courriels ou des messages vers Slack pour notifier l’arrivée de nouvelles alertes. Ci‐dessous un exemple de configuration mettant en place l’envoi des notifications vers Slack : ```yaml [...] # The root route on which each incoming alert enters. route: # On envoie tout vers slack par défaut receiver: slack [...] receivers: - name: 'slack' slack_configs: - api_url: "https://hooks.slack.com/services/xxx/xxx/xxxxxx" channel: '#prometheus' [...] ``` Dès que Prometheus envoie une alerte, cette dernière est poussée vers Slack sur le canal `#prometheus` afin d’être prise en compte par les différentes équipes. ## Branchement sur Prometheus Dernier point : brancher le serveur Prometheus sur le gestionnaire d’alertes avec la configuration suivante à ajouter dans le fichier `prometheus.yml` : ```yaml # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: # À adapter en fonction du serveur gestionnaire d’alertes - localhost:9093 ``` Un redémarrage du serveur sera nécessaire pour la prise en compte. Ceci fait, les alertes devraient commencer à arriver sur le canal de communication. # Pour conclure Le tour du propriétaire est maintenant terminé. À vous de jouer !

AltStyle によって変換されたページ (->オリジナル) /