blog-image

Monitoring - Installer un serveur Prometheus/Grafana ( arm - Raspberry PI/Rock64)

  • dHENRY
  • 26/12/2018
  • (Durée de lecture : 14 mn)

Update 2020-01-16 : Cet article complémentaire permet l’implémentation du stockage des données dans une base InfluxDB.

Cette procédure peut aisément être adaptée aux environnements X86 et Amd64 (barres-métal)

J’ai beaucoup utilisé Nagios, puis associé à Centreon, pour réaliser le monitoring des infrastructures que j’avais à gérer. Ce sont des solutions très lourdes, très gourmandes en ressources et qui font flipper quand vous devez appliquer la dernière mise à jour… La priorité restait de disposer d’une solution légère. J’ai préféré prendre du recul et lire énormément avant de choisir une solution pour MytinyDC, j’ai même pensé à développer…
Mes recherches ont abouties au site web de PROMETHEUS, solution développée par la société SOUNDCLOUD et devenue opensource.
En me rendant sur le site prometheus.io, j’ai découvert tout un écosystème et surtout, des programmes compilés pour les processeurs ARM. La piste était sérieuse.
Dès la première phase de tests, je constate très rapidement que l’ensemble sera la solution : simplicité de mise en œuvre évidente, et surtout une charge minimaliste pour les petites unités que j’utilise.
Cette solution est souvent présentée en duo : Prometheus/Grafana . Mais qu’est ce que Grafana ??? Comme indiqué sur sa page Wikipédia :

... permet la visualisation et la mise en forme de données métriques ...

https://fr.wikipedia.org/wiki/Grafana

Grafana est aussi disponible pour les processeurs ARM.

Pour résumer, il faut installer un ou des programmes exportateurs de métriques, sur les serveurs clients (dépend du type de monitoring souhaité), un programme sur le serveur qui collecte les données, un programme sur le serveur permettant de visualiser les tableaux de bord, et pour finir, l’essentiel, le programme sur le serveur chargé de lancer les alertes. Le résultat est très satisfaisant :

Prometheus/Grafana - Monitoring pour MytinyDC

Installation Prometheus

Je vais commencer par l’installation d’un exportateur de métriques sur un serveur client. Le projet “Prometheus” dispose d’un module “node_exporter” permettant le relevé de métriques systèmes (charge CPU, réseaux, etc…) compilé pour armv7 et arm64. Après installation et démarrage de ce dernier, il est très simple de vérifier son bon fonctionnement.
Je poursuivrai par l’installation du système de monitoring à proprement parlé, c’est à dire le service chargé de collecter les métriques auprès des serveurs clients, nommé “Prometheus”.
Il conviendra ensuite d’installer le serveur “Grafana”, qui permettra de visualiser les métriques collectées, sous forme de tableaux de bord.
Ce n’est pas fini, nous verrons la mise en place du système d’alertes “Alertmanager”, sans lui, notre système de monitoring ne sert à rien.

Et pour clore ce billet, nous verrons l’installation d’un exportateur supplémentaire : “haproxy_exporter” par exemple et l’intégration des alertes dans les systèmes de messagerie instantanée :

  • Matrix/Synapse/Element.io (messagerie interne du gouvernement Français)
  • Rocketchat un concurrent.

Ces deux messageries sont opensources et décentralisées (vos données sont chez vous), d’une qualité identique à Whatsapp, Hangout, Messenger. Ce qui en font des concurrents très sérieux. Personnellement et après avoir testé les deux, je préfère Matrix, qui est très complet, robuste, “ultra” rapide, ergonomique, et supporté par les petites unité arm64, qui constituent MytinyDC.

Topologie Monitoring - MytinyDC

Téléchargements

Installation Prometheus-node_exporter sur un client

Connectez-vous root à votre serveur client, rendez-vous dans le répertoire /opt:

cd /opt

et téléchargez l’archive “node_exporter” correspondant à votre plateforme :

  • Rasberry PI : Operating system : Linux - Architecture : armv7
  • Rock64 : Operating system : Linux - Architecture : arm64

