Levans' workshop

Experiments and thoughts about Machine Learning, Rust, and other stuff...

Monitorer ses machines avec collectd et grafana


Je me suis depuis peu mis en place un système pour monitorer mes différents serveurs, en utilisant collectd, un service permettant de collecter et remonter et centraliser de nombreuses métriques sur des serveurs linux. Néanmoins, l'interface d'affichage des métriques le plus classique, Collectd Graph Panel, bien que simple à mettre en place, offre une interface assez minimaliste.

Je me suis pour ma part tourné vers Grafana comme front-end. Ce service offre un affichage très moderne et simple à utiliser, entièrement configurable depuis son interface web. Il permet la définition de dashboards pour regrouper les métriques comme bon vous semble, et de regrouper les métriques dans des graphes sans limite. Bref, le bonheur.

Par contre, le hic : collectd et grafana ne peuvent pas communiquer directement. En effet, collectd collecte et remonte les métriques, et grafana récupère les métriques depuis un stockage pour les afficher. Il manque un intermédiaire : ledit stockage. J'ai pour ma part opté pour Graphite, qui a le bon goût de fonctionner out-of-the-box avec collectd et grafana.

Voici donc la description de la mise en place de mon installation:

Disclaimer: Mes machines sont toutes sous Gentoo, certains détails de l'installation que je décris devront donc être adaptés à votre distribution.

Mettre Collectd sur ses machines et remonter les données en réseau

Je ne vais pas revenir sur l'installation de collectd en lui-même, sa documentation est déjà très fournie (voir ici). Je vais me concentrer sur la remontée en réseau des métriques.

Parmi les nombreux plugins de collectd, se trouve le plugin Network, qui permet de transmettre les métriques sur le réseau à une autre isntance de collectd, plutôque de les stocker en local sur le disque.

Il s'agit donc de configurer la machine qui stockera les métriques comme serveur, et les autres comme clients. Dans mon cas, mes serveurs sont déjà reliées entre elles par un VPN chiffré, je me permets donc de transmettre les données en UDP en clair sur ce VPN. Mais il également possible de chiffrer les données (voir ici pour d'autres exemples), si elles doivent être transmise sur un réseau public.

Sur le serveur :

<Plugin network>
    <Listen "10.0.8.1" "25826">
        SecurityLevel None
        Interface "tun0"
    </Listen>
</Plugin>

Sur les autres machines :

<Plugin network>
    <Server "10.0.8.1" "25826">
        SecurityLevel None
    </Server>
</Plugin>

Configurez ensuite collectd sur chaque machine pour collecter les métriques qui vous intéressent.

Récupérer les métriques avec Carbon

Graphite se compose en fait de plusieurs éléments, les deux qui vont nous intéresser ici sont Carbon et Graphite-web. Carbon est la backend de stockage de données en elle-même, et graphite-web est une interface web permettant d'accéder au contenu de la BDD. Elle expose également une API web sur laquelle Grafana va se greffer pour afficher ses graphes.

Sous gentoo, carbon s'installe via l'ebuild dev-python/carbon.

Puis, pour le configurer dans notre cas, les principaux fichiers à modifier sont:

  • /etc/carbon/carbon.conf : je n'ai pour ma part rien changé dedans, mais certains réglages généraux y sont (rotation des logs, ports d'écoute des services, etc....) notamment la variable STORAGE_DIR qui dénote l'endroit où carbon va stocker ses données.
  • /etc/carbon/storage-schemas.conf : ce fichier définit la manière dont les données sont stockées sur le long terme, avec par exemple une résolution diminant au cours du temps.
  • /etc/carbon/storage-aggregation.conf : ce fichier définit la manière dont les données doivent être re-samplées lors d'une diminution de la résolution.

storage-schemas.conf

Mon fichier storage-schemas.conf est le suivant:

[carbon]
pattern = ^carbon\.
retentions = 60:90d

[default]
pattern = .*
retentions = 10s:7d,1m:30d,10m:1y

J'ai laissé les valeurs par défaut pour les données propres à carbon, et ai uniquement changé les réglages pour [default], qui va s'appliquer à mes métriques. Mais comme vous pouvez le voir, il est possible de définir autant de catégories que nécessaires via des regexps pour les matcher.

Ici, 10s:7d,1m:30d,10m:1y veut dire que mes données sont stockées avec une résolution d'un point toutes les 10 secondes pendant la première semaine, puis un point toutes les minutes pendant 30 jours, puis un point toutes les dix minutes pendant un an. Ce qui permet d'éviter de prendre trop de place disque pour de vieilles données.

