GRAFANA

26 août 2020 Non Par nospheratus

Tout d’abord, l’interface de Grafana seule ne sert à rien. Pour fonctionner elle a besoin d’être alimenté par des « Datas Sources ». La data source primaire que j’ai utilisé est Graphite qui lui concentre les données dans une base « whisper » qui ressemble à du rrd via carbon-cache. Sur les serveurs cibles, afin d’alimenter graphite, j’utilise collectd qui est un deamon qui collecte des données et les envoie à un serveur collectd sur le mode client/serveur. Ainsi il convient donc d’installer sur le serveur le moteur collectd qui va travailler avec carbon-cache.

Pour résumer sur le serveur :

  • Collectd : il réalise la collecte des données sur les différents serveurs
  • Graphite : Il concentre les données dans une base via carbon-cache et présente une API Rest à Grafana afin d’utiliser les données en base.
  • Grafana : Il utilise l’API de graphite afin de mettre en forme différents graphique.

Collectd

Collectd permet de collecter des données de multiples sources et de les agréger sous plusieurs types de stockage. A l’UFC, il s’agira de ces bons vieux fichiers rrd. Collectd est un logiciel très léger auquel on ajoute un système de plugin qui permet de collecter certains types de données. Par exemple le plugin load permet de collecter le load average sur un serveur. Ici je vais détailler l’installation, la configuration de l’architecture de type client/serveur dans laquelle un serveur va collecter les données de tous les clients.

Serveur à 172.20.16.63 graphite.nosland.com

Client à 172.20.16.65 moodle.nosland.com

Installation et configuration du serveur

Graphite$> apt-get install collectd collectd-utils

Il faut ensuite éditer le fichier de configuration principal : /etc/collectd/collectd.conf

Hostname « graphite.nosland.com »
FQDNLookup true
TypesDB « /usr/share/collectd/types.db » « /etc/collectd/my_types.db »

Une fois ces quelques paramètres vérifier, on relance le daemon systemctl restart collectd

Si tout est OK, on devrait avoir des fichiers dans le dossier /var/lib/collectd/rrd/graphite.serveurs.dsi.univ-fcomte.fr/

 Il faut maintenant configurer le serveur d’écoute, on édite de nouveau le fichier /etc/collectd/collectd.conf

Il faut s’assurer que la ligne de déclaration du plugin « network » n’est pas commenté. Si c’est le cas, il faut la dé-commenter :

#LoadPlugin mysql
#LoadPlugin netlink
LoadPlugin network  <= décommenter cette ligne !
#LoadPlugin nfs
#LoadPlugin nginx

Puis nous allons configurer le serveur d’écoute. Il faut pour cela se rendre dans la partie de configuration des plugins et repérer la partie concernant le plugin « network »

Notre serveur va écouter sur son interface réseau eth0 (172.20.16.63) et sur le port 25826 (udp). Pensez à ouvrir le FW.

On repère le début de la configuration du plugin par la balise : « <Plugin network> »

Dans le tableau suivant, je vous donne la configuration d’origine dans la colonne de gauche et la configuration que l’on doit obtenir dans la colonne de droite. En gras les lignes qui ont été dé-commentées et/ou modifiées.

#<Plugin network>
#       # client setup:
#       Server « ff18::efc0:4a42 » « 25826 »
#       <Server « 239.192.74.66 » « 25826 »>
#               SecurityLevel Encrypt
#               Username « user »
#               Password « secret »
#               Interface « eth0 »
#               ResolveInterval 14400
#       </Server>
#       TimeToLive 128
#
#       # server setup:
#       Listen « ff18::efc0:4a42 » « 25826 »
#       <Listen « 172.20.16.63 » « 25826 »>
#               SecurityLevel Sign
#               AuthFile « /etc/collectd/passwd »
#               Interface « eth0 »
#        </Listen>
#       MaxPacketSize 1452
#
#       # proxy setup (client and server as above):
#       Forward true
#
#       # statistics about the network plugin itself
#       ReportStats false
#
#       # « garbage collection »
#       CacheFlush 1800
# </Plugin>
->



<Plugin network>
#       # client setup:
#       Server « ff18::efc0:4a42 » « 25826 »
#       <Server « 239.192.74.66 » « 25826 »>
#               SecurityLevel Encrypt
#               Username « user »
#               Password « secret »
#               Interface « eth0 »
#               ResolveInterval 14400
#       </Server>
#       TimeToLive 128
#
#       # server setup:
#       Listen « ff18::efc0:4a42 » « 25826 »
        <Listen « 172.20.16.63 » « 25826 »>