Utilisez la commande wget, exemple pour la version Raspberry PI-0.17 :

wget https://github.com/prometheus/node_exporter/releases/download/v0.17.0/node_exporter-0.17.0.linux-armv7.tar.gz

Extraire les données de l’archive, exemple pour le téléchargement précédent :

tar xfz node_exporter-0.17.0.linux-armv7.tar.gz
rm node_exporter-0.17.0.linux-armv7.tar.gz
cd node_exporter-0.17.0.linux-armv7
# exécuter l'exporter en mode détaché
nohup ./node_exporter &

L’exportateur fonctionne et écoute maintenant sur le port : TCP/9100

Ajoutons les règles INPUT au firewall de ce serveur :

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 9100 -j ACCEPT
iptables  -A OUTPUT -o eth0 -p tcp -m tcp --sport 9100 -m state --state RELATED,ESTABLISHED -j ACCEPT

Pour tester le bon fonctionnement de ce service, utilisez un navigateur en indiquant l’url : http://[adresse IP de serveur client]:9100/metrics

Impressionnant, sans paramétrage particulier, l’exportateur fournit déjà les informations systèmes du serveur.

Installation Prometheus serveur

Connectez-vous root au serveur qui sera chargé de collecter les données des différents clients, rendez-vous dans le répertoire /opt:

cd /opt

et téléchargez l’archive “Prometheus” correspondant à votre plateforme :

  • Rasberry PI : Operating system : Linux - Architecture : armv7
  • Rock64 : Operating system : Linux - Architecture : arm64

Utilisez la commande wget, exemple pour la version Raspberry PI-0.17 :

wget https://github.com/prometheus/prometheus/releases/download/v2.6.0/prometheus-2.6.0.linux-armv7.tar.gz

Extraire les données de l’archive, exemple pour le téléchargement précédent :

tar xfz  prometheus-2.6.0.linux-armv7.tar.gz
rm  prometheus-2.6.0.linux-armv7.tar.gz
cd prometheus-2.6.0.linux-armv7/

Configuration du collecteur - fichier yaml

Je vais présenter ici un fichier de configuration basique, pour le cas où j’ai un serveur Prometheus (IP 172.28.0.3) et un client (IP 172.28.0.4)

global:# Default is every 1 minute.
   scrape_configs:
  # serveur prometheus ecoute sur TCP/9090
  - job_name: 'prometheus'
         #metrics_path defaults to '/metrics'
         #scheme defaults to 'http'.
      static_configs:
        - targets: ['localhost:9090']

  # Exportateurs : serveurs clients
  - job_name: 'nodes'
     scrape_interval: 1m # Override the default global interval for this job
     scrape_timeout: 10s # Override the default global timeout for this job
     static_configs:
     - targets: [' 172.28.0.4:9100']

Adaptez cette configuration à votre situation, le client dans mon cas est représenté par l’adresse IP : 172.28.0.4

Démarrer le collecteur en mode détaché :

nohup ./prometheus &

Le collecteur fonctionne et écoute maintenant sur le port : TCP/9090

Ajoutons les règles INPUT au firewall de ce serveur pour qu’il accepte les connexions sur le port TCP/9090 :

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 9090 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 9090 -m state --state RELATED,ESTABLISHED -j ACCEPT

Il est collecteur, ce qui sous-entend qu’il va se connecter au port TCP/9100 du ou des serveurs clients, comme indiqué dans la configuration du serveur Prometheus, Ajoutons aussi les règles OUTPUT:

iptables -A OUTPUT -o eth0 -p tcp -m tcp --dport 9101 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m tcp --sport 9101 -m state --state RELATED,ESTABLISHED -j ACCEPT

Pour tester le bon fonctionnement de ce service, utilisez un navigateur en indiquant l’url : http://[adresse IP de serveur prometheus]:9090/targets
qui permet de visualiser la liste des exportateurs inscrits dans le processus de monitoring :

