Blog

Installation de Collectd, Graphite et Grafana - Partie 2

Écrit le 31 07 2017 par Kévin MET _

Introduction

Je reviens pour la deuxième partie de ce tutoriel concernant l'installation de la stack Collectd, Graphite et Grafana et on va aujourd'hui s'attaquer à l'installation de Graphite et Grafana sur le serveur. Il s'agit d'un bon morceau alors on va abréger le blabla et attaquer de suite ! Pour ceux qui ont raté la première partie, ça se passe ici : installation de Collectd en mode serveur/client

Présentation de Graphite

Graphite se décompose en trois parties bien distinctes :

  • Whisper qui est une base de données qui ressemble à du RRD. Pour plus d'informations sur cette base de donnée, je vous invite à lire la documentation sur whisper.
  • Carbon qui est un ensemble de démons qui permettent d’agréger les données dans Whisper. Il ont également d'autres fonctions mais pour rester simple, nous allons nous en tenir à cette fonction principale. Pour ceux qui veulent un peu creuser : les différents démons de Carbon
  • Graphite-web qui présente une API REST à Grafana et qui permet également de produire des graphiques via un navigateur. C'est une webapp qui tourne en python en s'appuyant sur django.
schéma architecture graphite

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

  • Soit on utilise la base de données whisper avec le démon Carbon
  • Soit on fait lire directement nos fichiers rrd à Graphite-web

Installation de graphite-web

Dans ce tutoriel, nous verrons les deux façons de procéder mais on va commencer par la version simplifiée dans laquelle on utilise uniquement graphite-web et les rrd collectés par Collectd. On commence donc par l'installation de graphite-web. Pour cela, on va passer par la version packagée via pip car le paquet graphite-web n'est plus maintenu sur Debian stretch. Cela permet d'avoir une version récente :


apt install python-pip

Graphite-web utilise django en tant que dépendance, il faut donc l'installer :


pip install django

On installe ensuite les autres dépendances nécessaires via le package manager. Le paquet python-rrdtool est absolument nécessaire si vous souhaitez que graphite-web lise directement vos fichiers RRD. Si vous ne l'installez pas, vous n'aurez pas d'erreurs mais les fichiers RRD ne seront pas lus...


apt install python-dev libcairo2-dev libffi-dev build-essential apache2 libapache2-mod-wsgi python-rrdtool

On va ensuite chercher la dernière release sur cette page : graphite-web releases. Au moment où j'écris ce tutoriel il s'agit de la version 1.0.2. On va donc installer cette version de graphite-web dans le dossier /opt/graphite-1.0.2. Pour cela on doit utiliser les options --prefix et --install-lib :


pip install https://github.com/graphite-project/graphite-web/archive/1.0.2.tar.gz --install-option="--prefix=/opt/graphite-1.0.2" --install-option="--install-lib=/opt/graphite-1.0.2/webapp"

On fait ensuite un lien symbolique de ce dossier vers /opt/graphite. Cela nous permettra plus tard de faire la mise à jour sans tous casser. On aura juste à changer les options --prefix et --install-lib et faire le changement sur le lien symbolique pour vérifier que la mise à jour fonctionne correctement.


ln -s /opt/graphite-1.0.2/ /opt/graphite

Il faut ensuite initialiser la base de données qui par défaut est une base sqlite. On peut utiliser d'autres types de bases de données comme MySQL ou PostgreSQL.


PYTHONPATH=/opt/graphite/webapp django-admin.py migrate --settings=graphite.settings --run-syncdb

Cela va créer le fichier /opt/graphite/storage/graphite.db. Il faut ensuite utiliser le fichier local_settings.py.example comme fichier de configuration :


mv /opt/graphite/webapp/graphite/local_settings.py.example /opt/graphite/webapp/graphite/local_settings.py

Dans ce fichier de configuration qui est parfaitement commenté, on retrouve pas mal de réglages. Voici ceux qu'il faut absolument changer et je vous invite à faire un tour complet du fichier pour savoir ce que vous pouvez faire en plus :

  • SECRET_KEY : clé de hashage pour plein de trucs
  • TIME_ZONE : à mettre à Europe/Paris

Voilà, on est sur le minimum vital là mais ça devrait suffire pour continuer le tutoriel. On va ensuite utiliser le fichier wsgi qui sera exécuté par le module apache WSGI.


mv /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi

Il faut ensuite générer les fichiers statiques de l'appli web via cette commande. Cela va copier tous les fichiers statiques (css, js, images, etc.) dans le dossier /opt/graphite/static.


PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic --noinput --settings=graphite.settings