#               SecurityLevel Sign
#               AuthFile « /etc/collectd/passwd »
#               Interface « eth0 »
        </Listen>
#       MaxPacketSize 1452
#
#       # proxy setup (client and server as above):
#       Forward true
#
#       # statistics about the network plugin itself
#       ReportStats false
#
#       # « garbage collection »
#       CacheFlush 1800
</Plugin>

On pourrait ajouter une authentification mais vu que notre environnement est exclusivement sur un réseau privé et contrôlé, je me suis passé de cette configuration.
Il suffit maintenant de relancer le service : systemctl restart collectd

Si tout est ok on doit voir notre processus qui tourne :


Graphite$> netstat -ntulape | grep 25826 udp        0      0 172.20.16.63:25826      0.0.0.0:*                           0          18943      595/collectd

Installation et configuration de collectd sur le client

Comme pour le serveur on commence par installer les paquets collectd et collectd-utils

Moodle2019$> apt-get install collectd collectd-utils

Ensuite on modifie la valeur du hostname :

Hostname « moodle.nosland.com »

On dé-commente les plugins qui nous intéressent : cpu, df, disk, entropy, etc…
On s’assure que le plugin « network » ne soit pas commenté :

#LoadPlugin netlink
LoadPlugin network  <= décommenter cette ligne !

Puis on configure le plugin network afin qu’il envoie sa collecte sur notre serveur :

<Plugin network>
<Server « 172.20.16.63 » « 25826 »>
</Server>
</Plugin>

        (j’ai retiré toutes les lignes que je laisse en commentaire dans la configuration du plugin).

        On relance le service : systemctm restart collectd
Normalement on devrait avoir un dossier avec le nom du client sur le serveur :

Graphite$> ls /var/lib/collectd/rrd/
graphite.nosland.com     Moodle.nosland.com

Graphite

Graphite se décompose en 3 parties distinctes :

  • Whisper qui est une base de données (proche de rrd)
  • Carbon qui un deamon qui permet d’agréger les données dans Whisper.
  • Graphite-web qui est un webservice qui présente une API REST à grafana. (c’est une webapp qui tourne en Python en s’appuyant sur django.)

On peut utiliser Graphite de deux façons dans notre infra :

  • Soit on utilise les données whisper avec le deamon Carbon
  • Soit on fait lire directement nos fichiers à graphite-web

Installation de Graphite-web

On a besoin d’installer le package PIP car graphite-web n’est plus maintenu par Debian :

Graphite$> apt-get install python-pip

Graphite-web utilise django en tant que dépendance, on l’installe donc

Graphite$> pip install django

Puis on installe les autres dépendances :

Graphite$> apt-get install python-dev libcairo2-dev libffi-dev build-essential apache2 libapache2-mod-wsgi python-rrdtool

On fait ensuite un lien symbolique sur un dossier /opt/graphite. Ceci permettra de faire des mises à jours facilement par la suite :

Graphite$> ln –s /opt/graphite-1.1.5/ /opt/graphite

Ensuite on initialise la BDD (sqlite) :

Graphite$> PYTHONPATH=/opt/graphite/webapp django-admin.py migrate –settings=graphite.settings –run-syncdb

Ça créé un fichier /opt/graphite/storage/graphite.db
Nous allons ensuite récupérer un exemple pour la configuration afin de gagner du temps et de ne modifier que ce dont nous avons besoin :

Graphite$> mv /opt/graphite/webapp/graphite/local_settings.py.example /opt/graphite/webapp/graphite/local_settings.py

Il y a deux paramètres à modifier :

SECRET_KEY = ‘DSI-UnivFcomte’ (c’est une clef de hashage)
TIME_ZONE = ‘Europe/Paris’  (Besançon n’étant pas disponible^^)

On a besoin maintenant d’installer le module apache wsgi configuré pour Graphite :

Graphite$> mv /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi

Il faut ensuite générer les fichiers statics de l’apply web (css, js, images, etc…) dans le dossier /opt/graphite/static

Graphite$> PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic –noinput –settings=graphite.settings

