Distributed Monitoring mit Icinga2 und Puppet

Wir bei VSHN betreiben Applikationen auf Servern und Container Plattformen für Kunden mit verschiedensten Anforderungen. Dabei bilden neben dem Konfigurationsmanagement und der wöchentlichen Maintenance auch die täglichen Backups und natürlich das Monitoring die zentralen Punkte des proaktiven DevOps Betriebs. Bei aktuell über 600 managed Servern mit mehr als 30’000 Services wäre die manuelle Konfiguration sowie das Tuning des Monitorings und der Umsysteme wie InfluxDB, Grafana, etc. recht mühsam – darum haben wir dies komplett automatisiert.


In diesem Blog-Post zeigen wir, wie wir dies bewerkstelligen und wohin die Monitoring-Reise bei VSHN geht.

Architektur

Icinga2 ermöglicht ein komplett verteiltes Monitoring Setup, in dem auf jedem zu überwachenden System eine Icinga2 Instanz läuft. Jeder Client verbindet dann, meistens mit einer ausgehenden TCP Verbindung, verschlüsselt und über x509 authentifiziert, zur Master- oder der überliegenden Satelliten-Zone. Dies ist wichtig, da wir oft Systeme im Enterprise Umfeld betreiben, bei denen wir dann meistens auf einem Jumphost oder dediziert einen Satelliten betreiben. Anschliessend benötigt ausschliesslich dieser eine Verbindung ins Internet zu unserem Monitoring Master.

Des Weiteren kann so ein Server tagelang offline sein und trotzdem haben wir rückwirkend die komplette History und die Performance Daten (man kann auch rückwirkend Performance Daten in die InfluxDB schreiben), weil jede Icinga Instanz lokal ein Replay Log speichert und dieses anschliessend wieder an die überliegende Zone senden kann.

Eine Zone kann auch aus mehreren Icinga2 Instanzen (Servern) bestehen, um die Last zu verteilen und die Verfügbarkeit zu erhöhen.

Für die Authentifizierung und Autorisierung der VSHN- und Kunden-Benutzer ist Icingaweb2 ausserdem an unser zentrales LDAP angebunden. Eine Integration mit Grafana ermöglicht die Vorschau von Performance Data Grafiken direkt in Icingaweb2. Grafana greift auf InfluxDB zu, die wiederum von der Icinga2 Master Instanz mit Performance Daten befüllt wird.

Automatische Konfiguration

Alle unsere Server werden vollständig automatisiert mit Puppet konfiguriert. Dabei weisen wir via Hiera den Servern Rollen zu. Eine Rolle besteht wiederum aus Puppet Profilen (VSHN eigene Puppet Module, die meist auf einem Puppet Base Modul aufbauen). Das Profil steuert immer auch Backup, Firewall und Monitoring. So ist sichergestellt, dass jeder Server eine korrekte Backup-Konfiguration und die richtigen Firewall Rules hat und eben auch automatisch im Monitoring eingerichtet wird. Das heisst, es ist ausgeschlossen, dass ein managed Server nicht im Monitoring eingerichtet ist.

Cluster Konfiguration

Ein Icinga2 Cluster wird immer mittels Zonen und Endpoints konfiguriert. Zonen können mehrere Endpoints (Server mit Icinga2 Instanz) enthalten.

Die manuelle Konfiguration dazu würde vereinfacht so aussehen:

# zones
object Zone "master" {
  endpoints = [ "master1.vagrant.dev" ]
}
object Zone "sat1.vagrant.dev" {
  parent = "master"
  endpoints = [ "sat1.vagrant.dev" ]
}
...
object Zone "clientB.vagrant.dev" {
  parent = "sat1.vagrant.dev"
  endpoints = [ "clientB.vagrant.dev" ]
}
# endpoints
object Endpoint "master1.vagrant.dev" {
  host = "192.168.33.101"
}
object Endpoint "sat1.vagrant.dev" {
  host = "192.168.12.102"
}
...
object Endpoint "clientB.vagrant.dev" {
  host = "192.168.12.104"
}

Das muss dann noch auf allen beteiligten Server so gemacht werden. Ausserdem müssen neben der Icinga2 Grund- und Feature-Konfiguration entweder die Icinga2 eigene x509 PKI konfiguriert und verwendet oder die Zertifikate auf andere Weise ausgestellt und verteilt werden. Details zur manuellen Konfiguration sind hier zu finden: https://www.icinga.com/docs/icinga2/latest/doc/06-distributed-monitoring/

Bei uns wird das natürlich alles via Puppet gemacht. In der Regel reicht folgende Konfiguration aus Hiera (Beispiel für einen Client, der zu einem Satelliten verbindet):

Beispiel Client hinter Satellite