Dans mon cas, nous voyons 6 serveurs inscrits dans le job “node” chargé de collecter les informations systèmes, le job “Prometheus” qui est le serveur de monitoring, et le “haproxy” chargé de collecter les métriques d’un loadbalancer (répartiteur de charge).

A ce stade, vous pouvez déjà visualiser les données collectées au moyen du visualiseur interne à Prometheus :
http://[adresse IP de serveur prometheus]:9090/graph

Ce dispositif minimaliste ne permet pas de construire des tableaux de bord, mais uniquement d’afficher un graphique éphémère.

En moins de 20 minutes, le système de collecte est en place et fonctionnel

Recharger la configuration du serveur Prometheus

Vous avez la possibilité de redémarrer le serveur en utilisant la commande kill et exécuter à nouveau le programme, ou bien recharger la configuration, en envoyant le signal HUP au processus. Une autre option par appel API existe mais vous devrez démarrer Prometheus avec le paramètre “–web.enable-lifecycle”, déconseillé dans la documentation et effectuer l’appel avec la commande curl :

curl -X POST http://[adresse du serveur prometheus]:9090/-/reload

La méthode prescrite est d’envoyer le signal HUP au processus

ps -ef | grep prometheus - récuperer le pid
kill -HUP [pid processus prometheus]

Installation Grafana

Reportez-vous à la topologie ci-avant, le serveur Grafana va aller chercher les métriques auprès du serveur Prometheus, en vue de les afficher dans son interface.

Installation du serveur

Connectez-vous root au serveur qui sera chargé du support Grafana, rendez-vous dans le répertoire /opt:

cd /opt

et téléchargez l’archive “Grafana” correspondant à votre plateforme (lien situé ci-avant):

  • Rasberry PI : Ubuntu & Debian(ARMv7)
  • Rock64 : Ubuntu & Debian(ARM64)

Utilisez la commande wget, exemple pour la version Raspberry :

wget https://dl.grafana.com/oss/release/grafana_5.4.2_armhf.deb

Installer ce paquet Debian avec la commande “dpkg” :

dpkg -i grafana_5.4.2_armhf.deb

Si cette commande vous demande d’installer des logiciels dépendants, utilisez immédiatement la commande :

apt -f install

Supprimer le paquet

rm  grafana_5.4.2_armhf.deb

Le programme d’installation vous donnera les instructions pour le paramétrage final et le démarrage.

Après démarrage le serveur Grafana écoute sur le port TCP/3000
Ajoutons les règles INPUT au firewall de ce serveur :

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 3000 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 3000 -m state --state RELATED,ESTABLISHED -j ACCEPT

Paramétrage

A l’aide d’un navigateur, connectez-vous au serveur Grafana : http://[adresse IP serveur Grafana]:3000
Le compte et mot de passe sont : admin/admin
Grafana vous demandera de changer ce mot de passe.
La premier paramétrage à effectuer sera de créer la source de données, qui sera le serveur Prometheus