storage-aggregation.conf

Mon fichier storage-aggregation.conf est celui-ci:

[sum]
pattern = counter
xFilesFactor = 0
aggregationMethod = sum

[default_average]
pattern = .*
xFilesFactor = 0.5
aggregationMethod = average

Toutes les métriques dont le nom contient le terme counter sont aggrégées en sommant les valeurs, et le reste en en prenant la moyenne.

Connecter collectd et carbon

Reste à dire à collectd de tranmettre les données à carbon. Pour celà, on utilise le plugin write_graphite de collectd. Avec la configuration en terme de port par défaut, ça me donne:

<Plugin write_graphite>
    <Node "Carbon">
        Host "localhost"
        Port "2003"
        Protocol "tcp"
        LogSendErrors true
        Prefix "collectd."
        Postfix ""
        StoreRates true
        AlwaysAppendDS false
        EscapeCharacter "_"
    </Node>
</Plugin>

Plus qu'à démarrer le service carbon-cache, relancer le service collectd, et voilà, les métriques de tous nos serveurs sont remontées et enregistrées dans carbon !

Une jolie interface avec Grafana

Graphite-web pour l'api backend

Comme dit précédement, il faut d'abord installer et configurer graphite pour fournir une API HTTP que Grafana pourra appeller.

Sous gentoo, j'ai donc installé le paquet net-analyzer/graphite-web. Puis, quelque configuration rapide de /etc/graphite-web/local_settings.py. Notamment il faudra changer STORAGE_DIR et WHISPER_DIR si nécessaire (j'ai pour ma part gardé les valeurs par défaut /var/lib/carbon et /var/lib/carbon/whisper).

Puis, j'ai configuré un démon uwgi pour faire tourner graphite-web sur un socket en local, que grafana pourra appeller.Sous gentoo, j'ai donc copié le fichier /etc/conf.d/uwsgi en /etc/conf.d/uwsgi.graphite-web et changé les lignes suivantes (changez le reste à votre convenance, et adaptez pour votre distribution):

UWSGI_DIR=/etc/graphite-web/
UWSGI_EXTRA_OPTIONS='--plugins=python27 --http-socket 127.0.0.1:4444 --module wsgi'

Puis, j'ai créé le fichier service associé et lancé le service :

ln -s /etc/init.d/uwsgi /etc/init.d/uwsgi.graphite-web
rc-update add uwsgi.graphte-web default
service uwsgi.graphite-web start

Grafana pour de jolis graphes

Gentoo ne fournit pas d'ebuild pour grafana, j'ai donc téléchargé la tarball sur le site de grafana et l'ai extraite dans /opt/. Puis, j'ai modifié la configuration dans le fichier /opt/grafana/conf/defaults.ini sur les valeurs suivantes :

[server]
protocol = http
http_addr = 127.0.0.1
http_port = 3000
enforce_domain = false

[security]
admin_user = <admin_username>
admin_password = <admin_password>

J'ai laissé la base de données sur sqlite3, mais libre à vous de changer ça. J'ai également créé l'user et le groupe grafana auquel appartiennent le répertoire /opt/grafana et sous lequel je fais tourner le service. Pour l'instant dans un screen avec la commande

su grafana
cd /opt/grafana
./bin/grafana-server

en attendant que je fasse un vrai chier de service pour.

Puis j'ai configuré nginx pour faire un proxypasse pour grafana depuis un vhost de mon domaine :

server {
        listen 443;
        listen [::]:443;
        server_name grafana.example.com;

        ssl_certificate /etc/ssl/nginx/grafana.pem;
        ssl_certificate_key /etc/ssl/nginx/grafana.pem;

        location / {
                proxy_pass http://localhost:3000;
                proxy_set_header Host $host;
        }
}

Et j'ai pu me rendre sur l'interface de grafana, me connecter avec l'user admin précédemment défini dans la conf, et rajouter Graphite comme source de données à grafana :

  • Dans le menu de gauche qui apparait quand on clique sur le logo de grafana, onglet "Data Sources"
  • ajouter comme source de données de type "Graphite" sur l'url http://127.0.0.1:4444/, sans authentification, et avec comme acces-mode Proxy.

Cette dernière valeur impose que toutes les requètes de données soient proxifiées par le serveur grafana à Graphite. Ainsi l'interface graphite n'a besoin d'écouter qu'en local sur la machine, ce qui ôte le besoin de mettre un couche d'authentification par dessus.

Voilà, vous pouvez maintenant mettre en place vos graphes et vos dashboards, à l'aide de la documentation de Grafana.