Timelion, eine Kibana Erweiterung

timelion logoIch habe mich in der Vergangenheit mit verschiedenen Tools beschäftigt die Performancedaten bzw. Metriken speichern und darstellen können. Aktuell beschäftige ich mich näher mit Timelion aus dem Hause Elastic und das hat zwei Gründe: Zum einen wurde mir die Kibana Erweiterung auf der ElasticON letzte Woche wieder schmackhaft gemacht, nachdem ich es eigentlich schon zur Seite gelegt hatte. Zum anderen erweist sich Timelion als sehr nützlich in Verbindung mit meinem Icingabeat. Ein Beat der Daten aus Icinga 2 zur weiteren Verarbeitung entweder an Logstash oder direkt an Elasticsearch schicken kann.
Timelion, übrigens Timeline ausgesprochen, ist eine Erweiterung für das bereits bekannte Kibana Webinterface. Es ist dazu gedacht Daten aus einem Elasticsearch Cluster visuell darzustellen. Anders als die bisherigen Visualisierugsmethoden von Kibana wird bei Timelion aber nichts zusammen geklickt und gefiltert. Stattdessen müssen die eingebauten Funktionen direkt aufgerufen und mit Parametern gefüllt werden. Klingt erst mal kompliziert, nach etwas Übung geht das aber schneller als alles mit der Maus zu bedienen.
Ein Beispiel: Um die Anzahl der Dokumente in Elasticsearch zu zählen, wird die Funktion es() verwendet. Sie erwartet als Parameter eine Query. Mit es(*) werden sämtliche Dokumente gezählt, die Query dabei ist *
timelion default query
Als Query kann alles eingegeben werden was das normale Kibana Interface auch versteht, also Apache Lucene Syntax. Zum Beispiel kann ich die Anzahl der Checkresults darstellen, die mein Icinga gerade ausführt: .es(type:icingabeat.event.checkresult)timelion icingabeat checkresults
Einfach Dokumente zu zählen reicht aber oft nicht aus, insbesondere im Hinblick auf Metriken. Wichtig an dieser Stelle ist der eigentliche Wert von einem Eintrag, nicht die Anzahl der Einträge. Die es() Funktion kann mit ihrem metric Parameter genau das tun. Man muss sich lediglich entscheiden mit welcher Methode man die Daten aggregieren möchte. Auch wenn die Daten nicht in einem definierten Zeitrahmen in Elasticsearch gespeichert werden, müssen sie spätestens bei der Darstellung irgendwie zusammengefasst werden um einen gleichmäßigen Graphen anzeigen zu können. Timelion versucht den Abstand in dem Daten aggregiert werden automatisch zu ermitteln, meistens ergibt das “Sekündlich”. Ob das der richtige Intervall ist, hängt davon ab wie schnell die Daten rein fließen. Wie viele MySQL Queries Icinga 2 innerhalb der letzten Minute ausgeführt hat, lässt sich zum Beispiel folgendermaßen ermitteln:
.es(metric=avg:perfdata.idomysqlconnection_ido-mysql_queries_1min.value).label("1 min").title("MySQL Queries").color(green)timelion icingabeat mysql
Hier sieht man auch das sich mehrere Funkionen aneinander ketten lassen. Zum Beispiel zum setzen von Titel oder Farbe. Timelion bringt eine ganze Fülle an Funktionen mit die die Darstellung der Daten beeinflussen. Ich will nicht alle aufzählen, weitere Beispiele aber sind:

  • bars(): Ein Barchart anstelle einer Linie
  • movingaverage(): Berechnet den gleitenden Durchschnitt
  • min(), max() und sum(): Erklärt sich von selbst

Es können auch mehrere Linien innerhalb eines Graphen angezeigt werden, dazu wird die Funktion einfach mehrfach aufgerufen. Hier ein vergleich der Ausführungszeiten von Icinga Plugins:
.es(metric=avg:status.avg_execution_time), .es(metric=avg:status.max_execution_time), .es(metric=avg:status.min_execution_time) timelion icingabeat execution time
Insgesamt ist das nur ein kleiner Teil dessen was Timelion kann. Auch wenn die Bedienung etwas gewöhnungsbedürftig ist, so kommt man nach etwas Übung schnell rein. Die Graphen die erstellt werden können entweder als eigenständige Dashboards abgespeichert werden oder als einzelne Visualisierungen. Werden die Graphen einzeln abgespeichert können Sie zu Kibana Dashboards hinzugefügt werden. Dadurch ergibt sich eine gute Ergänzung zu den normalen Visualisierungen.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Monitoring Plugins in Go

