Ansible, so einfach!

Konfigurationsmanagement in Rechenzentren ist aus der modernen “DevOps” IT nicht mehr wegzudenken. Puppet, Chef, Salt oder Ansible automatisieren Umgebungen von mittelständischen Unternehmen bis hin zu Weltkonzernen.

Wenn wir die verschiedenen Lösungen betrachten, bedienen sie sich alle einer eigenen Sprache, diese soll möglichst einfach unsere Infrastruktur abbilden. (“infrastructure as a code”)
Da nicht jeder Admin im Tagesgeschäft programmiert, kann so eine Sprache ein Hindernis werden und Arbeitsschritte vielleicht verkomplizieren.

Seit einiger Zeit beschäftige ich mit Ansible, ein Tool welches ohne vorinstallierte Clients arbeitet und eine Konfiurationsprache basierend auf YAML nutzt.
Um Ansible zu nutzen muss lediglich eine SSH Verbindung, ein Benutzer mit Rootrechten und ein Inventarfile bestehen.
Das Sprache im YAML Format ist für jeden leicht lesbar und sofort verständlich.

Ansible kann entweder lokal auf dem Arbeitsrechner oder auf einem sogenannten “Managementnode” über bereitgestellte Pakete installiert werden.
Unter “/etc/ansible/” legen wir nach der Installation zusätzlich ein Inventar an.

$ cat /etc/ansible/hosts
host01.localdomain ansible_ssh_host=10.10.10.11
host02.localdomain ansible_ssh_host=10.10.10.12</pre lang="bash">

Wenn Ansible installiert und ein Inventarfile erstellt wurde, kann die Verbindung zum Server mit dem Modul “ping” getestet werden. Hierbei versucht Ansible den Server per SSH zu erreichen und einzuloggen.

$ ansible host01.localdomain -m ping
host01.localdomain | success >> {
"changed": false,
"ping": "pong"
}</pre lang="bash">

Alternativ kann statt dem Hostalias auch “all” gesetzt werden um alle Hosts aus dem Inventar zu prüfen.

$ ansible all -m ping</pre lang="bash">

Ansible bietet zahlreiche Module mit denen Pakete installiert, Dateien kopiert oder bearbeitet werden können. Hier findet ihr eine Übersicht aller Module
Tasks verwenden diese Module um die Arbeitsschritte in Playbooks oder Rollen auszuführen.

Beispiel eines Playbooks:

$ cat ansible_starter.yml
---
- hosts: all <- Führe die Tasks auf allen Hosts aus
  tasks:
    - name: say hello to everyone <- Name des Tasks
      debug:                      <- Name des Moduls
        msg: "Hello World"        <- Parameter des Moduls

– name: install ntp
yum:
name: ntp
state: installed
</pre lang=”yaml”>

$ ansible-playbook -s ansible_starter.yml
&lt;/pre lang="bash"&gt;
Diese Task werden der Reihenfolge nach auf dem Zielhost ausgeführt und damit haben wir schon eine kleine Automation geschaffen. Probiert's aus!

Da Ansible im Sturm mein Automationsherz erobern konnte war ich mit meinem Kollegen dieses Jahr auf dem Ansible Fest in London, einen Erfahrungsbericht der Veranstaltung findet ihr hier.

Thilo Wening

Autor: Thilo Wening

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

AnsibleFest London

Thilo, mein alter Azubi Kollege, und ich haben dieses Jahr das erste mal am AnsibleFest in London teilgenommen. Ziel davon war es, den Blickwinkel zu erweitern und zu sehen, welche Möglichkeiten es mit Ansible gibt und wie sie von anderen Unternehmen ausgeschöpft werden.
Die Unternehmen, die Vorträge gehalte oder an Interviews teilgenommen haben, erstrecken sich von Siemens, über Ansible selbst bis hin zur britischen Armee. Mich hat sehr erstaunt, dass sogar die britische Armee Ansible im produktiven Einsatz hat und dann auch einen Talk darüber abhält!

Das Ambiente war sehr vornehm. Die Veranstaltung fand im “InterContinental London” statt. Wie wir es von NETWAYS Veranstaltungen schon gewohnt sind, gab es reichlich zu Essen und zu Trinken, was uns nach der etwas längeren Anreise, doch zu Gute kam.

