tips and tricksAb und zu stehe ich vor dem Problem, dass ich auf einem zu überwachenden System den Icinga 2 Agent nicht benutzen kann.

Anstatt irgendwie das alte (und teils unsichere) NRPE zu benutzen, greife ich dann oft gerne auf check_by_ssh zurück.

Ein Remote-Check funktioniert relativ einfach:

.../check_by_ssh -H web1.example.com -l monitoring -i /etc/icinga2/secure/id_rsa -C '/usr/lib/nagios/plugins/check_users -w 3 -c 5'

Wie man an der Kommandozeile erahnen kann, rufen wir hier einfach per SSH ein Nagios Plugin auf.

Nun habe ich in der Icinga 2 Welt den Vorteil, dass ich saubere Kommandozeilen bauen kann, d.h. Icinga 2 kümmert sich darum, einen Befehl zu bauen, in dem alle Parameter sauber formatiert, und auch “escaped” sind.

Das by_ssh CheckCommand in der Icinga 2 ITL bietet ein kleines Hilfsmittel dafür an, hier ein einfacher Service als Beispiel:

apply Service "users" {
  import "generic-service"

  check_command = "by_ssh"

  vars.users_wgreater = 3
  vars.users_cgreater = 5
  vars.by_ssh_command = [ "/usr/lib/nagios/plugins/check_users" ]
  vars.by_ssh_arguments = {
    "-w" = "$users_wgreater$"
    "-c" = "$users_cgreater$"
  }

  // assign where ...
}

Wie man am Syntax vielleicht erkennen kann, funktioniert dies hier ähnlich wie die Definition von CheckCommands. Nur eben als Kommando in einem Kommando. Innerhalb vom CheckCommand by_ssh wird hier eine kleine Kommandozeile generiert, in der auch Macros aufgelöst werden.

Nachdem Icinga 2 Konfiguration fast wie eine kleine Programmiersprache ist, kann ich auch einfach vom fertigen CheckCommand aus der ITL die Definitionen kopieren:

apply Service "users" {
  // ...
  check_command = "by_ssh"
  vars.by_ssh_command = {{ get_check_command("users").command }}
  vars.by_ssh_arguments = {{ get_check_command("users").arguments }}
  // ...
}

Wenn ich es meinen Usern noch einfacher machen will kann man dies sogar per Template lösen:

template Service "ssh-service" {
  import "generic-service"

  // "save" original command name, and replace it
  vars.original_check_command = check_command
  check_command = "by_ssh"

  // these get evaluated at runtime
  vars.by_ssh_command = {{ get_check_command(service.vars.original_check_command).command }}
  vars.by_ssh_arguments = {{ get_check_command(service.vars.original_check_command).arguments }}
}

Der eigentliche Service bleibt dabei sehr übersichtlich, hier kommt es nur auf die Reihenfolge an, das check_command muss vor dem import gesetzt sein.

apply Service "users" {
  // ...
  check_command = "users"
  import "ssh-service"

  vars.users_wgreater = 3
  vars.users_cgreater = 5
  // ...
}

Über die Icinga 2 API kann ich gut sehen welches Kommando ausgeführt wird:

$ ICINGA2_API_PASSWORD="geheim" /usr/sbin/icinga2 console --connect https://root@localhost:5665/

=> get_service("web1.example.com", "users").last_check_result.command
[ "/usr/lib/nagios/plugins/check_by_ssh", "-C", "'/usr/lib/nagios/plugins/check_users' '-c' '4' '-w' '2'", "-H", "1.2.3.4" ]

Viel Spaß beim Ausprobieren!

Beitragsbild von Owen Moore (CC-BY-2.0)

Markus Frosch

Autor: Markus Frosch

Markus arbeitet bei NETWAYS als Principal Consultant und unterstützt Kunden bei der Implementierung von Nagios, Icinga und anderen Open Source Systems Management Tools. Neben seiner beruflichen Tätigkeit ist Markus aktiver Mitarbeiter im Debian Projekt.