Auf Twitter hat Jan Schaumann vor Kurzem begonnen eine Liste aufzustellen mit Dingen, die jeder Sysadmin in seinem Leben schon mindestens ein mal getan hat. Darunter zählen Sachen wie einen Parser für den ifconfig Befehl zu schreiben oder unvollständige Regexes für IP Adressen zu basteln. Beim Durchgehen dieser Liste habe ich mich immer wieder selbst ertappt. Es ist erschreckend, wie viele von diesen Dingen auf einen selbst zutreffen. Dennoch ist es sehr amüsant zu lesen.
Bei Netways arbeiten wir sehr viel im Bereich Monitoring. So ist es kein Wunder, das ich bei den Dingen die jeder Sysadmin schon mal getan hat, sofort auch an dieses Thema denken musste. Lange muss man da auch nicht überlegen: Jeder Sysadmin hat mindestens schon ein mal in seiner Karriere ein monitoring Plugin geschrieben. Das gehört einfach dazu und selbst DevOps wird uns vermutlich nicht davor bewahren.
Das Schreiben von monitoring Plugins ist auf den ersten Blick ein ziemlich einfaches Thema. So ein Plugin muss einen Rückgabewert von 0, 1 oder 2 liefert und im besten Fall einen Text ausgeben, der den Zustand beschreibt. Damit wären schon mal alle Grundvoraussetzungen gegeben. Weil es eben so einfach ist, gibt es auch so viele von diesen Plugins. Sie werden in nahezu jeder Programmiersprache geschrieben. Manche Plugins sind umfangreich mit vielen Optionen und noch mehr Performance Daten in der Ausgabe. Andere wiederum bestehen nur aus wenigen Zeilen und erfüllen einen einzigen speziellen oder simplen Zweck.
Was mich bei monitoring Plugins schon immer gestört hat, ist das Deployment von jenen. Je nachdem in welcher Sprache das Plugin entwickelt ist, müssen mit cpan, gem, pip, npm, pear, composer oder andern Package Managern Abhängigkeiten nachinstalliert werden. So richtig lästig wird das bei ein paar Hundert Plugins für ein paar Tausend Server mit unterschiedlichen Distributionen. Sind Windows Systeme dabei, … ach davon fang ich garnicht erst an.
Welche Lösung gibt es also dafür? Noch keine fertige, zumindest meiner Meinung nach. Selbst Configuration Management löst das Problem nicht ganz. Um das vernünftig zu machen, müsste man ja seine 3-Zeiler Plugins packetieren und vernünftige Module oder Cookbooks schreiben, die das dann auf die Systeme ausrollen. Bestenfalls natürlich auf jedes System nur die Plugins die dort auch wirklich hin gehören. Seitdem ich mich bezüglich eines Projekts aber mit der Programmiersprache Go auseinander setze, beschäftigt mich ein anderer Ansatz um das Problem zu lösen: was wäre, wenn so ein Plugin gar keine Abhängigkeiten hat?
Go ist eine Programmiersprache, deren Wurzeln bei C liegen. Sie ist dementsprechend auch keine Scriptsprache wie Ruby oder Python, fühlt sich manchmal aber trotzdem so an. Das führt dazu das Leute wie ich, die aus der Scripting Welt kommen, sich sehr schnell wohl fühlen mit Go. Ob Go eine objektorientierte Sprache ist, da scheiden sich die Geister. Objekte im klassischen Sinne gibt es nicht, zumindest werden sie nicht so genannt. Betrachtet man es im Detail, kann man aber nachvollziehen warum es Stimmen gibt, die Go als objektorientiert bezeichnen.
Wie bei anderen Sprachen auch gibt es bei Go viele Libraries die verwendet werden können, sie werden aber Packages genannt. Der in Go geschriebene Code muss kompiliert werden. Ein großer Vorteil dabei ist, dass die entstandenen Binaries standardmäßig statisch gelinkt sind. Das heißt im Umkehrschluss es muss nichts nachinstalliert werden mit gem, pip, cpan usw. Alles steckt schon in dieser einen Binary. Sicherlich lässt sich dasselbe auch mit C, C++ oder anderen Sprachen erreichen. Keine ist aber so einfach und einsteigerfreundlich wie Go. Das zählt für mich als sehr großer Vorteil, schließlich werden diese Plugins oft von Sysadmins entwickelt, deren Hauptbeschäftigung nicht das Programmieren ist.
Statisch gelinkte Binaries könnten also das Problem der Abhängigkeiten lösen. Spinnt man die Idee weiter, könnte man mit einem “monitoring plugin” Package für Go ein Framework schaffen mit dem einheitliche Plugins entwickelt werden. Eine tolle Idee, wenn ihr mich fragt. Das Problem des packetierens lässt sich übrigens wunderbar mit fpm lösen, dazu aber vielleicht ein anderes Mal mehr.
Mein Aufruf an dieser Stelle also: Schreibt eure monitoring Plugins in Go, denn ich möchte mich nicht stundenlang damit Beschäftigen sie zum Laufen zu kriegen!

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

RSpec Tests mit rspec-puppet-facts

Auf gefühlt jeder Konferenz gibt es mittlerweile mindestens einen Talk rund um das Thema testing im Configuration Management Umfeld. Obwohl ich bei NETWAYS schon länger mit Puppet arbeite, ist dieses Thema bis jetzt noch nicht so richtig bei mir aufgeschlagen. Jetzt hat es mich aber doch erwischt. Mit dem Icinga2 Chef Cookbook hatte ich meine ersten Berührungspunkte mit RSpec und Serverspec. Das gesammelte Know-How kann ich nun in unserem aktuellen Projekt, einem Rewrite vom Icinga2 Puppet Modul, ganz gut verwenden.
Eine Sache in Verbindung mit RSpec hat mich allerdings gestört: Auch wenn die Tests in der Regel relativ generisch sind, abhängig von Betriebssystem und Version können dennoch unterschiedliche Ergebnisse beim gleichen Test auftreten. Es wäre also hilfreich, alle Tests für alle Betriebssysteme und Versionen auszuführen, die man mit seinem Modul auch unterstützen möchte.
rspec-puppet-facts
Genau das oben genannte kann man mit de Gem rspec-puppet-facts erreichen. Ein kleines Beispiel:
Ein simpler Test für eine Klasse sieht klassischer Weise so aus:

  context "on debian 7" do
    let(:facts) do
      {
        :osfamily                  => 'Debian',
        :operatingsystem           => 'Debian',
        :operatingsystemmajrelease => '7',
      }
      it { is_expected.to compile.with_all_deps }
    end
  end
  context "on centos 6” do
    let(:facts) do
      {
        :osfamily                  => ‘RedHat’,
        :operatingsystem           => ‘CentOS’,
        :operatingsystemmajrelease => '6',
      }
      it { is_expected.to compile.with_all_deps }
    end
  end