Il faut ensuite modifier les droits sur le dossier /opt/graphite/storage/ qui doit pouvoir être accessible par l'utilisateur faisant tourner l'appli web, www-data dans le cas d'une Debian standard.


chown -R www-data: /opt/graphite/storage/

Il faut ensuite créer la conf pour le vhost qui va exécuter le module WSGI d'apache et donc graphite-web. Dans mon cas je fais écouter ce vhost uniquement sur 127.0.0.1 car Grafana sera sur le même serveur que graphite-web mais si vous souhaitez séparer les deux sur des serveurs différents il faudra le faire écouter sur une autre adresse. Dans ce cas, il faudra bien faire attention aux droits pour se connecter à l'API et à l'appli web. Il existe une option pour limiter la connexion à certains hosts : ALLOWED_HOSTS. Pour aller plus loin et utiliser un système d'authentification avec user/password, je vous laisse voir la doc sur la connexion avec un LDAP

Dans ma configuration apache, j'utilise donc 127.0.0.1 et je fais écouter sur le port 5566, les autre options sont commentées directement dans le fichier. Il faut donc créer le fichier /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>

Il faut ensuite activer cette conf dans apache, activer le module WSGI, vérifier que la config est OK avec apachectl et on relance apache2.


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

Une fois que c'est fait, on peut faire les liens symboliques dans le dossier désigné par l'option RRD_DIR du fichier local_settings.py. Dans notre cas, il s'agit du dossier par défaut : /opt/graphite/storage/rrd/. Attention, il ne faut pas de point dans le nom du fichier et c'est pour cela que l'on va remplacer les points (.) par des underscores (_) dans l'exemple suivant :


ln -s /var/lib/collectd/rrd/client1.mnt-tech.fr/ /opt/graphite/storage/rrd/client1_mnt-tech_fr
ln -s /var/lib/collectd/rrd/serveur.mnt-tech.fr/ /opt/graphite/storage/rrd/serveur_mnt-tech_fr

On peut maintenant vérifier que l'API de graphite-web répond bien avec une requête curl :


curl 127.0.0.1:5566/metrics/index.json

["client1_mnt-tech_fr.load.load.longterm", "client1_mnt-tech_fr.load.load.midterm", "client1_mnt-tech_fr.load.load.shortterm", "serveur_mnt-tech_fr.load.load.longterm", "serveur_mnt-tech_fr.load.load.midterm", "serveur_mnt-tech_fr.load.load.shortterm"]

On voit que le serveur répond bien et que tout est en ordre, on peut donc passer à la partie carbon+whisper pour ceux qui le souhaite. Pour les autres, vous pouvez directement passer sur la partie concernant l'installation de Grafana.

Installation de Carbon

Cette étape est plutôt rapide car il s'agit simplement d'installer le paquet graphite-carbon et de configurer Collectd pour lui envoyer ses données. On commence donc par installer le paquet :


apt install graphite-carbon

Puis pour sécuriser un minimum on va faire écouter le démon carbon uniquement sur 127.0.0.1 car notre collectd est sur le même serveur. Il faut donc modifier le fichier /etc/carbon/carbon.conf et changer cette ligne :


LINE_RECEIVER_INTERFACE = 127.0.0.1

Ce fichier de configuration est très bien commenté et je vous invite à le lire pour voir les options qui sont disponibles. On relance ensuite le service carbon-cache pour la prise en compte et on fait un netstat pour vérifier que carbon écoute bien sur 127.0.0.1 uniquement.


systemctl restart carbon-cache.service

netstat -ntulape | grep 2003

tcp        0      0 127.0.0.1:2003          0.0.0.0:*               LISTEN      0          15694271   4329/python

On active ensuite le plugin write_graphite de collectd et on ajoute ce bloc de configuration dans le fichier /etc/collectd/collectd.conf :


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

Pour aller vite dans l'explication de cette configuration, on explique à collectd qu'il faut envoyer les données qu'il collecte à carbon sur localhost, sur le port 2003 et on préfixe les données avec "collectd_". Cela va nous permettre de filtrer les données qui sont envoyés vers carbon depuis collectd. De cette façon on pourra ajuster les durée de rétention comme on le souhaite. Pour la prise en compte, on relance collectd. Pour avoir plus d'informations sur les options, je vous invite à lire la rubrique dédié au plugin write_graphite dans le man page de collectd.conf (5).


systemctl restart collectd.service

On va donc éditer le fichier /etc/carbon/storage-schemas.conf afin de définir les durées de rétention des données dans la base whisper. Comme nos données sont préfixées avec le terme "collectd_", on va appliquer une simple regexp sur ce terme et on va définir nos durées de rétention.


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

