ONLINE

Icinga Web 2 und graphite

graphite und Nagvis

Nachdem pnp4nagios schon schön seinen Dienst tut, aktiviere ich zusätzlich die Erstellung von Graphen über graphite; beides wird eine Weile parallel laufen, das liefert uns eine gute Basis für die Entscheidung, was schlussendlich produktiv gehen soll. Doch Obacht: die Maschine muss hier wirklich Performance bieten, beides parallel erzeugt schon eine wahnsinnige Rechenlast.

Installation der Pakete

Im ersten Schritt werden alle benötigten Pakete installiert; für den RaspberryPi 2 gibt es das Paket graphite-web nicht, das muss von Hand eingepfriemelt werden. Ist aber, wie du gleich sehen wirst, auch keine Hexerei. Also: auf RaspPi das Paket einfach weglassen und den Rest wie gehabt installieren. Ob ich übrigens dem Vorgängermodell des RaspPi dieses Setup würde zumuten wollen — ich bin nicht sicher…

 $ apt-get install graphite-carbon libapache2-mod-wsgi python-django python-django-tagging python-cairo python-tz python-pyparsing python-memcache python-rrdtool graphite-web

Icinga2 und carbon-cache verheiraten

Jetzt weisen wir Icinga 2 an, entsprechende Daten bereitzustellen; das geschieht, wir kennen es ja bereits, über einen simplen Aufruf auf Konsole:

$ icinga2 feature enable graphite
Enabling feature graphite. Make sure to restart Icinga 2 for these changes to take effect.
$ service icinga2 restart
[...]
[2015-10-17 12:01:21 +0200] critical/GraphiteWriter: Can't connect to Graphite on host '127.0.0.1' port '2003'.
[2015-10-17 12:01:31 +0200] critical/TcpSocket: Invalid socket: Connection refused

Unser eben installierter carbon-cache läuft noch nicht auf Port 2003, und Icinga 2 meckert an, dass es sich verbinden kann; also sorgen wir dafür, dass der Dienst auch beim Booten gestartet wird (indem wir das Flag auf true setzen) und starten beide durch:

## /etc/default/graphite-carbon
[...]
CARBON_CACHE_ENABLED=true
[...]
$ service carbon-cache start
[...] Restarting Graphite backend daemon: carbon-cacheStarting carbon-cache (instance a)
. ok
$ service icinga2 restart

Funktioniert alles? Wenn ja, so taucht nach einer Weile in /var/lib/graphite/whisper/ ein Ordner icinga auf; wie immer geben die Log-Files Aufschluss darüber, wenn etwas nicht wie erwartet funktioniert. Liegen an dieser Stelle Daten bereit, können sie aufbereitet und dargestellt werden — und hier kommt nun graphite-web ins Spiel.

graphite-web

graphite webCharmant, um konkrete Werte zu vergleichen und sich Graphen nach Wunsch zusammenzustellen — ein sehr bewegliches System, mir gefällt es gut. Auf beispielsweise einem Ubuntu-System genügt ein apt-get install graphite-web. Wenn du das nicht möchtest oder für deine Plattform kein fertiges Paket existiert, muss es per Github gezogen werden; das ist der etwas steinigere Weg, aber nicht viel, es müssen halt ein paar Pfade angepasst werden.

$ cd /usr/src
$ git clone https://github.com/graphite-project/graphite-web.git
Cloning into 'graphite-web'...
remote: Counting objects: 19598, done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 19598 (delta 9), reused 0 (delta 0), pack-reused 19563
Receiving objects: 100% (19598/19598), 19.14 MiB | 2.74 MiB/s, done.
Resolving deltas: 100% (12531/12531), done.
$ cd graphite-web
/usr/src/graphite-web$ ./check-dependencies.py

Ganz zu Anfang hatten wir per apt-get install bereits alle benötigten Komponenten installiert, nicht unbedingt alle optionalen; sollte auf deinem System etwas fehlen, so siehst du es hier und kannst nachinstallieren. Bereit? Dann kann graphite-web nun nach /opt/graphite installiert werden:

/usr/src/graphite-web$ python setup.py install

Nun sorgen wir dafür, dass das Webinterface von graphite-web auf Port 8000 verfügbar gemacht wird; dazu kopieren wir die apache2-Konfiguration, die bei der Installation mitgebracht wurde, an Ort und Stelle, modifizieren sie ein wenig und starten den Webserver durch.

 $ cp /opt/graphite/examples/example-graphite-vhost.conf /etc/apache2/sites-available/graphite-web.conf

Ich möchte, dass der Dienst auf Port 8000 läuft und dass WSGISocketPrefix ein anderes ist als in der Default-Konfig vorgegeben:

## /etc/apache2/sites-available/graphite-web.conf
[...]
WSGISocketPrefix /var/run/apache2
[...]
<VirtualHost *:8000>
[...]
## /etc/apache2/ports.conf
[...]
Listen 8000
[...]

Eine Konfiguration an Ort und Stelle zu legen ist glücklicherweise nicht kompliziert — es existiert eine Beispielkonfiguration, an der wir uns mühelos orientieren können.

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

Wird graphite-web von Github gezogen, müssen hier einige Änderungen vorgenommen werden — zum Beispiel von WHISPER_DIR, das zwingend nach /var/lib/graphite/whisper/ zeigen muss.

Abschliessend die neue Konfiguration aktivieren und dem Webserver einen Tritt geben:

$ a2ensite graphite-web.conf
Enabling site graphite-web.conf.
$ service apache2 restart

Jetzt erstellst du dir eine User-Datenbank:

$ /opt/graphite/webapp/graphite$ PYTHONPATH=/opt/graphite/webapp django-admin syncdb --settings=graphite.settings
Creating tables ...
Creating table account_profile
[...]
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'):
E-mail address: marianne@spiller.me
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

Theoretisch läuft das Webinterface nun also auf Port 8000; praktisch tut es nicht viel, ausser eine Menge Fehler zu produzieren — die Logfiles finden sich übrigens unter /opt/graphite/storage/log/webapp/!

  • »No such file or directory« bei Javascript-Dateien
    • $ /opt/graphite$ ln -s webapp/content static
  • Target WSGI script not found or unable to stat: /opt/graphite/conf/graphite.wsgi
    1. cd /opt/graphite/conf/
    2. cp graphite.wsgi.example graphite.wsgi
  • IOError: [Errno 13] Permission denied: ‚/opt/graphite/storage/log/webapp/***‘
    • chown -R www-data:www-data /opt/graphite
  • /opt/graphite/webapp/graphite/settings.py:235: UserWarning: SECRET_KEY is set to an unsafe default. This should be set in local_settings.py for better security
    • Dann muss /opt/graphite/webapp/graphite/settings.py bearbeitet und der unsichere Default-Key durch einen guten ersetzt werden — für die Erzeugung gibt es auch Online-Generatoren, wenn man das möchte.)

Damit die spätere Aggregation der Daten in per carbon-cache funktioniert, muss auch die Datei /etc/carbon/storage-schemas.conf bearbeitet werden; es ist peinlich genau darauf zu achten, dass die Intervalle denen entsprechen, in denen Icinga2 seine Checks durchführt. Im folgenden Beispiel werden Checks, die jede Minute ausgeführt werden, für zwei Tage gespeichert (1m:2d), Checks, die alle fünf Minuten ausgeführt werden, sollen für zehn Tage gespeichert werden (5m:10d) — und so weiter. Passe an dieser Stelle die Konfiguration deinen Begebenheiten an!

[icinga_internals]
pattern = ^icinga\..*\.(max_check_attempts|reachable|current_attempt|execution_time|latency|state|state_type)  
retentions = 5m:7d
 
[icinga_default]
pattern = ^icinga\.  
retentions = 1m:2d,5m:10d,30m:90d,360m:4y

An dieser Stelle können die beteiligten Dienste nochmal durchgestartet werden; auf Port 8000 läuft nun graphite-web und generiert aus den übermittelten Daten die ersten Graphen. Das ist grossartig! Und nun müssen wir diese hübschen Bildchen lediglich noch in icingaweb2 einbinden…

icinga2-module-graphite

graphite module icingaweb2Ziehe dir per Github das Modul, das genau diese Arbeit verrichten wird:

$ cd /usr/share/icingaweb2/modules
$ git clone https://github.com/findmypast/icingaweb2-module-graphite graphite

Auf dem RaspPi musste ich den passenden Konfigurations-Ordner von Hand anlegen und eine Konfig hineinpacken:

$ mkdir /etc/icingaweb2/modules/graphite
## /etc/icingaweb2/modules/graphite/config.ini
[graphite]
base_url = http://YOUR.HOST.OR.IP:8000/render?
host_name_template = icinga.$host.name$.$metric$
service_name_template = icinga.$host.name$.$service.name$.$metric$
graphite_args_template = &target=$target$&width=300&height=120&hideAxes=false&lineWidth=2&hideLegend=true&colorList=049BAF&bgcolor=white&fgcolor=black
graphite_large_args_template = &target=$target$&width=800&height=700&colorList=049BAF&lineMode=connected&bgcolor=black&fgcolor=gray

Das entspricht nicht dem Default, der funktionierte hier nicht; auf meinem Ubuntu-System sieht die Konfiguration so aus:

## /etc/icingaweb2/modules/graphite/config.ini
[graphite]
base_url = http://YOUR.HOST.OR.IP:8000/render?
host_name_template = icinga2.$host.name$.host.$host.check_command$.perfdata.$metric$.value
service_name_template = icinga2.$host.name$.services.$service.name$.$service.check_command$.perfdata.$metric$.value
graphite_args_template = &target=$target$&source=0&width=300&height=120&hideAxes=false&lineWidth=2&hideLegend=true&colorList=049BAF&bgcolor=white&fgcolor=black
graphite_large_args_template = target=$target$&source=0&width=800&height=700&colorList=049BAF&lineMode=connected&bgcolor=black&fgcolor=gray

Hier musst du schauen, was von deinem System wie geliefert wird; während ich unter Ubuntu kaum etwas von Hand machen musste, war auf dem RaspPi relativ viel Handarbeit erforderlich. Wichtig ist auch zu beachten, dass der Punkt . als Separator verwendet wird! Ich für meinen Teil war jedenfalls sehr glücklich, als ich es so weit geschafft hatte.

graphite und Nagvis

graphite und NagvisZuletzt wollte ich meine neuen hübschen Graphen gerne in die hover-Dateien von Nagvis einbinden; hier gibt es allerdings (noch?) Schwierigkeiten, vielleicht sollte ich auch einfach mal einen Feature Request stellen? Mein Default-Check für Hosts ist hostalive, und so kann ich für alle Hosts als Metrik rta angeben. Doch für die Services ist das nicht so einfach: bei jedem wäre eine andere Metrik von Interesse, und Nagvis gibt da derzeit nichts als Makro vor. Die einzige Metrik, die allen Services gemeinsam ist, ist latency, und die gibt nichts her. Aber wer weiss: vielleicht hat einer von euch eine Idee? Unterschrift

<!-- /var/lib/nagvis/userfiles/templates/default.hover.html -->
[...]
<!-- SHOW PERFORMANCE DATA -->
<table>
   <tr><th><label>Performance Data</label></th></tr>
   <!-- BEGIN service -->
        <tr><td><img src="http://barbapapa.bafi.lan:8000/render/?width=586&height=308&target=icinga.[obj_name].[obj_display_name].latency" alt="latency"></td></tr>
   <!-- END service -->
   <!-- BEGIN host -->
        <tr><td>Aufruf: icinga.[obj_name].rta</td></tr>
        <tr><td><img src="http://barbapapa.bafi.lan:8000/render/?width=586&height=308&target=icinga.[obj_name].rta" alt="rta"></td></tr>
   <!-- END host -->
</table>
<!-- END PERFORMANCE DATA -->
[...]
  1. Hallo Marianne,

    erstmals vielen Dank für Deine sehr ausführliche Anleitung.

    Ich bin auch auf dem Icinga2 Trip aufgesprungen und kann nicht mehr los lassen Jetzt habe ich eine Frage zum Graphite icinga Modul. Gibt es ein Grund warum Du damals (Artikel ist ja ein Jahr alt) die GIT Repository (https://github.com/findmypast/icingaweb2-module-graphite) benutzt hast?

    In der „offiziellen“ Icinga GIT Repository Sammlung gibt es auch eine für das gleiche Modul
    und zwar hier (https://github.com/Icinga/icingaweb2-module-graphite). Diese Version ist von der Konfiguration und vom Verhalten her total anders. Ich habe mittlerweile mehrere Icinga Installationen (@home und @work) und ich habe es natürlich geschafft diese mit unterschiedlichen Graphite Modulen einzurichten

    Ich glaube es wäre sinnvoll dies irgendwo in deiner Anleitung zu vermerken. Was meinst Du?

    Gruß,
    Sebastian

    PS: btw toller Blog

    • Hi,

      hm, also der Grund, weshalb ich das findmypast-Modul eingesetzt habe war der, dass das offizielle damals für meine Zwecke unbrauchbar war; mag sein, dass sich das inzwischen geändert hat, aber als gleich würde ich beide Module dennoch nicht bezeichnen wollen

      Und was das Vermerken angeht: ist ja dann hiermit geschehen.

      Frohe Weihnachten!

  2. Da hat sich ein kleiner Tippfehler eingeschlichen: /etc/defaults/graphite-carbon

    Es muss /etc/default/graphite-carbon (default ohne s) lauten.

    Gruß Chris

  3. @stefanfreitag @sys_adm_ama Macht immer wieder Spass, damit zu spielen. Und ein paar zusätzliche kann man fürs Heimnetzwerk verwenden.

    — via twitter.com

  4. @sys_adm_ama @widhalmt hmmm ein raspberry pi? Dann probiere ich es vll mal nebenher aus. Einer steht hier noch!

    — via twitter.com

  5. Pingback: Rittal CMC-III per Icinga2 überwachen · /sys/adm/ama

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.