So müsste man jetzt für jede Distribution und jede Version jeden Test schreiben/kopieren. Unter Verwendung von rspec-puppet-facts können die unterstützten Betriebssysteme samt Versionen aus der metadata.json angezogen werden. In dieser Datei sollten die Informationen darüber, unter welchen Voraussetzungen das Modul lauffähig sein soll, ohnehin schon stehen. Vorausgesetzt man hat die Datei korrekt befüllt natürlich. Basierend darauf werden dann Puppet Facts bereitgestellt und man kann über diese iterieren. Die oben beschriebenen Tests können dann also so aussehen:

  on_supported_os.each do |os, facts|
    context "on #{os}" do
      let(:facts) do
        facts
      end
      it { is_expected.to compile.with_all_deps }
    end
  end
Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Chef Cookbook Integration Tests mit TestKitchen

Infrastructure as Code ist zu einem der wichtigsten Themen angewachsen mit denen sich Admins und ganze IT Abteilungen beschäftigen. Wie immer wenn es um Code geht, spielt die Qualität von diesem eine wichtige Rolle. Wenn man seine Chef Cookbooks nicht gerade nur für sich selbst schreibt, sondern gern auch veröffentlichen möchte, gehört Qualität zum guten Ton. Eines der Qualitätsmerkmale ist die Anwendbarkeit des Cookbooks auf verschiedene Betriebssysteme und Versionen. Hier beginnt auch schon die Schwierigkeit: Oft wird ein Cookbook für das System geschrieben das man selbst verwendet, schlicht, weil man andere Systeme ja nicht zum Testen hat. Sicherlich ist die Zeit ein wichtiger Faktor dabei, es hat aber auch kaum jemand Lust dazu sich mit der Installation von mehreren VMs zu beschäftigen. Um richtig testen zu können, müssen diese ja auch regelmäßig zurückgesetzt werden. Abhilfe schafft da das Chef Development Kit (ChefDK).
ChefDK
Im Development Kit sind alle Tools enthalten die man braucht zum Cookbooks zu entwickeln, testen und maintainen. Es ist zudem für alle großen Betriebssysteme verfügbar. Mit dem Commandline tool chef kann man die ersten Schritte gehen: Cookbook generieren, templates anlegen etc. Auch mit dem zentralen Server kann man kommunizieren, etwa um Cookbooks zu installieren. Ein Chef Client ist im Kit auch enthalten, mit ihm lassen sich Cookbooks direkt ausführen. Das Chef Ökosystem bietet relativ viel um Cookbooks zu testen, das Wichtigste ist im ChefDK mit drin:

  • TestKitchen Ein Framework zum erstellen und ausführen von Integration Tests
  • ChefSpec Unit testing auf Basis von RSpec
  • Foodcritic Code Analyse basierend auf festgelegten Regeln
  • Cookstyle Ruby code Analyse basierend auf RuboCop

TestKitchen
Nun also zurück zum Problem mit dem testen von verschiednen Betriebssystemen und deren Versionen. TestKitchen zielt genau darauf ab, dieses Problem zu lösen. In einer Yaml Datei (.kitchen.yml) wird eine Testmatrix angelegt die festlegt, was genau getestet werden soll. Dazu gehören die Betriebsysteme, deren Versionen und eine oder mehrere Suites die auf diese angewendet werden sollen. Suites bestehen aus einer Liste von Recipes die ausgeführt werden. Dazugehörige Attribute können ebenfalls gesetzt werden. Beispielhaft sieht das dann so aus:

---
driver:
  name: vagrant
provisioner:
  name: chef_zero
platforms:
  - name: ubuntu-16.04
  - name: centos-7.2
  - name: windows-2012r2
suites:
  - name: icinga2server
  run_list:
    - recipe[icinga2::server]
  attributes:
    icinga2:
      version: '2.4.10-1'

Mit dem CLI Kommando kitchen kann das Cookbook jetzt auf den aufgelisteten Plattformen ausgeführt werden. Voraussetzung in diesem Beispiel ist, dass Vagrant installiert ist. Auch andere Driver können verwendet werden, Beispiele dafür wären Docker, HyperV oder OpenNebula. Eine gesamte liste findet man in der Dokumentation.

kitchen test

Das Kommando führt ein mal den gesamten Ablauf durch: VMs erstellen, Cookbook ausführen, Zustand prüfen und VMs wieder zerstören. Für jede Kombination zwischen Plattform und Suite werden mithilfe von Vagrant virtuelle Maschinen erstellt. Die dazugehörigen Boxen werden Standardmäßig von Bento angezogen. Beim ausführen sollte man aber vorsichtig sein, je nachdem wie viele Tests und Plattformen man aufgelistet hat, kann das zu relativ vielen VMs führen, was dann gerne auch mal dazu führt, dass das eigene System lahmgelegt wird.
Um das Problem zu umgehen können einzelne Instanzen erstellt werden, indem man genau angibt welche Kombination man testen möchte:

kitchen setup server-ubuntu-1604

Dieses Kommando wird eine VM mit Ubuntu 16.04 erzeugen, einen Chef Client auf dieser installieren und das Cookbook ausführen. Im Idealfall steht dann eine VM auf dem das Cookbook erfolgreich ausgeführt wurde. Man kann sich auf dieser dann auch einloggen, um ggf. manuell zu prüfen ob alles glatt gelaufen ist:

kitchen login icinga2server-ubuntu-1604

Eine Liste aller Instanzen bekommt man mit kitchen list
Zu diesem Zeitpunkt hat man zumindest die Gewissheit, dass das besagte Cookbook generell lauffähig ist und keine Fehler wirft. Ob aber tatsächlich der gewünschte Zustand erreicht ist, ist noch unklar. In Kombination mit TestKitchen lässt sich ein Zustand am besten mit ServerSpec ermitteln.
ServerSpec
Mit ServerSpec werden RSpec Tests geschrieben die den tatsächlichen Zustand eines hosts prüfen. Es wird nicht nur in Kombination mit Chef verwendet, sondern auch mit den meisten anderen Configuration Management Tools.
TestKitchen erwartet die ServerSpec Tests im Verzeichnis test/integration. Jede Suite erhält ihr eigenes Verzeichnis in dem die entsprechenden Dateien liegen in denen beschrieben ist was geprüft werden soll:

test
`-- integration
|-- icinga2server
| `-- serverspec
| |-- icinga2server_spec.rb

Beispielhaft könnte eine icinga2server_spec.rb folgenden Inhalt haben:

require 'serverspec'
require 'pathname'
set :backend, :exec
set :path, '/bin:/usr/local/bin:$PATH'
describe package(“icinga2”) do
  it { should be_installed }
end
describe service('icinga2') do
  it { should be_running }
end

Dabei wird geprüft ob auf dem System das Paket icinga2 tatsächlich installiert ist und ob der Service icinga2 läuft. Ausgedrückt werden Tests in einer relativ einfach verständlichen “Sprache”, da Begriffe und Aufbau stark an die menschliche Sprache angelehnt sind.
Aus den vorherigen Schritten sollte mindestens schon eine VM bereit stehen auf der die ServerSpec tests jetzt angewendet werden können:

kitchen verify icinga2server-ubuntu-1604

Im besten Fall ist die Ausgabe positiv

bsheqa@blerims-mbp ~/git/github/chef-icinga2 (feature/testkitchen-12286) $ kitchen verify client-ubuntu-1404
-----> Starting Kitchen (v1.10.2)
-----> Verifying ...
Preparing files for transfer
[…]
Package "icinga2"
should be installed
Service "icinga2"
should be running
Finished in 0.14585 seconds (files took 0.36682 seconds to load)
2 examples, 0 failures
Finished verifying (0m2.89s)

Mit diesem gesamten Workflow nimmt TestKitchen einem sehr viel Arbeit ab, die man sonst verwenden müsste, um virtuelle Maschinen zu pflegen und nachzusehen, ob alles so angewendet wurde, wie es im Cookbook beschrieben ist. Integration Tests selbst helfen dabei ein Gefühl dafür zu bekommen, wie sich das Cookbook als Ganzes unter verschiedenen Umgebungen mit unterschiedlichen Attributen verhält. Mit entsprechenden ServerSpec Tests gewinnt man endgültig die Sicherheit, das alles wirklich so funktioniert, wie es soll.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Graphite – Die Geschichte eines Datenpunkts

Graphitgraphite-logoe ist tot. So zumindest ist die Meinung vieler auf Twitter und Co. Ein ganz anderes Bild zeigt sich allerdings in den Github Repositories. In kurzen Zeitabständen wird von mehreren Entwicklern commited. Bugs werden gefixt und Features implementiert. Die Geschwindigkeit, in der es Releases gibt, könnte natürlich schneller sein. Software wird aber nicht automatisch besser durch hohe Versionsnummern, das haben andere schon oft bewiesen. Das Projekt ist also alles andere als tot. Ganz im Gegenteil, sogar ein schönes neues Logo gibt es.
Was unser Interesse geweckt hat
Doch was ist es, das Graphite so interessant für viele Devs und Ops macht? Die I/O die es auf den Festplatten verursacht ist es mit Sicherheit nicht. Auch das verwalten dieser Whisper Dateien, samt Storage Schema und Aggregation Methods bereitet vermutlich den wenigsten von uns Spaß. Graphite hat etwas gebracht, was kein anderer auf diese Art und Weise hatte: eine API auf Metriken. Nicht nur das, sogar Funktionen zum Gruppieren, Transformieren und Filtern sind enthalten. Plötzlich ist es so einfach, Datenpunkte darzustellen und Graphen in eigene Tools einzubauen. Dem Kollegen mal eben einen maßgefertigten Graphen schicken? Kein Problem. Was bei RRD noch zu Kopfschütteln und knirschenden Zähnen, noch schlimmer: zu Perl Skripten geführt hat, ist nun ganz einfach und selbstverständlich. Graphite hat die Art und Weise wie wir mit Graphen umgehen verändert. Und das ist auch gut so.
Wichtig beim Thema Skalierung: SSDs
Das Thema der Skalierung ist und bleibt dennoch eine Herausforderung. Weil es eben so einfach zu verwenden ist, landen mit der Zeit mehr und mehr Daten in der Datengrube. Das System muss mitwachsen, andernfalls besteht die Gefahr, Daten zu verlieren. Es werden viele kleine Datensätze in kurzen Zeitabständen geschrieben. Am besten kann das natürlich mit SSDs abgefangen werden. Wem SSDs für das Gesamtsetup zu teuer sind, der kann sich mit Facebooks Flashcache einen Cache basteln und die permanente Lagerung auf mechanische Platten verschieben.
Die Geschichte eines Datenpunkts
So ein Datenpunkt beginnt seine Reise in der Regel auf einem Server. Dort wird er aufgesammelt von einem Collector, beispielsweise CollectD, Icinga2 oder Diamond. In voller Geschwindigkeit geht es dann Richtung Graphite. Sofern das Setup nicht minimal gehalten wurde, wartet dort eine ganze Kette an Carbon Daemons, angeführt vom Carbon Relay. Diese erste Aufprallstelle nimmt alle Metriken entgegen und verwaltet sie in Queues. Jedes nachgelagerte Ziel (Aggregator oder Cache) bekommt seine eigene. Wie voll diese Queue ist, hängt davon ab, wie schnell die Anschlussstelle (Aggregator oder Cache) die Metriken abarbeiten kann. Läuft diese Queue voll, werden Datenpunkte verworfen. Genau so verhält sich auch der Carbon Aggregator. Die Standardeinstellung MAX_QUEUE_SIZE sollte also regelmäßig überprüft werden.
graphite-queues-and-caches
Carbon Cache als zentrale Stelle
Sehr ähnlich verhält sich Carbon Cache. Er erstellt für jeden Metrikpfad eine eigene Queue. In jeder dieser Queues werden die dazugehörigen Datenpunkte gesammelt, so können später in einer einzigen Schreiboperation mehrere Datenpunkte auf ein Mal geschrieben werden. Das spart I/O, die Daten liegen aber so lange im RAM. Mit der Einstellung CACHE_WRITE_STRATEGY kann eine Strategie ausgewählt werden, mit der Daten geschrieben werden. Ein “Writer Thread” arbeitet diese Queues ab und schreibt die Datenpunkte in die entsprechenden Whisper Dateien. Diese einzelnen Queues können zwar prinzipiell erst mal nicht volllaufen, der gesamte Cache kann es aber. Mit der Option MAX_CACHE_SIZE wird eine Größe festgelegt, die für die Gesamtheit aller Metrik-Queues gilt.
Am besten erzählt der die Geschichte, der sie erlebt hat
Diese Geschichte eines Datenpunkts wird von den Carbon Daemons selbst erzählt. Natürlich in Bildern, mit Graphen. Alle diese Daemons speichern Messwerte über sich selbst. Anhand dieser lässt sich genau verfolgen, wie sich das Setup verhält. Die wichtigsten Metriken dabei sind:

  • Relay
    • metricsReceived – Anzahl der empfangenen Metriken
    • sent – Anzahl der weitergeleiteten Metriken, aufgeschlüsselt pro Ziel
    • relayMaxQueueLength – Aktuelle größe der Queue
    • fullQueueDrops – verworfene Metriken, aufgrund von vollen Queues
  • Aggregator
    • metricsReceived – empfangene Metriken, sollte mit der Anzahl gesendeter Metriken vom Relay übereinstimmen
  • Cache
    • cache.queues – Anzahl der Metrik-Queues
    • cache.size – Summe aller Datenpunkte in allen Metrik-Queues
    • pointsPerUpdate – Anzahl der Datenpunkte die pro Schreiboperation geschrieben werden
    • avgUpdateTime – So lange dauert eine Schreiboperation im Durchschnitt

