icinga2 placeholder

wall < "Ein einfacher event handler in Icinga2"

Broadcast message from spillerm@unixe.de (pts/1) (Mi Jan 06 13:29:11 2016):
4
Diesen Beitrag schrieb ich vor 3 Jahren. Behalte das beim Lesen bitte im Hinterkopf.

Die Aufgabe

Ich möchte auf meinem Host webserver mit IP 192.168.3.3 nicht nur überwachen, ob der Dienst memcached läuft — ich möchte ihn auch starten, falls er es mal nicht tut. Natürlich ist das exemplarisch — grundsätzlich lässt sich die Logik auf beliebige Dienste anwenden. Und ausweiten, wie ihr feststellen werdet…

event_restart_by_ssh

Ein Rückgabewert von 0 bedeutet, unser Check liefert OK, und im Umkehrschluss bedeutet das: bei jedem Rückgabewert > 0 schicken wir unseren event handler auf die Reise. Wir können uns diesen Rückgabewert greifen ($service.state_id$) und prüfen, ob er grösser als (greater than-gt) 0 ist (test $service.state_id$ -gt 0); ist er größer als 0 (sprich die Überprüfung liefert ein true zurück), so wird der Restart des Dienstes angetriggert — und nur dann (&& sudo service $event_restart_by_ssh_daemon$ restart).

object EventCommand "event_restart_by_ssh" {
  import "plugin-event-command"
  command = [ PluginDir + "/check_by_ssh" ]
  arguments = {
    "-H" = {
                value = "$event_restart_by_ssh_address$"
                description = "Host address."
        }
    "-C" = {
                value = "test $service.state_id$ -gt 0 && sudo service $event_restart_by_ssh_daemon$ restart"
                description = "Test and command for daemon to restart."
        }
    }
  vars.event_restart_by_ssh_address = "$address$"
}

Der Service

In meinem Beispiel definiere ich für meinen Host webserver einen Service, der per nrpe die Verfügbarkeit von memcached abprüft; welches Plugin ihr hierfür zum Einsatz bringt sei euch überlassen, wichtig ist nur, dass es konforme Rückgabewerte liefert. Mit vars.event_restart_by_ssh_daemon gebe ich mit, wie der Daemon heisst, der im Bedarfsfalle restartet werden muss.

object Service "NRPE service memcached" {
  import "generic-service"
  hostname = "webserver"
  check_command = "nrpe"
  vars.nrpe_command = "check_memcached"
  event_command = "event_restart_by_ssh"
  vars.event_restart_by_ssh_daemon = "memcached"
}

Der User

Icinga2 Event HandlerOkay. Wir bekommen mit, wenn der Dienst absemmelt. Wir haben ein Event definiert, das in dem Falle greifen und den Dienst neu starten soll. Wir werden feststellen, dass das allein jedoch nicht reicht: der User, unter dem Icinga2 läuft — auf meinem System heisst er nagios — muss sich per SSH vom Monitoring-Server aus auf webserver ohne Passwort einloggen und $DINGE tun dürfen.

Grundsätzlich regeln wir das so, indem für User nagios ein SSH-Key erstellt, der öffentliche Schlüssel auf webserver in authorized_keys hinterlegt und der sshd auf webserver entsprechend konfiguriert wird — kurz: die übliche SSH Key-Based Authentication (hierzu hatte ich vor einiger Zeit einen ausführlicheren Artikel, der auch heute noch Gültigkeit hat).

Zusätzliche Sicherheit bringe ich hinein, indem ich in der authorized_keys festhalte, dass User nagios sich ausschliesslich von meinem Monitoring-Server aus einloggen darf; das ist zu erreichen, indem dem Key ein from="..." voran gestellt wird. Und je nach Anwendungsfall kann man den Zugriff weiter beschränken, indem auch noch mit command="..." festgehalten wird, was genau der User ausführen darf.

from="192.168.3.1" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABA[...]

Auf webserver halten wir fest, dass der User nagios den memcached restarten darf — üblicherweise darf das nämlich nur root.

$ visudo
[...]
nagios	ALL = (ALL) NOPASSWD: /usr/sbin/service memcached *