Als OpenSource Firma kommen wir bei NETWAYS immer mehr in Kontakt mit dem Configuration Management Tool Ansible. Bereits die ersten Kunden sind auf uns, eben wegen Ansible zugekommen und haben in Zusammenarbeit mit uns ihr Setup aufgebaut. Die Verwaltung der Produktivsysteme läuft demnach mit Ansible und diese Konfigurationen sind sowohl für uns als Administratoren als auch für den Kunden selbst mittels Git zugänglich. Falls auch ihr euch überlegt, eure Systeme mit Ansible zu verwalten, dann kommt gerne auf uns zu! Wir helfen gerne.

Zum Abschluss sind hier noch Bilder vom Hotel sowie von der Anreise hinterlegt.

Marius Gebert

Autor:

Marius ist seit September 2013 bei uns beschäftigt. Er hat im Sommer 2016 seine Ausbildung zum Fachinformatiker für Systemintegration absolviert und kümmert sich nun um den Support unserer Hostingkunden. Seine besonderen Themengebiete erstrecken sich vom Elastic-Stack bis hin zu Puppet. Auch an unserem Lunchshop ist er ständig zu Gange und versorgt die ganze Firma mit kulinarischen Köstlichkeiten. Seine Freizeit verbringt Marius gern an der frischen Luft und wandert dabei durch die fränkische Schweiz

Icinga 2 – Monitoring automatisiert mit Puppet Teil 4: Konfiguration II

Heute werden wir uns die Define Resource icinga2::object::host zum konfigurieren eines Host-Objekts anschauen und auch Services via apply-Regeln an diesen Host binden.

::icinga2::object::host { 'NodeName':
  target  => '/etc/icinga2/example.d/my_hosts.conf',
  import  => [ 'generic-host' ],
  address => '127.0.0.1',
}

Generell kann bei Objekten mit target angegeben werden in welche Datei sie geschrieben werden. Auch lässt sich mit dem Parameter order Einfluss auf die Reihenfolge der einzelnen Objekte in der jeweiligen Datei nehmen. Der Defaultwert für Host-Objekte ist 50, möchte man nun ein weiteres Host-Objekt davor einfügen, ist bei diesem order auf einen Wert kleiner 50 zu setzen. Das funktioniert mit anderen Objekttypen auf die gleiche Weise. So werden z.B. Hostgruppen oder Services mit einer order von 55 bzw. 60 standardmäßig hinter Hosts einsortiert. Um das mittels import eingebundene Template generic-host vor dem Host in die Datei zu schreiben muss im folgenden Codebeispiel order explizit gesetzt werden, da auch ein Host-Template aus icinga2::object::host erzeugt wird und damit den Defaultwert 50 hat.

::icinga2::object::host { 'generic-host':
  template           => true,
  target             => '/etc/icinga2/example.d/my_hosts.conf',
  order              => '47',
  check_interval     => '1m',
  retry_interval     => 30,
  max_check_attempts => 3,
  check_command      => 'hostalive',
}

Der Titel, also der Name des Objektes, und Werte aller Attribute werden durch einen einfachen Parser ausgewertet. So werden Zahlen als solche erkannt, auch wenn sie in Puppet als String geschrieben sind. Das gilt auch für Zeitabstände wie 1h, 1m oder 1s. Auch Konstanten werden erkannt, dadurch wird NodeName als solche erkannt und in der Icinga-Konfiguration nicht gequotet als Konstanten geschrieben. Die erzeugte Konfigurationsdatei sieht dann wie folgt aus:

template Host "generic-host" {
  check_interval = 1m
  retry_interval = 30
  max_check_attempts = 3
  check_command = "hostalive"
}

object Host NodeName {
  import "generic-host"
  address = "127.0.0.1"
}

Ein einzelnes Service-Objekt wird äquivalent erstellt. Möchte man jedoch mittels Apply den Service mehreren Hosts zuordnen geht dies mit Puppet ebenfalls, der Parameter apply muss hier lediglich auch true gesetzt werden.

::icinga2::object::service { 'ping4':
  target        => '/etc/icinga2/example.d/services.conf',
  apply         => true,
  import        => [ 'generic-service' ],
  check_command => 'ping4',
  assign        => [ 'host.address' ],
}

Die Assign- bzw. Ignore-Ausdrücke werden über die Parameter assign bzw. ignore definiert. Die Werte müssen als Array zugewiesen werden. Aus den einzelnen Elemente werden jeweils Assign- bzw. Ignore-Ausdrücke erzeugt.