Das sind natürlich nicht alle, Geschichten brauchen schließlich viel mehr Details. Alle drei Daemons liefern auch Daten über die Ausnutzung von CPU, Speicher und viele weitere Messwerte.
So endet die Reise des Datenpunkts in seinem letzten Ziel: der Whisper Datei. Dort wird er wieder und wieder abgefragt, zu Zwecken der Darstellung. Bis seine Zeit abgelaufen ist und er überschrieben wird, damit endet die Reise dann endgültig.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

CoreOS – Cluster Discovery

Bei der Einrichtung eines neuen CoreOS Clusters muss man sich für eine Variante entscheiden, mit der sich die einzelnen Server untereinander bekannt machen. In Wirklichkeit ist es auch kein CoreOS-, sondern ein etcd-Cluster. Der Key-Value Store, etcd genannt, ist die Kernkomponente die dazu genutzt wird, Informationen über mehrere Server hinweg zu speichern. Im ersten Schritt müssen diese Nodes aber davon in Kenntnis gesetzt werden, dass sie zusammengehören. Wissen sie erst mal voneinander, finden sie auch den weg zueinander. Etcd besitzt mehrere Mechanismen, um diesen ersten Kontakt herzustellen. Bekanntermaßen werden die einzelnen CoreOS Dienste in der cloud-config konfiguriert. Diese Datei wird beim Start geladen und umgesetzt. Meine unten aufgeführten Beispiele stellen keine vollständige cloud-config dar, lediglich die relevanten Teile einer solchen.

Initial Cluster State

Viel Frust kann man sich sparen, indem man die Option initial-cluster-state richtig verwendet. Wird ein neues etcd-Cluster erstellt, muss diese Einstellung auf new gesetzt sein. Fügt man hingegen eine Node einem Cluster hinzu, ist der Wert zwingend auf existing einzustellen. Andernfalls wird der neue Server trotz Discovery Mechanismen versuchen ein neues Cluster zu initiieren.

Statische Konfiguration

Bei einer statischen Konfiguration werden alle Nodes in der cloud-config fest eingetragen. Kommen Server hinzu oder fallen sie weg, muss die Konfiguration ebenfalls angepasst werden.

#cloud-config
coreos:
  etcd2:
    listen-client-urls: http://0.0.0.0:2379
    listen-peer-urls: http://$private_ipv4:2380
    initial-cluster: srv1=http://10.0.0.1:2380,srv2=http://10.0.0.3:2380,srv3=http://10.0.0.3:2380

Diese Art der Konfiguration bietet sich an, wenn alle Nodes dieselbe cloud-config laden. Die Anzahl der Server sollte sich nicht oft ändern, da man sonst viel Zeit mit dem Umbau der Konfiguration verbringt. Durch die festen Einträge geht viel von der Dynamik verloren, die CoreOS so charmant macht. Mal eben Server dazu zu stellen oder abbauen ist nicht mehr ohne Weiteres möglich.

etcd.io Discovery Service

Die Macher von etcd haben einen Service im großen weiten Internet stehen, so wie sich das für ein anständiges Tool in der heutigen Zeit nun mal gehört. Bei diesem Service lassen sich unter einer eindeutigen ID die eigenen CoreOS/Etcd Nodes eintragen und verwalten. Das muss nicht manuell gemacht werden, sondern geschieht automatisch nach Angabe bestimmter Parameter.
Das ganze funktioneirt so:

    1. Man erstellt eine neue, eindeutige ID. Unter dieser werden die eigenen Einträge dann gespeichert.
      curl 'https://discovery.etcd.io/new?size=3'
    2. Die URL die man geliefert bekommt, wird dann in der cloud-config hinterlegen. Somit weis etcd beim Start automatisch wo er sich anzumelden hat. Zusätzlich bekommt er dort Informationen über bestehende Nodes.
#cloud-config
coreos:
  etcd2:
    listen-client-urls: http://0.0.0.0:2379
    listen-peer-urls: http://10.0.0.1:2380
    discovery: https://discovery.etcd.io/e8bd58c845d69485b1d0767541bc72bd