Fazit: User nagios darf sich nun vom Monitoring-Server — und nur von dort! — auf webserver einloggen und den Service memcached — und nur den! — neu starten.

Der Test

Zeit für den ersten Testlauf! Hierzu schalten wir das debuglog von Icinga2 ein:

$ icinga2 feature enable debuglog
Enabling feature debuglog. Make sure to restart Icinga 2 for these changes to take effect.
$ service icinga2 restart
$ tail -f /var/log/icinga2/debug.log | grep memcached

Und nun kann auf webserver der memached abgeschaltet werden:

$ service memcached stop

Im Output des debug.log können wir nun live beobachten, was geschieht:

[2016-01-05 13:14:39 +0100] debug/CheckerComponent: Executing check for 'webserver!NRPE service memcached'
[2016-01-05 13:14:39 +0100] notice/Process: Running command '/usr/lib/nagios/plugins/check_nrpe' '-H' '192.168.3.3' '-c' 'check_memcached': PID 26610
[2016-01-05 13:14:39 +0100] notice/Process: PID 26610 ('/usr/lib/nagios/plugins/check_nrpe' '-H' '192.168.3.3' '-c' 'check_memcached') terminated with exit code 2
[2016-01-05 13:14:39 +0100] notice/Checkable: State Change: Checkable webserver!NRPE service memcached soft state change from OK to CRITICAL detected.
[2016-01-05 13:14:39 +0100] notice/Checkable: Executing event handler 'event_by_ssh_restart_service' for service 'webserver!NRPE service memcached'
[2016-01-05 13:14:39 +0100] notice/Process: Running command '/usr/lib/nagios/plugins/check_by_ssh' '-C' 'test 2 -gt 0 && sudo service memcached restart' '-H' '192.168.3.3': PID 26617
[2016-01-05 13:14:41 +0100] notice/Process: PID 26617 ('/usr/lib/nagios/plugins/check_by_ssh' '-C' 'test 2 -gt 0 && sudo service memcached restart' '-H' '192.168.3.3') terminated with exit code 0

Vergesst nicht, für den produktiven Betrieb das debuglog wieder abzuschalten — das müllt euch sonst fröhnlich das File-System voll ;-)

Nur der Anfang…

UnterschriftWie ihr schnell sehen werdet: das ist nur der Anfang, denn auf diese Art kann man den User nagios alle möglichen Wartungsarbeiten auf den Maschinen ausführen lassen. An dieser Stelle findet ihr eine ausführlichere Version, bei der das Restarten eines Dienstes nur eine Möglichkeit darstellt und von der ihr euch prima inspirieren lassen könnt.

4
  1. Khlav Kalash

    Sehr hilfreich und gut beschrieben (wie übrigens alle Artikel zu dem Thema), nur leider bewege ich mich an der stelle auf durch aus bekanntem Terrain.

    Ich verzweifele gerade allerdings an einer Umsetzung ohne Config-Files und würde gern den Neustart eines Dienstes auf einem Remote-System nur über den Director konfigurieren. Scheitere aber leider mangels Dokumentation und an den Knoten im Hirn… eine Idee?

    VG

    • Hi,

      das ist eine interessante Frage und ich muss gestehen, dass ich das bislang noch nicht versucht habe (du bringst mich da aber durchaus auf eine Idee. Hm.)

      Ich hatte mit Ein einfacher event handler in Icinga2 das Thema im Bezug auf textbasierte Konfig-Files behandelt — das in den Director zu übertragen scheint mir aber möglich, da man unter Commands → Add new Icinga Command ja im Drop-Down-Feld Event Plugin Command auswählen kann. Ich denke das wäre der Startpunkt für Spielereien zu dem Thema.

      Viele Grüße — und viel Erfolg :)

  2. Ich würde erst bei einem HARD-State aktiv werden…
    arguments -C
    ändern in

    value = „test $service.state_id$ -gt 0 && test ‚$service.state_type$‘ = ‚HARD‘ && sudo service $event_restart_by_ssh_daemon$ restart“

    Dann wird der Dienst/das Service erst beim Hard-State neu gestartet

Keine weitere Reaktionen mehr möglich.