apply Service "ping4" to Host {
  import "generic-service"

  check_command = "ping4"
  assign where host.address
}

Custom-Attribute können in beliebiger Anzahl dem Parameter vars als Dictionary-Elemente zugewiesen werden. So erzeugt dieser zusätzlich Puppet-Code für das oben beschriebene Host-Objekt,

  vars => {
    os     => 'Linux',
    disks  => {
      'disk /' => {
        disk_partition => '/',
      },
    },

die folgenden Zeilen Icinga-Konfiguration:

  vars.os = "Linux"
  vars.disks["disk /"] = {
    disk_partition = "/"
  }

Der Parser kann auch komplexere Ausdrücke korrekt bearbeiten, wie in assign des folgenden Services ssh.

::icinga2::object::service { 'ssh':
  target        => '/etc/icinga2/example.d/services.conf',
  apply         => true,
  import        => [ 'generic-service' ],
  check_command => 'ssh',
  assign        => [ '(host.address || host.address6) && host.vars.os == Linux' ],
}

Attribute aus dem Host-Kontext wie auch die Operatoren werden korrekt erkannt, das Wort Linux ist nicht bekannt und damit gequotet dargestellt. Alle bekannten Wörter werden ohne Quotes geschrieben. Bekannte Wörter sind neben dem Objekt-Titel, alle Objekt-Attribute, Custom-Attribute, die Konstanten der Icinga-Instanz und eine in icinga2::params::globals definierte Liste.

apply Service "ssh" to Host {
  import "generic-service"

  check_command = "ssh"
  assign where (host.address || host.address6) && host.vars.os == "Linux"
}

Um nun via Puppet auch die folgende Konfiguration modellieren zu können,

apply Service for (fs => config in host.vars.disks) to Host {
  import "generic-service"

  check_command = "disk"
  vars = vars + config
}

Hierzu setzt man den Parameters apply auf einen String, der dem Zuweisungsteil einer Icinga-Foreach-Schleife für Services entspricht. Wichtig hier zu beachten ist, das fs und config nun auch bekannte Wörter sind und nicht gequotet werden. Nähme man anstatt fs z.B. disk, hätte das zur Folge, das die Zeile check_command, mit disk ohne Quotes geschrieben wird. Damit ist dann aber leider die Konfiguration nicht korrekt, die Validierung schlägt fehl und ein Neustart von Icinga wird nicht ausgeführt.

::icinga2::object::service { 'disk':
  target        => '/etc/icinga2/example.d/services.conf',
  apply         => 'fs => config in host.vars.disks',
  import        => [ 'generic-service' ],
  check_command => 'disk',
  vars          => 'vars + config',
}

Zu den bisher erschienen Artikel dieser Serie geht es hier.

Lennart Betz

Autor: Lennart Betz

Der diplomierte Mathematiker arbeitet bei NETWAYS im Bereich Consulting und bereichert seine Kunden mit seinem Wissen zu Icinga, Nagios und anderen Open Source Administrationstools. Im Büro erleuchtet Lennart seine Kollegen mit fundierten geschichtlichen Vorträgen die seinesgleichen suchen.

Store passwords like a boss #2

Als Programmierer von Webanwendungen, die Ihre Benutzer selbst verwalten, kommt man um das Thema Sicherheit nicht herum – so auch ich als Mitentwickler von Icinga Web 2.

Aus diesem Anlass habe ich recherchiert, wie Passwörter von Benutzern sinnvoll gespeichert werden können und mein neu gewonnenes Wissen geteilt.

Darüber hinaus habe ich vorgeschlagen, Icinga Web 2 dementsprechend zu erweitern. Eric hat diesen Vorschlag begutachtet und mich auf eine Alternative aufmerksam gemacht, nämlich…

password_hash()

PHP bietet seit Version 5.5 u. a. diese Funktion, um Passwörter zu verschlüsseln. Diese ersetzt meine selbst geschriebene Funktion aus dem Vorgänger-Blogpost vollständig:

$encryptedNewPassword = password_hash($newPassword, PASSWORD_DEFAULT);

Der Rückgabe-Wert kann direkt in einer Datenbank gespeichert werden – so einfach ist das.

Der zweite Parameter der Funktion bestimmt den Verschlüsselungs-Algorithmus. Damit kann man diesen zwar frei wählen, aber ich empfehle, den Standard vorzuziehen, denn dieser ändert sich (laut Doku) mit neueren PHP-Versionen zu Gunsten der Sicherheit. Damit bleiben zumindest die neuen/geänderten Passwörter aktuell was die Sicherheit angeht.

password_verify()

Wie der Name schon andeutet, überprüft diese Funktion ein vom Benutzer eingegebenes Passwort auf Übereinstimmung mit einem verschlüsselten Passwort:

$ok = password_verify($enteredPassword, $encryptedPassword);
if ($ok) {
    ...

password_needs_rehash()

Wie bereits erläutert: mit einem neuen Standard-Verschlüsselungs-Algorithmus werden automatisch alle neu verschlüsselten Passwörter sicherer. Aber was ist mit den bereits bestehenden?

Da bestehende Passwörter (aus gutem Grund!) nur verschlüsselt vorliegen, können sie nicht alle “in einem Abwasch” migriert werden. Die einzige Gelegenheit ist die Anmeldung eines Benutzers, die das Klartext-Passwort erfordert. Und als wäre die Funktion für diese Gelegenheit geschrieben…

if ($ok) {
    $outdated = password_needs_rehash($encryptedPassword, PASSWORD_DEFAULT);
    if ($outdated) {
        $encryptedPassword = password_hash($enteredPassword, PASSWORD_DEFAULT);
    }
    ...

Fazit

Der IT-Branche wird nicht umsonst nachgesagt, dass sie eine “permanente Innovation” vollbringe. Umso wichtiger ist es, aus Gründen der Datensicherheit, mit der dunklen Seite der Macht mitzuhalten.

Denn die sind böse, sehr böse…

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.

Mein Praktikum bei Netways – Thorben

//Im Namen von Thorben

Erstmal vorweg, ich bin Thorben, 16 Jahre alt und besuche zur zeit das Europa Gymnasium in Gommern (Sachsen-Anhalt, nähe Magdeburg) in der 10. Klasse. Wir hatten die Ankündigung zum Praktikum bekommen und ich wollte irgendwas in Richtung IT machen. Da war es natürlich super, dass ich Ronny Biering kenne, der hier bei Netways arbeitet, über welchem ich dann auch den Kontakt und das Praktikum mit und bei Netways bekam. Nun sollte meine Praktikumsstelle 2 Wochen lang bei Netways sein, was mich echt freute.

Es fing klassisch mit dem Vorstellen jedes Mitarbeiters dieser Firma an und auch mit der Einweisung bei der Kaffeemaschine (wichtigster Mitarbeiter) :). Ich lernte Tim kennen, welcher fortlaufend, neben Sebastian, mein Betreuer des Praktikums sein sollte. Er erklärte mir grob Dinge über die 2 Wochen hier bei Netways und zeigte mir auch diverse Bereiche, wie auch das Rechenzentrum. Meine erste Aufgabe war testweise einen Raspberry PI zum laufen zu bringen und ihm im Anschluss mit dem Netways Dashboard zu versehen. Das ganze wiederholte ich 3 mal, bis ich dann auch schneller als es Tim lieb war, fertig wurde.
Markus Frosch hatte noch einen Vortrag über Passwörter im allgemeinen und über die Benutzung mit Enpass gehalten. Es war recht informativ, sodass ich dieses Programm auch zuhause verwenden werde. Danke dafür.
Danach sollte ich WordPress mit einer Mysql-Datenbank einrichten, womit ich jetzt auch erfolgreich einen eigenen Blog habe. Als auch dies fertig war, „durfte“ ich dann auch die Netzwerk Anschlüsse protokollieren und dann im Anschluss auch die Notebooks der neu ankommenden Praktikanten mit CentOS aufsetzen. Zwischendrin war ich auch im Lager und habe den Bereich mit den Lan Kabeln aufgeräumt und fein säuberlich nach Farbe sortiert. Zur zeit beschäftige ich mich neben dem Blog hier mit dem erledigen einiger Aufgaben, wie einen eigenen Passwort Generator oder auch die Buchstabenhäufigkeit per Bash zu ermitteln. Zum Abschluss bekam ich die Aufgabe, eine html-Seite mit eingebundenen Bildern zu erstellen.

Damit sind meine 2 Wochen Praktikum hier bei Netways auch fast um und ich kann getrost sagen, es war kein Fehler dieses hier zu absolvieren. Ich bekam einen für mich recht großen Einblick in die Shell Oberfläche, da ich nur 2 Jahre mit Delphi zu tun hatte. Im Gegensatz zu Delphi versteh ich jetzt wenigstens mal ein paar Dinge im Bereich der Befehle, womit es im Endeffekt auch Spaß macht die Shell zu benutzen. Auch die Firma an sich ist für mich eine positive Erfahrung in Hinsicht der Hilfe und auch dem Zusammenhalt unter den Mitarbeitern. Und auch Tim, welcher immer ein Ohr für meine Fragen offen hat.

Graphite Reporting mit der Render-API

Vor kurzem durfte ich mich damit beschäftigen, wie man schnell und halbwegs vernünftig eine Art Reporting für Performance-Daten für Icinga 2 umsetzen kann. Um solche Daten entsprechend aufzubereiten bedarf es weiterer Open-Source-Software. Meiner Meinung nach eignet sich Graphite hierzu am besten. Ich möchte heute einen kurzen Einblick in die Möglichkeiten geben.

Graphite ist ein Werkzeug, welches aus drei Komponenten besteht: Carbon-Cache als Datensammler, Whisper als Storage-Backend und Graphite-Web um die Graphen visuell und als API bereitzustellen. Icinga 2 schreibt die Performance-Daten mit dem “graphite”-Feature direkt an den Carbon-Cache-TCP-Socket. Welche Möglichkeiten habe ich als Anwender nun, diese historischen Daten für meine Zwecke in Reporting zu verwenden?

Eigentlich ganz einfach: Graphite liefert eine eigene Render-API. Diese bietet die Möglichkeit, die Daten als Graph, csv , json, pdf und einige weitere Formate zu generieren. Der Anwender kann diese Daten als REST-API Aufruf im Browser oder beispielsweise curl in der Shell abholen. Dabei können verschieden Metriken und Aggregationen auf Graphen angewandt und unterschiedliche Werte gebündelt abgerufen werden.

 

Wie fange ich an?

Generell wird die URL wie folgt aufgebaut:

http://grtaphite.ip/render?target=icinga2..services.*.*.perfdata.*.value

Im gezeigten Beispiel kann man für die “target”-Metriken auch Wildcards verwenden, um etwa mehrere Services gleichzeitig abzufragen. Dies entspricht dem Dateipfad im Whisper-Backend. Man kann allerdings auch Listen oder Arrays angeben, um gezielt bestimmte Werte abzufragen.

Es gibt unterschiedliche Möglichkeiten, die Daten für die entsprechenden Ausgaben weiterzuverarbeiten. Die wohl wichtigsten sind &from für die Zeit und &format für die Formatierung der Daten.

 

Metrik “Baum”

Um die Werte für die CPU-Load abzufragen, muss der entsprechende Service in Icinga 2 definiert sein und Performance-Daten nach Graphite schreiben. Im Screenshot sieht man im Baum “services” – “load”, letzterer stellt den Service-Namen dar. Der Sub-Knoten “load” liefert die Information, dass hier das “load” CheckCommand verwendet wurde. Tip an dieser Stelle: Lässt sich etwa für Dashboard-Templates als eindeutiger Schlüssel verwenden in Grafana.

Performance-Daten liefern zum einen “perfdata”, worin einzelne Metriken mit ihrem Namen abgelegt werden, etwa “load1” und darunter “value” als Wert und Thresholds, etwa “crit” und “warn”, sofern definiert. Zusätzlich können auch Metadaten von Icinga 2 geschrieben werden, die man aber explizit in der Konfiguration einschalten muss (“metadata”).

 

Einzelne Metrik abfragen

Im folgenden interessiert uns aber lediglich der Wert der Metrik “load1” als einzelner Wert. Um eine ordentliche Ausgangsbasis zu erhalten, wählen wir den Zeitraum der letzten 3 Stunden. Tip: Es sind relative und absolute Zeitangaben möglich.

http://192.168.100.101/render?target=icinga2.icinga3op_foreman_local.services.load.load.perfdata.load1.value&height=800&width=600&from=-3hours

 

Mehrere Metriken zusammenfassen

Man kann diese Abfrage auch erweitern, indem man mehrere Werte gleichzeitig abfrägt:

http://192.168.100.101/render?target=icinga2.icinga3op_foreman_local.services.load.load.perfdata.{load1,load15,load5}.value&height=800&width=600&from=-3hours

 

Mehrere Hosts mit der gleichen Metrik abfragen

Eine Abfrage mit verschiedenen Servern für “load15” als Metrik könnte so aussehen:

http://192.168.100.101/render?target=icinga2.icinga*op_foreman_local.services.load.load.perfdata.load15.value&height=800&width=600&from=-3hours

Formatierung

Die Darstellung der Daten setzt immer eine &height und eine &width als Parameter voraus. Es ist auch möglich hier Tortendiagramme mit verschiedenen Funktionen für Mittelwerte und Summen aufzurufen.

Man kann die erhaltenen Daten auch als CSV-Werte formatieren und dann beispielsweise mit curl abspeichern. Alternativ kann man sich diese Werte auch direkt im Browser anzeigen lassen.

[root@icinga1op ~]# curl 'http://192.168.100.101/render/?target=icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value&from=-3hours&format=csv'

icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:30:00,0.24
icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:31:00,0.21
icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:32:00,0.17
icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:33:00,0.15
icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:34:00,0.16
icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:35:00,0.13
icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value,2017-06-16 06:36:00,0.12
....

Wie bereits erwähnt lassen sich die Daten auch im JSON-Format anzeigen. Dies kann wieder über den Browser oder mittels curl erfolgen.

Das folgende Beispiel rendert alle erhaltenen Datenpunkte als JSON-Format:

[root@icinga1op ~]# curl 'http://192.168.100.101/render/?target=icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value&from=-3hours&format=json'
[{"target": "icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value", "datapoints": [[0.13, 1497595140], [0.11, 1497595200], [0.15, 1497595260], [0.13, 1497595320], [0.1, 1497595380], [0.08, 1497595440], [0.07, 1497595500], [0.06, 1497595560], [0.06, 1497595620], [0.05, 1497595680], [0.04, 1497595740], [0.07, 1497595800], [0.05, 1497595860], [0.04, 1497595920], [0.05, 1497595980], [0.04, 1497596040], [0.08, 1497596100], [0.06, 1497596160], [0.07, 1497596220], [0.06, 1497596280], [0.06, 1497596340], [0.05, 1497596400], [0.04, 1497596460], [0.04, 1497596520], [0.03, 1497596580], [0.05, 1497596640], [0.04, 1497596700], [0.05, 1497596760], [0.04, 1497596820], [0.09, 1497596880], [0.07, 1497596940], [0.06, 1497597000], [0.06, 1497597060], [0.05, 1497597120], [0.04, 1497597180], [0.04, 1497597240], [0.03, 1497597300], [0.02, 1497597360], [0.02, 1497597420], [0.01, 1497597480], [0.01, 1497597540], [0.01, 1497597600], [0.01, 1497597660], [0.01, 1497597720], [0.01, 1497597780], [0.07, 1497597840], [0.06, 1497597900], [0.07, 1497597960], [0.08, 1497598020], [0.07, 1497598080], [0.06, 1497598140], [0.04, 1497598200], [0.04, 1497598260], [0.03, 1497598320], [0.14, 1497598380], [0.14, 1497598440], [0.13, 1497598500], [0.12, 1497598560], [0.1, 1497598620], [0.09, 1497598680], [0.09, 1497598740], [0.07, 1497598800], [0.06, 1497598860], [0.07, 1497598920], [0.1, 1497598980], [0.1, 1497599040], [0.08, 1497599100], [0.06, 1497599160], [0.05, 1497599220], [0.04, 1497599280], [0.04, 1497599340], [0.03, 1497599400], [0.02, 1497599460], [0.05, 1497599520], [0.04, 1497599580], [0.03, 1497599640], [0.03, 1497599700], [0.04, 1497599760], [0.05, 1497599820], [0.04, 1497599880], [0.04, 1497599940], [0.04, 1497600000], [0.04, 1497600060], [0.03, 1497600120], [0.03, 1497600180], [0.02, 1497600240], [0.01, 1497600300], [0.01, 1497600360], [0.01, 1497600420], [0.04, 1497600480], [0.04, 1497600540], [0.03, 1497600600], [0.03, 1497600660], [0.02, 1497600720], [0.04, 1497600780], [0.04, 1497600840], [0.03, 1497600900], [0.03, 1497600960], [0.02, 1497601020], [0.01, 1497601080], [0.01, 1497601140], [0.01, 1497601200], [0.01, 1497601260], [0.01, 1497601320], [0.01, 1497601380], [0.01, 1497601440], [0.01, 1497601500], [0.01, 1497601560], [0.01, 1497601620], [0.63, 1497601680], [1.29, 1497601740], [1.87, 1497601800], [2.4, 1497601860], [2.74, 1497601920], [2.36, 1497601980], [1.93, 1497602040], [1.58, 1497602100], [1.29, 1497602160], [1.7, 1497602220], [2.26, 1497602280], [2.77, 1497602340], [3.1, 1497602400], [3.37, 1497602460], [3.09, 1497602520], [2.56, 1497602580], [2.09, 1497602640], [1.71, 1497602700], [1.4, 1497602760], [1.16, 1497602820], [0.95, 1497602880], [0.78, 1497602940], [0.63, 1497603000], [0.52, 1497603060], [0.42, 1497603120], [0.35, 1497603180], [0.28, 1497603240], [0.23, 1497603300], [0.19, 1497603360], [0.16, 1497603420], [0.13, 1497603480], [0.12, 1497603540], [0.1, 1497603600], [0.08, 1497603660], [0.07, 1497603720], [0.05, 1497603780], [0.07, 1497603840], [0.06, 1497603900], [0.05, 1497603960], [0.04, 1497604020], [0.03, 1497604080], [0.03, 1497604140], [0.02, 1497604200], [0.02, 1497604260], [0.01, 1497604320], [0.01, 1497604380], [0.01, 1497604440], [0.01, 1497604500], [0.01, 1497604560], [0.01, 1497604620], [0.01, 1497604680], [0.01, 1497604740], [0.01, 1497604800], [0.01, 1497604860], [0.04, 1497604920], [0.05, 1497604980], [0.06, 1497605040], [0.08, 1497605100], [0.06, 1497605160], [0.07, 1497605220], [0.06, 1497605280], [0.04, 1497605340], [0.05, 1497605400], [0.04, 1497605460], [0.03, 1497605520], [0.03, 1497605580], [0.02, 1497605640], [0.02, 1497605700], [0.01, 1497605760], [0.01, 149760

Um die Daten leserlich in der Konsole aufzubereiten, empfiehlt es sich “python -m json.tool” als Formatierungshilfe zu verwenden.

curl 'http://192.168.100.101/render/?target=icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value&from=-3hours&format=json' | python -m json.tool

Um die JSON-Daten in der Console zu visualisieren kann man Zach Holman’s Spark verwenden:

[root@graphite ~]# curl 'http://192.168.100.101/render/?target=icinga2.icinga3op_foreman_local.services.load.load.perfdata.load5.value&from=-3hours&format=json' | python -mjson.tool | grep ',' | grep -v '\]' | spark
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3695 0 3695 0 0 230k 0 --:--:-- --:--:-- --:--:-- 240k
▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▃▅▅▅▃▃▃▃▅▅███▅▅▃▃▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

 

Conclusio

Das war nur ein kleiner und rudimentärer Überblick was über die Render-API möglich ist. Jedoch bietet sie genügend Anregung um mehr mit Graphite, Icinga 2 und Metriken zu machen. Die Render-APi bietet zudem die Möglichkeit, programmatisch in Scripts darauf zuzugreifen. Mir hat es zumindest Lust auf mehr gemacht und ich denke, dass ich noch weitere Blogposts zu diesem Thema schreiben werde 🙂

Falls ihr nicht warten könnt, hier nochmal der Link zur Doku. Oder ihr schaut einfach mal bei uns in der Graphite-Schulung vorbei und lernt die Render-API am praktischen Beispiel kennen.

Daniel Neuberger

Autor: Daniel Neuberger

Nach seiner Ausbildung zum Fachinformatiker für Systemintegration und Tätigkeit als Systemadministrator kam er 2012 zum Consulting. Nach nun mehr als 4 Jahren Linux und Open Source Backup Consulting zieht es ihn in die Welt des Monitorings und System Management. Seit April 2017 verstärkt er das Netways Professional Services Team im Consulting rund um die Themen Elastic, Icinga und Bareos. Wenn er gerade mal nicht um anderen zu Helfen durch die Welt tingelt geht er seiner Leidenschaft für die Natur beim Biken und der Imkerei nach und kassiert dabei schon mal einen Stich.