DNS Discovery

Hier kommt mein persönlicher Favorit. Es ist quasi eine Kombination aus den zwei genannten Variationen. Bei der DNS Discovery werden unter einer festgelegten Subdomain DNS SRV Einträge gesetzt. Jeder Host der Teil des etcd-Clusters ist, wird eingetragen. Beim Start eines Servers fragt er selbstständig die hinterlegte Subdomain ab und erfährt somit die Hostnamen aller im Cluster vorhandenen Server.

~> dig -t SRV +short _etcd-server._tcp.coreos.netways.de
0 100 2380 node1.coreos.netways.de.
0 100 2380 node2.coreos.netways.de.
0 100 2380 node3.coreos.netways.de.
0 100 2380 node4.coreos.netways.de.
0 100 2380 node5.coreos.netways.de.

Die cloud-config muss entsprechend konfiguriert werden.

#cloud-config
coreos:
  etcd2:
    discovery-srv: coreos.netways.de
    listen-client-urls: http://0.0.0.0:2379
    listen-peer-urls: http://node1.coreos.netways.de:2380
Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Logging mit Docker

Wir beschäftigen uns bei Netways viel mit den Themen Logging, Log Management und der Visualisierung eben dieser. Kein Wunder, gehört Logging doch mit zu den essenziellen Teilen eines jeden guten Monitorings. Logs sind seit jeher sowohl für Entwickler auch als auf Adminitratoren wichtig, also quasi total devops. So zieht sich dieses Thema mit der Zeit durch alle Techniken während immer weiter neue Lösungen entwickelt und alte verbessert werden. Es ist also keine Überraschung das es auch in Bezug auf Docker, dem größten Hype überhaupt in letzter Zeit, nicht zu vernachlässigen ist. Wir werden oft gefragt, was denn jetzt nun die richtige Lösung ist  um an die Logs der geliebten Docker Container zu kommen. Nun, eine pauschalte Antwort darauf gibt es wohl nicht, ich kann aber einen Überblick geben.
Wenn wir über Docker und Logs reden ist es wichtig zu wissen, das es dabei (meist) ausschließlich um den Standard-Output des jeweiligen Containers geht. In der Regel besteht ein Container aus einem einzigen Prozess der die gewünschte Applikation startet und nichts weiter. Ein Syslog Daemon ist also nicht vorhanden und somit gibt es innerhalb des Containers auch kein richtiges Logging. Man könnte jeden Container aufblähen und ihm ordentliches Logging verpassen mit einem ordentlichen Syslog Daemon, der kategorisieren und an weitere Syslogs Server schicken kann. Die bevorzugte Variante ist jedoch alles nach stdout und sdterr zu schicken, da man darauf auch von außerhalb des Containers zugreifen kann.
Überblick
Docker unterstützt verschiedene Driver für das Logging. Anhand eines gewählten Drivers beim Start des Cointainers lässt sich steuern wohin Logs weitergeleitet werden. Zu jedem Driver gibt es Optionen die mitgegeben werden können.

   docker run --log-driver=... --log-opt ...

Immer wieder kommen mit neuen Docker Versionen neue Features oder gar neue Driver hinzu. Neben den verschiedenen Log Drivern lässt sich auch none einstellen, um das Logging komplett zu deaktivieren.
Der Standard
Zugegeben, Logging war zu Beginn nicht gerade ein priorisiertes Thema im Docker Projekt. Dennoch gibt es schon lange eine rudimentäre Stütze zum auslesen von Logs. Standardmäßig wird alles in json-Dateien geschrieben. Auslesen kann man diese dann am einfachsten mit dem docker logs Kommando.

   docker run -d ubuntu bash -c "while true; do echo `uptime`; sleep 10; done"
   docker logs 1a2e14a58c75
     10:53:34 up 4 days, 13:29, 4 users, load average: 0.38, 0.33, 0.35
     10:53:34 up 4 days, 13:29, 4 users, load average: 0.38, 0.33, 0.35

Der Alleskönner
Syslog ist der Alleskönner unter den Docker Logging Drivers. Unter Verwendung des Syslog Standards werden Logs an entfernte Daemons weitergeleitet. Das macht es lohnenswert diese für die weitere Verarbeitung und Analyse an Logstash zu schicken.

   docker run -i -t --log-driver=syslog --log-opt syslog-address=udp://logstash.netways.de:514 ubuntu bash -c "while true; do echo `uptime`; sleep 10; done"

Zusätzlich zum Syslog Server lassen sich auch ein paar weitere Optionen setzen:

   --log-opt syslog-facility=daemon
   --log-opt syslog-tag="myContainer"

Der Neue
Mit der Docker Version 1.8 verzeichnete das Projekt Graylog einen Erfolg in der Zusammenarbeit mit Docker. Ihr bekanntes Format GELF (Graylog Extended Log Format) wurde mit aufgenommen und ist seitdem als eigener Log Driver verfügbar. Da sich das Format nicht nur mit dem dazugehörigen Prodokut Graylog benutzen lässt, sondern auch von Logstash unterstützt wird, ist es eine echte alternative zum klassischen Syslog.

   docker run -i -t --log-driver=gelf --log-opt gelf-address=udp://logstash.netways.de --log-opt gelf-tag="myContainer" ubuntu bash -c "while true; do echo `uptime`; sleep 10; done"

Die Anderen
Die genannten Möglichkeiten sind nicht alle, es gibt auch Log Driver für FluentD und journald, dazu aber ein anderes Mal mehr.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Puppetcamp '15