Ces trois durées de rétention vont répartir les données dans trois sets différents. Le premier permettra d'avoir sur une minute, une précision à 10 seconde, le deuxième sur 1 jour, une précision à la minute et le troisième sur un an, une précision à 10 minutes. Pour plus d'info à ce sujet, il y a la documentation en ligne sur storage-schemas-conf. On relance une dernière fois le service carbon-cache pour prendre en compte ce paramètre.


systemctl restart carbon-cache.service

Si tout est ok, on devrait commencer à voir des données provenant de collectd dans la base whisper. On vérifier que ce soit bien le cas :


ls -l /var/lib/graphite/whisper/

total 12
drwxr-xr-x 3 _graphite _graphite 4096 Jul 25 18:14 carbon
drwxr-xr-x 3 _graphite _graphite 4096 Jul 30 17:52 collectd_client1_mnt-tech_fr
drwxr-xr-x 3 _graphite _graphite 4096 Jul 30 17:49 collectd_serveur_mnt-tech_fr

On a bien les données de nos deux serveurs, on peut donc passer à l'installation de grafana !

Installation de Grafana

On commence par ajouter le dépôt officiel qui est sur packagecloud.io (au moment où j'écris cet article le dépôt stable Debian sur packagecloud.io est encore Jessie, il faut donc utiliser jessie même sur une Stretch. Pour cela on va créer le fichier /etc/apt/sources.list.d/grafana.list. On va ensuite ajouter la clé du dépôt et on va installer le paquet grafana.


echo "deb https://packagecloud.io/grafana/stable/debian/ jessie main" > /etc/apt/sources.list.d/grafana.list

curl https://packagecloud.io/gpg.key | sudo apt-key add -

apt install apt-transport-https

apt update

apt install grafana

systemctl daemon-reload

systemctl enable grafana-server.service

systemctl start grafana-server.service

Par défaut, grafana écoute sur toutes les interfaces sur le port 3000. On peut faire de nombreux changements à ce sujet et d'autres dans le fichier /etc/grafana/grafana.ini. On va faire écouter grafana uniquement sur 127.0.0.1 et on ajoutera un vhost dans apache qui utilisera le serveur grafana en tant que reverse proxy. On change donc la ligne http_addr et on relance grafana.


http_addr = 127.0.0.1

systemctl restart grafana-server.service 

Il ne reste plus qu'à mettre en place notre vhost qui va proxyfier les requêtes vers 127.0.0.1:3000. J'en profite également pour utiliser un vhost en SSL et qui écoute donc sur le port 443. Vous adapterez cette partie à votre convenance. Voici donc mon fichier de configuration apache /etc/apache2/sites-available/serveur.mnt-tech.fr.conf :


<VirtualHost *:443>
	ServerName serveur.mnt-tech.fr
	Header set X-Robots-Tag "noindex, nofollow"
	
	ProxyRequests off
	ProxyPass / http://127.0.0.1:3000/
	ProxyPassReverse / http://127.0.0.1:3000/
	
	SSLCertificateFile /etc/apache2/ssl/wildcard.mnt-tech.fr.crt
	SSLCertificateKeyFile /etc/apache2/ssl/wildcard.mnt-tech.fr.key
	SSLCACertificateFile /etc/apache2/ssl/gandi-standardssl-2.chain.pem
	
	ErrorLog /var/log/apache2/serveur.mnt-tech.fr_error.log
	CustomLog /var/log/apache2/serveur.mnt-tech.fr_access.log combined
</VirtualHost>

Il ne reste plus qu'à activer ce vhost, à charger les modules d'apache nécessaires et à relancer le service apache2.


a2ensite serveur.mnt-tech.fr.conf

a2enmod headers

a2enmod proxy

a2enmod proxy_http

apachectl -t

systemctl restart apache2.service

On peut ensuite se connecter sur https://serveur.mnt-tech.fr et utiliser admin:admin en tant qu'user:password. Je vous conseille de commencer par changer ce mot de passe en priorité. Ensuite, on ajoute notre datasource comme dans le screenshot suivant :

Ajout d'un datasource dans grafana

Voilà, on a fini l'installation et on va pouvoir commencer à mettre en place nos premiers dashboard mais on verra cela plus en détail dans la troisième partie de cette série.

♥ Partage sur tes réseaux sociaux ♥
Kévin MET
Kévin MET

Auteur de ce blog et gérant de la société MNT-TECH, je publie sur ce blog lorsque le temps me le permet et lorsqu'un sujet qui me parait intéressant n'a pas encore été abordé en français. Toutes les informations techniques présentes sur cette page peuvent être réutilisées moyennant le fait de citer la source.