Icinga2

Wenn man heutzutage nach Monitoring-Lösungen sucht, wird man häufig auf die Open Source Lösung Icinga2 stoßen. Da ich mit meiner Nagios Installation nicht mehr richtig zufrieden bin, wollte ich schon seit längerem Icinga2 ausprobieren. Aller Anfang ist schwer und so kam bei meinem ersten Versuch mit Icinga2 keine funktionierende Lösung heraus. Ich habe seitdem immer wieder in Tutorials gestöbert, z.B. in Icinga2 und ein Client Node, die Doku gewälzt und auch im Buch „Icinga 2: Ein praktischer Einstieg ins Monitoring“ geschmöckert. Mit mehr Wissen ausgestattet wurde mir klar, dass ich nach dem Distributed Monitoring with Master, Satellites, and Clients Guide vorgehen muss. Da ich dabei auf kleine und große Probleme gestoßen bin, war es auch noch hilfreich auf der Icinga Mailingliste nach Hilfe zu fragen. In diesem Blogartikel halte ich nun die für mich wichtigen Hinweise und Konfigurationen fest, in der Hoffnung das es später mir oder jemand anderem nützen könnte.

Installation

Ich habe mir die Icinga Repositories eingebunden und die Pakete icinga2 und icingaweb2 installiert. Mein Master läuft auf Ubuntu Xenial, die Installation und initiale Konfiguration der Icinga Pakete klappte problemlos. Nach der Installation hat man dann ein funktionierendes Monitoring für die Master Maschine. Wenn man mehrere Maschinen unter einem Master zusammen fassen will, muss man sich für eine Variante des verteilten Monitorings entscheiden.

Ein Master, mehrere Satelliten (Clients/Agents)

Ich verwende einen Icinga2 Master, auf dem Icingaweb2 läuft. Auf dem Master sind also per Webinterface alle Dienste einsehbar, desweiteren werden vom Master die Notifizierungen vorgenommen. Der Master wird mit dem „Top Down Config Sync“ zentral alle Konfigurationen für die Clients verwalten. Top Down ist auch seit dem von mir verwendeten Icinga 2.6 die empfohlene Variante.

Master Setup

Das Setup habe ich entsprechend dem Distributed Monitring Guide durchgeführt. Der Master wird mit icinga2 node wizard aufgesetzt:

Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]: n

Nachdem der Wizzard gelaufen ist, deaktiviert man zunächst die in conf.d hinterlegte Konfiguration, bevor man mit der Konfiguration der Zonen fortfährt. Am einfachsten deaktiviert man dazu den Include in der Datei icinga2.conf:

/**
* Although in theory you could define all your objects in this file
* the preferred way is to create separate directories and files in the conf.d
* directory. Each of these files must have the file extension ".conf".
*/
//include_recursive "conf.d"

Icinga unterteilt alle Hosts in Zonen, ich benenne diese immer nach dem vollen Hostnamen (FQDN), damit tue ich mir leichter. Es ist natürlich auch möglich die Zone für den Master wie im Guide mit „master“ anzulegen. Unter /etc/icinga2 werden nun erstmal die Ordner für die globalen Templates, den Master und den ersten Client eingerichtet:

mkdir -p zones.d/global-templates zones.d/MASTERFQDN zones.d/CLIENTFQDN

Der global-templates Ordner enthält alle Definitionen, die auf alle Clients verteilt werden sollen. Ich bediene mich hier aus dem deaktivierten conf.d Ordner und kopieren von dort die Dateien commands.conf, templates.conf, timeperiods.conf und users.conf um mir die weitere Konfiguration zu erleichtern.

Als nächstes konfiguriere ich die nötigen Zonen in /etc/icinga2/zones.conf

object Zone "global-templates" {
global = true
}

object Endpoint "MASTERFQDN" {
host = "MASTERFQDN"
}

object Zone "MASTERFQDN" {
endpoints = [ "MASTERFQDN" ]
}

object Endpoint "CLIENTFQDN" {
host = "CLIENTFQDN"
}

object Zone "CLIENTFQDN" {
endpoints = [ "CLIENTFQDN" ]

parent = "MASTERFQDN"
}

Nun müssen diese angelegten Zonen in den bereits erzeugten Ordnern mit Konfiguration gefüllt werden. Unter /etc/icinga2/zones.d/MASTERFQDN konfiguriert man das Monitoring für den Master selbst und für alle Dienste, die vom Master aus auf Funktion geprüft werden sollen, z.B. ping für IPV4 und IPv6.

hosts.conf

object Host "MASTERFQDN" {
import "generic-host"
check_command = "hostalive"
address = "IPv4-Adresse"
address6 = "IPv6-Adresse"
vars.os = "Linux"
}

notifications.conf

apply Notification "mail-icingaadmin" to Host {
import "mail-host-notification"
user_groups = host.vars.notification.mail.groups
users = host.vars.notification.mail.users
assign where host.vars.notification.mail
}

apply Notification "mail-icingaadmin" to Service {
import "mail-service-notification"
user_groups = host.vars.notification.mail.groups
users = host.vars.notification.mail.users
assign where host.vars.notification.mail
}

ping.conf

apply Service "ping4" {
import "generic-service"
check_command = "ping4"
assign where host.address
}

apply Service "ping6" {
import "generic-service"
check_command = "ping6"
assign where host.address6
}

services.conf

object Service "disk" {
import "generic-service"
check_command = "disk"
host_name = "MASTERFQDN"
}

object Service "load" {
import "generic-service"
check_command = "load"
host_name = "MASTERFQDN"
}

object Service "procs" {
import "generic-service"
check_command = "procs"
host_name = "MASTERFQDN"
}