Vergangenen Donnerstag ging für mich zum ersten mal das alljährliche Puppetcamp bereits am Abend vor dem eigentlichen Camp los. Gemeinsam mit Achim hatten wir die ehrenvolle Aufgabe eine “Kickstart Introduction” über Puppet zu halten. Bereits hier haben wir schon einen guten Eindruck von dem breit gefächerten Publikum des Puppetcamps bekommen. Vom Anfänger bis zum Mehrjährigen User waren alle Vertreten.
Die Keynote wurde danIMG_5443n von Nigel Kersten gehalten. Der CIO von Puppetlabs hat mit allgemeinen Informationen und Neuerungen rund um das Produkt Puppet und Puppetlabs schon Stimmung auf mehr gemacht. Selbst während den Fragerunden anderer Voträge konnte man immer wieder gut erleben, welches Fachwissen Nigel zu bieten hatte. Der daruaf folgenden Redner, Sebastian Reitenbach, hatte eine Geschichte zu erzählen wie sie jeder schon erlebt hatte der Puppet produktiv einsetzt und die jeden interessieren würde der das noch vor sich hatte. Vor gut einem Jahr hatte Sebastian nämlich noch überhaupt kein Configuration Management eingeesetzt. Nun konnte er aus dieser Einführungsphase von Puppet quasi noch ganz frisch erzählen was es heist die gesamte Arbeitsweise zu ändern. Viele Tipps und Tricks waren besonders an Einsteiger gerichtet und sollten so den Beginn vereinfachen.
Nach einerIMG_5466 kurzen Verschnaufpause ging es auch schon direkt weitere mit dem nächsten Speaker, Pedro Pessoa. Der konnte mit guten Anschaungsmaterial darstellen auf welche Weise Puppet bei seinem Arbeitgeber Server Density einesetzt wird. Das Unternehmen hat sich auf Hosted Server und deren Monitoring spezialisiert und arbeitet mit einer bereits 4 Jahre alten Codebasis, wobei sie sich immer mehr auf Module aus dem Puppet Forge stützen möchten. Im darauf folgenden Talk teilte Rajesh Sivaraman seine Erfahungen die er gemacht hatte bei der Integration von Puppet in CI (Continuous Integration) Umgebungen. Eindrucksvoll erklärte er in wenigen Minuten wie er lernte Jenkins für seine Zwecke zu nutzen um bestimmte Tasks verschiedenste Technologien wie Virtuelle Maschinen und auch Docker Container zu verteilen. Das ganze geschah natürlich mithilfe von Puppet.
 
Nur IMG_5520wenige Tage vor dem diesjährigen Puppetcamp in Berlin war das neue Puppet 4 erschieden. Natürlich waren allle ganz heiß darauf zu erfahren, welche Änderungen und Verbesserungen es geben würde. Das nahm Martin Alfke dann zum Glück auch zum Anlass und zeigte alle wichtigen Änderungen in der neuen Version. Trotz all der neuen Features und Performance Verbesserungen stellten am Ende doch alle ernüchternd fest das ein wechsel vom alten Puppet vermutlich nicht so einfach und schnell geschehen könnte, dennoch war die Motivation hoch die Ärmel hochzukrempeln und  die Migration anzugehen. Puppetmodule im Forge werden zudem in Zukunft die Kompatibilität zu verschiedenen Puppet Versionen anzeigen, damit es da nicht zu Verwechslungen kommt. Fast selbstverständlich hatte Nicholas Corrarello dann auch eine Live Demonstration von Puppet Enterprise zu bieten. Das Tool wird auch in naher Zukunft mit Puppet 4 umgehen können.
IMG_5528Nach einer letzten Pause ging es dann auf zum Endspurt, und der hatte es in sich. Felix Frank, der bereits sein eigenes Buch über Puppet veröffentlicht hatte, zeigte auf warum es so wichtig ist Puppet Code zu testen. Doch dabei belies es der erfahrenen Puppet Anwender nicht. Mit vielen Kniffen und Tricks konnte man bei ihm lernen wie einfach Testing und Debugging sein konnte. Die Wichtigkeit dieser Techniken bleibt unumstritten. Den Abschluss des Puppetcamps bot Andrea Giardini. Der CERN Mitarbeiter erklärte nicht nur in groben Zügen die gesamte CERN Umgebung, sondern ging auch in Details in deren Puppet Umgebung ein. Die Erkenntnis “Die Kochen ja auch nur mit Wasser” war aber nicht das Einzige was man aus diesem Vortrag mitnehmen konnte. In derart großen Umgebungen ist man plötzlich völlig anderen Herausforderungen gegenüber gestellt. Wie deren Lösung aussehen kann, konnte Andrea an diesem Tag sehr gut erklären.
Nachdem die Vorträge alle vorbei waren, haben sich viele der Teilnehmen zum weiteren sogenannten “socializen” in der Hoteleigenen Bar eingefunden. Natürlich, der gesamte Input des Tages wollte ja auch erst mal verdaut und besprochen werden und welche besser Möglichkeit gäbe es dazu als mit gleichgesinnten bei einem kühlen Berliner Bier.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Kibana 4

Vergangenen Februar war es endlich so weit, Kibana 4 wurde nach mehreren Beta Versionen und Release Candidates endlich final released. Weil wir es selbst kaum erwarten konnten, hatte ich bereits bei Erscheinung der ersten Beta in unserem Blog über die neuen Funktionen und Arbeitsweisen berichtet.
Viel hat sich seitdem dann auch nicht mehr geändert. Das primäre Ziel bleibt weiterhin die Visualisierung der Daten in mehreren Dimensionen. So lassen sich Balken und Kreisdiagramme beliebig oft schachteln und in Dashboards mit anderen Darstellungen wie Liniendiagrammen oder Weltkarten verknüpfen. Die Entwickler von Elastic haben stark an der Stabilität der einzelnen Features gearbeitet. Hier und da wurden kleine visuelle Unstimmigkeiten und überflüssige Schaltflächen bearbeitet oder ganz entfernt.
Diese kleinen Änderungen machen aber den Unterschied, insbesondere bei der täglichen Arbeit mit dem Tool macht sich das stark bemerkbar. Ebenfalls hinzu gekommen ist die Integration für das vor kurzem vorgestellte “Shield” Produkt, welches die Benutzer- und Zugriffsverwaltung eines Elastic Clusters erlaubt. So geht es mit der neuen Webanwendung mit immer größeren Schritten in Richtung “Enterprise” Anwendung und liefert damit eine echte Konkurrenz zu anderen, meist sehr teuren, Alternativen. Ans Ausruhen denkt offensichtlich aber keiner, denn die Version 4.1 ist schon in Arbeit und lässt auf weitere Features und Bugfixes hoffen.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.