profile_icinga2::parent_zone: 'sat1.vagrant.dev'
profile_icinga2::parent_endpoints:
  'sat1.vagrant.dev':
    host: '192.168.12.102'
 profile_icinga2 kümmert sich dann um alles, inklusive der Zonen / Endpoint Konfiguration und konfiguriert die sowieso vorhanden Zertifikate der PuppetCA für die Icinga2 API. Das offizielle Puppet Modul für Icinga2 gibt es hier: https://github.com/Icinga/puppet-icinga2

Host und Service Checks – Konfigurations-Flow

1. Puppet Run auf einem Server inkludiert profile_icinga2 und Service Profile (z.B. profile_mariadb), Beispiel Hieradata:

---
classes:
 - profile_icinga2
 - profile_mariadb

profile_mariadb::manage_monitoring: true # default

2. Icinga2 Profil exportiert

    • a. Host Object

 

    b. MariaDB Service Check

3. Puppet run auf Monitoring Master
4. Im selben Puppet run auf dem Monitoring Master werden alle Host Objects und Service Objects gesammelt und in Icinga2 angelegt
5. Die Hosts und Services werden im Config Sync Verzeichnis (zones.d) der jeweiligen Client Zone von Puppet angelegt
6. Icinga2 config check wird von Puppet durchgeführt und Icinga2 reloaded
7. Icinga2 synchronisiert die Config via Top-Down-ConfigSync auf alle Satelliten und Clients

    • a. Jede Satellite und Client Instanz bekommt dabei nur die Config, die ihn auch wirklich betrifft

 

    b. Jede Instanz validiert und aktiviert die Config

8. Icinga2 Satelliten syncen die Configs auf ihre Clients
9. Check ist im Monitoring:

Die Nachteile von Exported Resources

Puppet ist unser primäres Konfigurationsmanagement und Automatisierungs-Werkzeug. Allerdings ist bei der Verwendung von Exported Resources immer Vorsicht geboten.

  • Verlust der PuppetDB Daten führt zum Wegräumen aller Hosts und Services im Monitoring, was sich zwar wieder – nachdem jeder Server wieder einen Puppet run gemacht hat – von selbst „heilt“. Trotzdem unschön.
  • Die ganze Sache ist sehr träge, da jede Änderung einen Puppet run auf dem Server (Icinga2 Client) und auf dem Icinga2 Master benötigt, bevor die Änderungen wirksam sind.
  • Der Puppet run auf dem Monitoring Master sammelt tausende Zone-, Endpoint-, Host- und zehntausende Service-Objects Resources zusammen und ergibt somit einen Puppet run, der locker länger als 20-30 Minuten dauert. Das System wird somit noch träger.

Mögliche Lösungen

Wir wollen in Zukunft auf das Einsammeln von Exported Resources verzichten und Icinga2 direkt mit den Daten aus der PuppetDB konfigurieren. Warum? Weil ein Puppet Run auf fast allen Servern im 1-2 Minuten-Bereich oder weniger liegt, der Puppet Run auf dem Monitoring Master jedoch das Problem ist.

Es gibt auch bereits eine Lösung: Icinga2 Director mit PuppetDB Anbindung

Dabei würden die Server weiterhin Host und Service Objects via Puppet exportieren, jedoch sammelt ein Import / Sync Job (3) des Directors die Objekte direkt aus der PuppetDB zusammen, filtert und konfiguriert daraus Icinga2 Objekte.

Resultat

Nur noch ein schneller Puppet Run auf den eigentlich betroffenen Server, Änderungen sind innert 1-2 Minuten in Icinga2 aktiv. Der Puppet Run auf dem Monitoring Master gerät in der Hintergrund und ist maximal noch für die Zonen Konfiguration und PKI zuständig, welche im Vergleich zu Service Checks und dem damit verbundenen Tuning eher statisch ist.

Fazit

Verglichen mit der manuellen Konfiguration von Hosts und Services in einem Monitoring System oder der für uns fast komplett unbrauchbaren Auto-Discovery Funktionen anderer Systeme, haben wir mit top Open Source Software eine Lösung geschaffen, die unsere Anforderungen erfüllt, sich komplett in unsere DevOps Arbeitsweise integriert und uns somit den proaktiven Betrieb für unsere Kunden ermöglicht sowie extrem vereinfacht. Es gibt aber an zahlreichen Punkten Verbesserungspotential und uns wird es darum sicher nie langweilig.

Mehr zu Distributed Monitoring mit Icinga2: https://www.icinga.com/docs/icinga2/latest/doc/06-distributed-monitoring/

Dies wird sicher nicht der letzte Blog Post zu Icinga2, Icinga2 Director, Monitoring usw. gewesen sein.