object Service "swap" {
import "generic-service"
check_command = "swap"
host_name = "MASTERFQDN"
}

object Service "users" {
import "generic-service"
check_command = "users"
host_name = "MASTERFQDN"
}

object Service "apt" {
import "generic-service"
check_command = "apt"
host_name = "MASTERFQDN"
}

object Service "icinga" {
import "generic-service"
check_command = "icinga"
host_name = "MASTERFQDN"
}

ssh.conf

apply Service "ssh" {
import "generic-service"
check_command = "ssh"
assign where (host.address || host.address6) && host.vars.os == "Linux"
}

Weiter geht es mit der Konfiguration für den ersten Client in /etc/icinga2/zones.d/CLIENTFQDN:

hosts.conf

object Host "CLIENTFQDN" {
import "generic-host"
check_command = "hostalive"
address = "IPv4-Adresse"
address6 = "IPv6-Adresse"
vars.os = "Linux"
zone = "MASTERFQDN"
}

Durch das Aufnehmen des Clients in die Zone des Masters wird der hostalive Check auf dem Master ausgeführt. icingaweb2 zeigt übrigens die verwendete Check-Quelle an. Dort sieht man schnell wo ein bestimmter Check ausgeführt wurde.

services.conf

object Service "disk" {
import "generic-service"
check_command = "disk"
host_name = "CLIENTFQDN"
}

object Service "load" {
import "generic-service"
check_command = "load"
host_name = "CLIENTFQDN"
}

object Service "procs" {
import "generic-service"
check_command = "procs"
host_name = "CLIENTFQDN"
}

object Service "swap" {
import "generic-service"
check_command = "swap"
host_name = "CLIENTFQDN"
}

object Service "users" {
import "generic-service"
check_command = "users"
host_name = "CLIENTFQDN"
}

object Service "apt" {
import "generic-service"
check_command = "apt"
host_name = "CLIENTFQDN"
}

object Service "icinga" {
import "generic-service"
check_command = "icinga"
host_name = "CLIENTFQDN"
}

Die weiteren Clients kann man analog konfigurieren. Eine Prüfung der Konfiguration mit icinga2 daemon -C sollte keine Fehler liefern. Die neue Konfiguration wird dann mit /etc/init.d/icinga2 reload aktiv.

Client Konfiguration

Nun können wir uns der Konfiguration des ersten Clients zuwenden. Da das Webinterface vom Master bereit gestellt wird, fügt man auf jedem Client nur das Icinga Repository hinzu und installiert das icinga2 Paket. Als nächsten führen wir auf dem Client den Node Wizard aus, um die verschlüsselte Verbindung zum Master einzurichten: icinga2 node wizard

Die wichtigen Antworten sind:

Please specify if this is a satellite setup ('n' installs a master setup) [Y/n]:

Hier drücken wir Enter um den Satellit zu konfigurieren. Desweiteren muss man darauf achten, dass man sowohl die Konfiguration, als auch Kommandos vom Master akzeptiert:

Accept config from master? [y/N]: y
Accept commands from master? [y/N]: y

Der Rest sollte selbsterklärend nach der Anleitung funktionieren. Als nächstes müssen wir wieder den conf.d Include in der Datei icinga2.conf auf dem Satelliten deaktivieren, da er ja die Konfiguration über den Master beziehen wird:

/**
* Although in theory you could define all your objects in this file
* the preferred way is to create separate directories and files in the conf.d
* directory. Each of these files must have the file extension ".conf".
*/
//include_recursive "conf.d"

Die zones.conf benötigt auf jedem Satellit die global-templates, die Master und die Client Zone:

object Zone "global-templates" {
global = true
}

object Endpoint "MASTERFQDN" {
host = "MASTERFQDN"
port = "5665"
}

object Zone "MASTERFQDN" {
endpoints = [ "MASTERFQDN" ]
}

object Endpoint "CLIENTFQDN" {
}

object Zone "CLIENTFQDN" {
endpoints = [ "CLIENTFQDN" ]
parent = "MASTERFQDN"
}

Eine Prüfung der Konfiguration mit icinga2 daemon -C sollte auch auf dem Client keine Fehler liefern. Die neue Konfiguration wird ebenfalls mit /etc/init.d/icinga2 reload aktiv. Nun sollte der Icinga2 Cluster schon korrekt funktionieren und den Master und den ersten Client überwachen.

Status des Clusters überwachen

Da die Satelliten ihre Daten sammeln und an den Master übermitteln, würde es ohne einen weiteren Check nicht auffallen, wenn die Satelliten aufhören Daten zu senden. Wir fügen deshalb in der Master Zonen (zones.d/MASTERFQDN) diesen weiteren Check ein:

cluster.conf

object Service "cluster" {
check_command = "cluster"
check_interval = 5s
retry_interval = 1s
host_name = "MASTERFQDN"
}

Aktuell gibt es noch eine weitere Lücke im Monitoring: wenn der Master komplett ausfällt, wird kein Alarm geschlagen. Hierzu plane ich noch einen externen Check, da ein komplettes HA-Setup für mich wahrscheinlich zu viel ist. Ich versuche das zu verbloggen, sobald der Check fertig ist.

Fazit und Ausblick

Die Einrichtung von Icinga2 von null an war für mich kein Spaziergang. Ich musste einiges neu lernen. Mit den richtigen Guides, Howtos und Hilfe von der Mailingliste habe ich ein neues Monitoring-System aufbauen können, das Nagios jetzt schon in vielen Punkten ersetzen kann. Auf einigen Clients werde ich noch Checks für RAID, SMTP, IMAP(S), HTTP, DNS etc. konfigurieren müssen, aber die ganze Infrastruktur dafür habe ich nun. Ich werde sicher weiter berichten.