Les données sont maintenant accessibles, nous allons pouvoir implémenter un tableau de bord. Ou du moins, pour commencer, importer un tableau de bord existant. En effet, les tableaux de bord (dashboards) créés, peuvent aisément être exportés et réutilisés par d’autres. Prometheus, renvoie toujours les même schéma de données, par conséquent, les tableaux de bord sont distribuables. Pour commencer, je vous conseille d’importer le dashboard dont l’ID est : 1860 (https://grafana.com/dashboards/1860)

Indiquez l’id du dashboard et cliquez sur load * Sélectionnez la source de données

Cliquez sur import

Cliquez sur le selecteur de dashboad et sélectionner Node Exporter Full

Le résultat est immédiat

Ajouter un client au système de monitoring

Je souhaite ajoute le serveur 172.28.0.2 au monitoring, suivre la procédure ci-avant pour installer l’exportateur. Ajoutons le serveur dans la configuration du serveur (job : nodes) :

global:# Default is every 1 minute.
scrape_configs:
# serveur prometheus ecoute sur TCP/9090
- job_name: 'prometheus'
#metrics_path defaults to '/metrics'
#scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
# Exportateurs : serveurs clients
- job_name: 'nodes'
scrape_interval: 1m # Override the default global interval for this job
scrape_timeout: 10s # Override the default global timeout for this job
static_configs:
- targets: [' 172.28.0.4:9100']

   - targets: [' 172.28.0.2:9100']

Adaptez les éléments en gras à votre situation.

Rechargez la configuration Prométheus (voir ci-avant)

Les alertes

Prometheus dispose de plusieurs connecteurs (voies de diffusion des alertes), pagers divers, outils de gestion d’incidents et l’email que nous aborderons ici.

Installation du serveur d’alertes

L’architecture est de type “décentralisée”, ce service peut-être disposé sur un serveur différent du serveur de monitoring Prometheus.

Connectez-vous root à votre serveur d’alertes, rendez-vous dans le répertoire /opt:

cd /opt

Et téléchargez l’archive “alertmanager” correspondant à votre plateforme :

  • Rasberry PI : Operating system : Linux - Architecture : armv7
  • Rock64 : Operating system : Linux - Architecture : arm64

Utilisez la commande wget, exemple pour la version Raspberry PI-0.16 :

wget https://github.com/prometheus/alertmanager/releases/download/v0.16.0-alpha.0/alertmanager-0.16.0-alpha.0.linux-armv7.tar.gz

Extraire les données de l’archive, exemple pour le téléchargement précédent :

tar xfz alertmanager-0.16.0-alpha.0.linux-armv7.tar.gz
rm alertmanager-0.16.0-alpha.0.linux-armv7.tar.gz
cd alertmanager-0.16.0-alpha.0.linux-armv7/

Paramétrage

Le paramétrage du serveur s’opère au moyen d’un fichier au format yaml : alertmanager.yml. Le pré-requis est un système de messagerie fonctionnel. Ma configuration stmp : localhost, sans authentification.

global:
 templates:
 - "./templates/*.tmpl"
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 5h
receiver: 'email'       # A default receiver
routes:
  -  match:
severity: 'warning'
receiver: 'email'
  -  match:
  severity: 'critical'
receiver: 'email'
receivers:
  -  name: 'email'

 email_configs:

  -  send_resolved: true
to: '[email destination]'
smarthost: 'localhost:25'
from: '[email expéditeur]'
headers:
From:  '[email expéditeur] '
Subject: '{{ template "email.default.subject" . }}'
To:  [email destination]
html: '{{ template "email.default.html" . }}'
require_tls: false

Adaptez cette configuration selon votre situation (en gras et entre [])

Exécuter alertmanager en mode détaché :

nohup ./alertmanager &

L’altertmanager fonctionne et écoute maintenant sur le port : TCP/9093

Ajoutons les règles INPUT au firewall de ce serveur :

iptables -A INPUT -i eth0 -p tcp -m tcp --dport  9093 -j ACCEPT
iptables  -A OUTPUT -o eth0 -p tcp -m tcp --sport  9093  -m state --state RELATED,ESTABLISHED -j ACCEPT

Pour tester le bon fonctionnement de ce service, utilisez un navigateur en indiquant l’url : http://[adresse IP de serveur client]:9093

Alertmanager en fonctionnement

Paramétrage Prometheus serveur

Rendez-vous dans le répertoire du serveur Prometheus et ajouter au fichier prometheus.yml :

alerting:
  alertmanagers:
    -  static_configs:
       -  targets:
           -  'localhost:9093'
rule_files:
 - "./rules.yml"

Adaptez les éléments en gras à votre situation

Créez le fichier rules.yml dans le répertoire Prometheus :

groups:
- name: example
rules:
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."

Rechargez la configuration Prometheus (voir ci-avant)

Si le service Alertmanager n’est pas hébergé sur le serveur Prometheus, ajouter les règles Firewall sur le serveur Prometheus :

iptables -A OUTPUT -o eth0 -p tcp -m tcp --dport 9093 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m tcp --sport 9093 -m state --state RELATED,ESTABLISHED -j ACCEPT

Génération d’une alerte

Le plus simple sera de refuser les accès au port 9100 d’un serveur client en supprimant le règle firewall correspondante, ou tout simplement arrêter le processus node_exporter du serveur.
Prometheus le considérera comme : “down” (hors service).

Flux du message d’alerte

Dans un premier temps connectez-vous à l’interface web du serveur prometheus, menu “Alerts”. Aucune alerte pour le moment

On attend le prochain “scrapping” vers ce serveur (interface web du serveur prometheus, menu “Status/Targets”)

Basculer vers le menu “Alerts”

L’alerte est en attente

L’alerte est déclenché, donc envoyé à l’alertmanager

Connectez-vous à l’interface web de l’alertmanager

L’alerte est publiée

L’email d’alerte a été envoyé, vérifiez votre boîte aux lettres.

Contenu de l’email d’alerte

Notre système est opérationnel

Rajouter la règles firewall d’accès au port TCP/9100 sur l’unité en défaut, ou redémarrer le processus node_exporter. Et attendre le prochain “scrapping”. Un email se envoyé, indiquant la disparition du défaut :

Ce graphique (Grafana) montre clairement toutes les interruptions qui ont eu lieu durant la phase de test réalisée, pour écrire ce billet (et les pauses café…)

Ajouter un exportateur

Dans cet exemple, je vais ajouter l’exportateur “haproxy_exporter”. Pour cela je dispose d’un serveur équipé du logiciel haproxy et paramétré pour la répartition de charge Layer7.

Connectez-vous root à votre serveur haproxy, rendez-vous dans le répertoire /opt:

cd /opt

Et téléchargez l’archive “haproxy_exporter” correspondant à votre plateforme :

  • Rasberry PI : Operating system : Linux - Architecture : armv7
  • Rock64 : Operating system : Linux - Architecture : arm64

Utilisez la commande wget, exemple pour la version Raspberry PI-0.09 :

wget https://github.com/prometheus/haproxy_exporter/releases/download/v0.9.0/haproxy_exporter-0.9.0.linux-armv7.tar.gz

Extraire les données de l’archive, exemple pour le téléchargement précédent :

tar xfz haproxy_exporter-0.9.0.linux-armv7.tar.gz
rm haproxy_exporter-0.9.0.linux-armv7.tar.gz
cd haproxy_exporter-0.9.0.linux-armv7/

Pour utiliser cet exportateur vous devrez activer les statistiques haproxy. Ajoutez à votre fichier /etc/haproxy/haproxy.cfg, les lignes suivantes

frontend stats-haproxy
mode http
log global
maxconn 2
stats uri /
stats realm Haproxy\ Statistics
##stats auth xxxxx:xxxx
bind [adresseIP stats]:[port stats] ssl crt [nom du fichier certificat .pem]

# ou sans support SSL : bind [adresseIP stats]:[port stats]
enabled

Pour les besoins de ce billet j’ai désactivé l’authentification d’accès aux statistiques HAPROXY

Recharger haproxy :

systemctl reload haproxy

Exécuter l’exporter en mode détaché et en lui fournissant les paramètres d’accès aux statistiques HAPROXY :

nohup ./haproxy_exporter --haproxy.scrape-uri=https://[adresseIP stats]:[port stats] /?stats;csv --no-haproxy.ssl-verify &

ou bien sans le support SSL :

nohup ./haproxy_exporter --haproxy.scrape-uri=http://[adresseIP stats]:[port stats] /?stats;csv &

L’exportateur fonctionne et écoute maintenant sur le port : TCP/9101

Ajoutons les règles INPUT au firewall de ce serveur :

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 9101 -j ACCEPT
iptables  -A OUTPUT -o eth0 -p tcp -m tcp --sport 9101 -m state --state RELATED,ESTABLISHED -j ACCEPT

Pour tester le bon fonctionnement de ce service, utilisez un navigateur en indiquant l’url : http://[adresse IP de serveur client]:9101/metrics

Paramétrage du serveur Prometheus

Rendez-vous dans le répertoire d’installation du service prometheus. Ajoutez ces lignes au fichier prometheus.yml

job_name: 'haproxy'
  static_configs:
   - targets: ['172.28.0.1:9101']

Adaptez les valeurs en gras à votre situation

Rechargez la configuration Prometheus (voir ci-avant)

Rendez-vous maintenant sur le serveur Grafana, en tant qu’administrateur et ajouter le dashboard dont l’id est : 2428 (https://grafana.com/dashboards/2428)
Générer un peu de flux au niveau du loadbalancer Haproxy et consultez le dashboard Grafana:

Intégration Matrix/Synapse/Element.io

update du 25/04/2019
Merci de vous reporter à ces articles :

Intégration RocketChat

Suivre la procédure : github.com/pavel-kazhavets/AlertmanagerRocketChat

class Script {
    process_incoming_request({
        request
    }) {
        //console.log(request.content);
        var alertColor = "warning";
        if (request.content.status === "resolved") {
            alertColor = "good";
        } else if (request.content.status === "firing") {
            alertColor = "danger";
        }
        let finFields = [];
        for (i = 0; i < request.content.alerts.length; i++) {
            var endVal = request.content.alerts[i];
            var elem = {
                title: "alertname: " + endVal.labels.alertname,
                value: "_instance:_ " + endVal.labels.instance,
                short: false
            };
            finFields.push(elem);
            if (!!endVal.annotations.summary) {
                finFields.push({
                    title: "summary",
                    value: endVal.annotations.summary
                });
            }
            if (!!endVal.annotations.severity) {
                finFields.push({
                    title: "severity",
                    value: endVal.annotations.severity
                });
            }
            if (!!endVal.annotations.description) {
                finFields.push({
                    title: "description",
                    value: endVal.annotations.description
                });
            }
        }
        return {
            content: {
                username: "monitoring",
                attachments: [{
                    color: alertColor,
                    title_link: request.content.externalURL,
                    title: "Prometheus notification [" + request.content.status + "]",
                    fields: finFields
                }]
            }
        };
       return {
            error: {
                success: false
            }
        };
    }
}

J’ai apporté quelques modifications afin d’indiquer le statut de l’alerte au niveau du titre de l’alerte reçue sur rocketchat et commenté l’instruction console.log…

Aller plus loin

  • Préparation des serveurs pour l’exécution automatique des services au démarrage du serveur : fabrication des fichiers pour “systemd”
  • Filtrer les métriques relevées (fichiers de configuration des services)
  • Communication avec un outil de gestion d’incidents (victorops,opsgeni,trudesk,…)
  • Modularité, haute disponibilité,…
  • Sécuriser l’ensemble : affiner les règles de firewall, implémenter l’authentification au niveau du serveur Prometheus
  • Attention, la console Prometheus exprime les dates en UTC. Tandis que Grafana est paramétrable, Prometheus ne l’est pas (Il s’agit d’un choix des développeurs).

Licence de ce document : Creative Commons (CC BY-NC-ND 4.0)

CETTE DOCUMENTATION EST LIVRÉE “EN L’ÉTAT”, SANS GARANTIE D’AUCUNE SORTE ET DISTRIBUÉE DANS UN BUT ÉDUCATIF EXCLUSIVEMENT. L’AUTEUR, CONTRIBUTEURS DE CETTE DOCUMENTATION OU ©MYTINYDC.COM NE SAURAIENT EN AUCUN CAS ÊTRE TENUS RESPONSABLES DES DOMMAGES DIRECTS OU INDIRECTS POUVANT RÉSULTER DE L’APPLICATION DES PROCÉDURES MISES EN ŒUVRE DANS CETTE DOCUMENTATION, OU DE LA MAUVAISE INTERPRÉTATION DE CE DOCUMENT.