Enfin nous devons changer le propriétaire du dossier /opt/graphite/storage qui doit être utilisable par apache (www-data).

Graphite$> chown -R www-data: /opt/graphite/storage/

Il faut ensuite créer le fichier de configuration apache pour graphite-web. Vu que Grafana est sur le même serveur, graphite-web ne va écouter que sur le loopback (127.0.01), et sur le le port 5566 (port par défaut définit dans la webapp de graphite).
On créé donc /etc/apache2/sites-available/graphite-web.conf

WSGISocketPrefix /run/wsgi
Listen 5566
<VirtualHost 127.0.0.1:5566>
DocumentRoot « /opt/graphite/webapp »
ErrorLog /var/log/apache2/graphite-web_error.log
CustomLog /var/log/apache2/graphite-web_access.log common
# Configuration de WSGI
WSGIDaemonProcess graphite processes=5 threads=5 display-name=’%{GROUP}’ inactivity-timeout=120
WSGIProcessGroup graphite
        WSGIApplicationGroup %{GLOBAL}
WSGIImportScript /opt/graphite/conf/graphite.wsgi process-group=graphite application-group=%{GLOBAL}
WSGIScriptAlias / /opt/graphite/conf/graphite.wsgi
# Pour rendre le fichier graphite.wsgi visible par apache
<Directory /opt/graphite/conf/>
                Require all granted
</Directory>
        # Alias pour les fichiers statiques
        Alias /static/ /opt/graphite/static/
# Autorisation sur les fichiers statiques
<Directory /opt/graphite/static>
                Require all granted
</Directory>
# L’alias vers le dossier media de django
Alias /media/ « /usr/local/lib/python2.7/dist-packages/django/contrib/admin/media/ »
</VirtualHost>

On active le fichier de conf, puis on teste la config, et enfin si tout est OK on relance le service apache2 :

Graphite$> a2ensite graphite-web.conf
Graphite$> a2enmod wsgi
Graphite$> apachectl -t
Graphite$> systemctl restart apache2

Maintenant, nous avons notre graphite qui tourne et qui cherche des fichiers pour alimenter sa base et les livrer en API, mais dans le fichier de configuration de graphite : local_settings.py la variable RRD_DIR est positionnée sur /opt/graphite/storage/rrd/ or collectd conserve les fichiers dans le dossier /var/lib/collectd/rrd

Autre détails, nous avons vu que collectd créé des dossiers par serveur avec la variable qui a été définit dans le fichier de conf du client (HOSTNAME). Or nous utilisons des FQDN, et le problème est que graphite ne sait pas interpréter les ‘points’ donc nous allons créer un lien symbolique pour chaque serveur mais en prenant soin de remplacer les « . » par des « _ » :

Graphite$> ln -s /var/lib/collectd/rrd/graphite.nosland.com/ /opt/graphite/storage/rrd/ graphite_nosland_com
Graphite$> ln -s /var/lib/collectd/rrd/moodle.nosland.com/ /opt/graphite/storage/rrd/ moodle_nosland_com

Installation de Carbon

Carbon va nous être utile pour préfixer les données de collectd de façon ensuite à pouvoir adapter la rétention comme on le souhaite.
Pour installer on utilise apt :

Graphite$> apt-get install graphite-carbon

Pour sécuriser un minimum on fait écouter le deamon sur le loopback (127.0.0.1). On modifie donc le fichier /etc/carbon/carbon.conf :

LINE_RECEIVER_INTERFACE = 127.0.0.1

On relance ensuite le service

Graphite$> systemctl restart carbon-cache.service

On active ensuite le plugin write_graphite de collectd. En fait le daemon collectd va envoyer ses données à Carbon (qui écoute sur le port 2003 par défaut), et va les préfixer de « collectd_ »
On édite le fichier /etc/collectd/collectd.conf et on ajoute à la fin de celui-ci :

LoadPlugin write_graphite
<Plugin write_graphite>
                <Node « localhost »>
                  Port « 2003 »
                  protocol « tcp »
                ReconnectInterval 0
                LogSendErrors true
                Prefix « collectd_ »
                StoreRates true
</Node>
</Plugin>

Et on relance collectd : systemctl restart collectd.service

Nous allons maintenant configurer la rétention dans la base whisper via le fichier /etc/carbon/storage-schemas.conf. Vu que nos fichiers sont préfixés nous allons utiliser une regexp pour définir la rétention.