Kibana im neuen Gewand

Einige Zeit war es relativ ruhig im Bereich Log Management mit Elasticsearch, Logstash und Kibana (ELK Stack). Jetzt tut sich jedoch was und wir können uns auf tolle neue Features freuen. Neben dem Update von Elasticsearch auf die Version 1.4.1 wird aktuell auch viel an der Visualisierungskomponente Kibana gearbeitet. Mit einer nicht vor allzu langer Zeit erschienenen Beta Version erhalten wir einen Blick in einen kompletten Rewrite der Browserbasierten Applikation. Kibana4 verfolgt ein neues Konzept und öffnet die Türen für neue Features.
Browserbasiert? Nicht nur!
Während Kibana sich in der aktuellen Version 3 selbst zum Elasticsearch Cluster verbindet, muss bei der neuen Version ein Daemon auf dem Server gestartet werden. Dieser kümmert sich um die Verbindung zum Elasticsearch und fungiert somit als eine Art Proxy. Das ist insbesondere in Hinsicht auf zukünftige Authentifizierungs und Authorisierungs-Plugins wichtig. Die Schnittstelle für Plugins bringt das neue Kibana nämlich auch gleich mit. Mit dem, kurz vor dem Release stehenden Security-Plugin für Elasticsearch, Shield, nähern wir uns mit großen Schritten einem mandantenfähigen und sicheren Log Management System.
Discover
Kibana4-discoverDas neue Konzept verfolgt eine Aufteilung in verschiedene Ebenen der Visualisierung. Die Unterste, bzw. erste, ist die Suche. In einem simplen Interface kann man seine Query verfassen und sichtbare Felder auswählen. Das Histogram fasst die Anzahl der gefundenen Logs zusammen und bietet einen Überblick. Wie gewohnt lassen sich einzelne Logs aufklappen und Filter auf einzelne Felder anwenden. Diese Ansicht dient dazu tatsächliche Log Meldungen zu suchen und zu verfolgen und hat noch wenig mit Visualisierung zu tun.
Visualize
Kibana4-visualize-step1In diesem Bereich wird es schon bunter. Die vorher durchgeführten Suchen können gespeichert und als Basis für die Visualisierung verwendet werden. Das ist jedoch nicht zwingend, es kann auch eine komplett neue und leere Suche benutzt werden. Der Visualisierungsteil verfolgt den Ansatz, Grafiken Schritt für Schritt zu erstellen. Das wird schon zu Beginn deutlich, indem man auswählen muss welche Art der Grafik man erstellen möchte und welcher Index dafür angezogen werden soll. In meinem Fall erstelle ich ein Kuchendiagramm. Im nächsten Schritt teile ich die Kuchenstücke nach dem “program” Feld auf. Die eigentliche Neuerung zeigt sich im zweiten Schritt. Das erstellte Diagramm kann jetzt nämlich noch weiter behandelt werden. So lassen sich die Kuchenstücke ein weiteres Mal aufteilen. Bei Barcharts und den anderen Visualisierungsarten funktioniert das ebenfalls.
Kibana4-visualize-step2Kibana4-visualize-step2-barchart
Dashboards
Kibana4-dashboardDie erstellten Graphen werden in Dashboards gesammelt dargestellt. Am oberen Ende steht, wie gewohnt, ein Query Feld und der Timepicker um die Darstellung einzuschränken.
Installation
Die Installation gestaltet sich sehr einfach. Nach dem Download steht schon alles Bereit was benötigt wird. Wie wir es von Logstash schon kennen, ist auch das neue Kibana in jRuby gepackt und setzt eine aktuelle Java Instalaltion voraus. Der Elasticsearch Cluster wird in der yaml-Formatierten Datei config/kibana.yaml konfiguriert, es wird mindestens eine Version 1.4 von Elasticsearch vorausgesetzt. Kibana muss dann nur noch mit bin/kibana gestartet werden und ist standardmäßig auf dem Port 5601 erreichbar.
Fazit
Das neue Kibana4 ist definitiv noch nicht reif für den Produktivbetrieb, aber das sagt ja das “Beta” im Namen schon. Die Idee der Aufteilung in verschiedene Ebenen finde ich sehr gelungen, auch wenn es mehr Verständnis erfordert und insbesondere in den Visualisierungsteil noch viel Arbeit gesteckt werden muss. Das Webinterface wirkt insgesamt aufgeräumter und macht durch die hellen Farben einen sanfteren Eindruck. Die Anordnung der Graphen ist deutlich verbessert worden, da die Größen immer einheitlich sind. Auch wenn es hier und da noch ein paar Bugs gibt und noch einige Feature Requests offen sind, so lohnt sich ein kurzer Blick auf jeden Fall. Neue Beta Versionen sind schon in Vorbereitung und lassen auf noch mehr Stabilität, Bugfixes und Features hoffen. Wann ein endgültiges Release geplant ist, lässt sich zum aktuellen Zeitpunkt noch nicht sagen.

Blerim Sheqa
Blerim Sheqa
Product Manager

Blerim ist seit 2013 bei NETWAYS und seitdem schon viel in der Firma rum gekommen. Neben dem Support und diversen internen Projekten hat er auch im Team Infrastruktur tatkräftig mitgewirkt. Hin und wieder lässt er sich auch den ein oder anderen Consulting Termin nicht entgehen. Inzwischen ist Blerim als Product Manager für Icinga tätig und kümmert sich dort auch um die Partner.