On édite donc le fichier storage-schemas.conf

[collectd]
pattern = ^collectd.*
retentions = 10s:1h,1m:1d,10m:1y

Ces 3 durées de rétention vont répartir les données dans 3 différents groupes :

  • Une précision de 10 secondes sur une heure
  • Une précision de 1 minutes sur 1 jour
  • Une précision de 10 minutes pour une année

On relance carbon : systemctl restart carbon-cache

Installation de Grafana

Il faut commencer par ajouter le dépôt officiel :

Graphite$> wget -q -O – https://packages.grafana.com/gpg.key | sudo apt-key add –
Graphite$> add-apt-repository « deb https://packages.grafana.com/oss/deb stable main »
Graphite$> apt-cache policy grafana
Graphite$>apt-get update && apt-get install grafana –y
Graphite$>systemctl daemon-reload

Graphite$> wget -q -O – https://packages.grafana.com/gpg.key | sudo apt-key add –
Graphite$> add-apt-repository « deb https://packages.grafana.com/oss/deb stable main »
Graphite$> apt-cache policy grafana
Graphite$>apt-get update && apt-get install grafana –y
Graphite$>systemctl daemon-reload
Graphite$>systemctl enable grafana-server.service
Graphite$>systemctl start grafana-server.service

Par défaut grafana écoute sur toutes les interfaces sur le port 3000.

On va modifier ça, et faire écouter grafana que sur le loopback. On ajoutera ensuite un vhost apache pour l’accès.

On modifie donc le fichier /etc/grafana/grafana.ini

http_addr = 127.0.0.1

Ensuite on relance le service : systemctl restart grafana-server

On ajoute donc un vhost apache /etc/apache2/sites-available/graphite.conf

<VirtualHost *:443>
        ServerName graphite.nosland.com
        Serveralias grafana.nosland.com
        Header set X-Robots-Tag « noindex, nofollow »
        ProxyRequests off
        ProxyPass / http://127.0.0.1:3000/
        ProxyPassReverse / http://127.0.0.1:3000/
        SSLEngine on
        SSLCertificateFile /etc/apache2/ssl/apache.pem
        ErrorLog /var/log/apache2/graphite_error.log
        CustomLog /var/log/apache2/graphite_access.log combined
</VirtualHost>

Il ne reste plus qu’à activer le fichier de conf et relancer le service :

Graphite$>a2ensite graphite.conf
Graphite$>a2enmod headers
Graphite$>a2enmod proxy
Graphite$>a2enmod proxy_http
Graphite$>apachectl -t
Graphite$>systemctl restart apache2.service

On se connecte ensuite sur le site :

https://graphite.nosland.com

Par défaut le login est admin et le mot de passe est password. On le modifie puis on peut commencer à configurer notre grafana.

On ajoute notre datasource (graphite-web) :

Puis on configure notre datasource comme sur la capture :

De là on peut commencer à créer nos propres Dashboard :

On clique sur « Add Query » :

Dans « select métric » on va choisir Moodle2019 (sur les capture appelée MoodleProd)

Puis La mémoire, et ensuite le composant collectd récupéré pour la mémoire, ici le pourcentage de libre et enfin la valeur.

Immédiatement Grafana nous dessine une courbe :

On peut modifier la couleur en cliquant sur le rectangle vert devant le nom de la métric :

Pour continuer, on clique sur le logo

Sur cette partie on peut choisir le type de visualisation :

Le graph actuel, la valeur simple, un cadran, des barres, etc…

On va rester sur le graph dans cet exemple mais je ne vais pas tout détailler, le mieux et d’essayer par vous-même.

Pour finaliser mon graphique, je vais lui passer l’unité adaptée :

Et je finis avec un peu de présentation et de valeurs clefs : mini, maxi, moyen et actuelle :

Enfin on donne un titre dans la dernière partie en cliquant sur l’icône :

Et une fois fini, on clique sur la flèche en haut à gauche :

On obtient donc notre graphique sur notre tableau de bord (dashboard)

Pour finir on enregistre notre Dashboard en cliquant sur la petite « disquette » :

Et voilà. L’interface est assez intuitive. Il suffit de fouiller un peu. On peut ainsi faire des groupes de dashboard, faire des playlists etc… On peut créer des utilisateurs, gérer des groupes d’utilisateurs etc..