Checkmk im Homelab: Agent mit TLS, Local-Checks für eigene Jobs und die Fallen dabei

Checkmk-Serviceliste eines Containers mit eigenen Local-Checks für nächtliche Jobs und das zugehörige Script

Verfasst von

in

Checkmk überwacht bei mir alles, was im Haus Strom zieht und eine Netzwerkadresse hat: Proxmox-Knoten, Container, Windows-Server, Drucker, Steckdosen. Die Grundinstallation ist schnell gemacht. Schwieriger wird es danach: Wie kommen neue Container sauber mit Agent hinein, wie überwache ich eigene Jobs wie Backups und nächtliche Abgleiche, und was geht dabei schief? Das ist mein Stand nach einigen Wochen Betrieb, mit den Fehlern, die ich gemacht habe.

Checkmk-Serviceliste eines Containers mit eigenen Local-Checks für nächtliche Jobs und das zugehörige Script

Der Netzscan findet alles, aber nur als Adresse

Checkmk kann einen Ordner regelmäßig per Ping nach neuen Geräten durchsuchen lassen. Bei mir läuft der Scan stündlich über die Bereiche, in denen Server und Geräte liegen. Das ist bequem, hat aber eine Eigenart: Neue Geräte landen als reine Ping-Hosts mit der IP-Adresse als Namen. Für Steckdosen und Kameras reicht das. Für einen neuen Server will ich einen richtigen Namen und den Agent.

Bei einem neuen Container lösche ich deshalb den automatisch angelegten Ping-Host, solange er noch keine Messwerte hat, und lege einen Host mit dem DNS-Namen und dem Merkmal „Checkmk-Agent“ an. Der Scan legt die Adresse danach nicht noch einmal an, weil sie jetzt bekannt ist.

Beim Aufräumen fiel mir einmal ein Host auf, der aussah wie ein Duplikat: dieselbe Adresse, aber als IP-Name. Ich habe ihn gelöscht. Es war der Host mit dem Agent und 50 Services, der Host mit dem schönen Namen hatte nur Ping. Der Messverlauf war weg. Seitdem sehe ich vor dem Löschen eines vermeintlichen Duplikats nach, welcher der beiden die Services hat.

Agent mit TLS, ohne Kennwort in der History

Den Linux-Agent nehme ich nicht aus dem Internet, sondern aus dem Verzeichnis der eigenen Checkmk-Site. So passt die Version zum Server. Vor dem Installieren vergleiche ich die Prüfsumme der kopierten Datei mit der auf dem Server. Danach registriert sich der Agent per TLS bei der Site. Ohne Registrierung läuft er unverschlüsselt, und Checkmk meldet das zu Recht als Warnung.

Für die Registrierung braucht der Agent ein Konto auf der Site. Ich nutze einen Automationsbenutzer. Dessen Geheimnis soll weder in der Shell-History noch in der Prozessliste auftauchen, deshalb reiche ich es per Pipe weiter:

# Agent aus der eigenen Site, Prüfsumme vergleichen
sha256sum check-mk-agent_*.deb      # auf beiden Seiten
dpkg -i check-mk-agent_*.deb

# Registrierung: das Secret kommt per Pipe, nicht als Argument
ssh monitoring-server 'cat /pfad/zum/automation.secret' | ssh neuer-host \
  'cmk-agent-ctl register --hostname neuer-host.example.lan \
     --server monitoring-server:8000 --site monitoring \
     --user automation --password "$(cat)" --trust-cert'

Danach folgen eine Service-Erkennung (cmk -II host) und die Aktivierung der Konfiguration. Bei einem frischen Debian-Container kommen so 15 bis 20 Services zusammen, von CPU über Dateisysteme bis zu systemd-Diensten.

Änderungen per REST-API aktivieren

Hosts lege ich per REST-API an, weil das wiederholbar ist und in Skripte passt. Eine Eigenheit hat mich anfangs Zeit gekostet: Zum Aktivieren verlangt die API den ETag der Liste offener Änderungen im Header If-Match. Das ist Absicht, denn so aktiviert man keine Änderungen, die man nicht gesehen hat. Ich lese die offenen Änderungen deshalb vorher aus. Stammen welche von jemand anderem, etwa vom Netzscan, schaue ich sie mir an, bevor ich sie mit aktiviere.

A=http://localhost/monitoring/check_mk/api/1.0
H="Authorization: Bearer automation $SECRET"
# offene Änderungen ansehen und ETag merken
curl -s -D - -H "$H" "$A/domain-types/activation_run/collections/pending_changes"
# aktivieren, nur wenn der ETag noch stimmt
curl -s -X POST -H "$H" -H "If-Match: \"$ETAG\"" -H "Content-Type: application/json" \
  "$A/domain-types/activation_run/actions/activate-changes/invoke" \
  -d '{"redirect": false, "sites": ["monitoring"]}'

Local-Checks: eigene Jobs mit fünf Zeilen überwachen

Local-Checks bringen mir am meisten. Das sind kleine Skripte im Verzeichnis /usr/lib/check_mk_agent/local/ des Agents. Sie geben eine Zeile pro Service aus: Status (0 bis 3), Name, Messwerte und Text. Checkmk macht daraus einen normalen Service mit Verlauf und Benachrichtigung.

Jeder nächtliche Job schreibt bei mir am Ende eine kleine Statusdatei mit Zeitpunkt und Rückgabewert. Der Local-Check liest nur diese Datei. So bleibt der Check schnell, und der Job muss nichts von Checkmk wissen.

Ablauf vom nächtlichen Job über die Statusdatei und den Local-Check zum Checkmk-Service, darunter die Schwellen 30 und 54 Stunden
#!/bin/bash
# Statusdatei des nächtlichen Abgleichs: zeit=<Unix-Zeit>, rc=<Rückgabewert>
. /var/lib/mein-job/status
ALTER=$(( ($(date +%s) - zeit) / 3600 ))
S=0; [ "$ALTER" -ge 30 ] && S=1; [ "$ALTER" -ge 54 ] && S=2; [ "$rc" != 0 ] && S=2
echo "$S Mein_Job alter_h=$ALTER;30;54 Letzter Lauf vor $ALTER h, Rückgabe $rc"

Die Schwellen 30 und 54 Stunden sind so gewählt, dass ein täglicher Job sich um ein paar Stunden verschieben darf, ohne dass etwas rot wird. Fällt er einmal aus, wird es gelb, fällt er zweimal aus, rot. Die Messwerte hinter dem Namen (alter_h=…;30;54) ergeben nebenbei einen Graphen, an dem ich sehe, wann ein Job schleichend später fertig wird.

Regeln gelten für das Item, nicht für den Servicenamen

Für die Temperatur meiner Festplatten wollte ich eigene Schwellen setzen, nur für die SATA-Platten. Die Bedingung „Service-Name beginnt mit …“ in der Regel griff aber nicht. Bei Regeln für Prüfparameter vergleicht Checkmk diese Bedingung mit dem Item, also dem variablen Teil des Namens, nicht mit dem ganzen Servicenamen. Besser wählt man über Service-Labels aus, die der Check selbst mitbringt, etwa den Typ der Platte.

Zeitzonen in Containern

Viele LXC-Vorlagen laufen in UTC, die Proxmox-Hosts und Windows dagegen in Ortszeit. Ein Timer mit OnCalendar=03:30 startet in so einem Container im Sommer um 05:30 Ortszeit, mitten in anderen Jobs. Deshalb steht die Zeitzone jetzt im Timer:

[Timer]
OnCalendar=*-*-* 03:30 Europe/Berlin
Persistent=true

Rauschen leise stellen, ohne es zu verstecken

Die Ereignisprotokolle der Windows-Server meldeten anfangs ständig harmlose Warnungen. Statt den Service abzuschalten, stufe ich bekannte Meldungen per Regel herunter oder lasse sie ignorieren, und jede Regel trägt einen Kommentar, warum die Meldung harmlos ist. So bleibt der Service aktiv und meldet neue, unbekannte Fehler weiterhin.

Zwei Beispiele von den Domänencontrollern: Die DFS-Replikation meldet während der nächtlichen Sicherung den Fehler 9036 („Paused for backup or restore“), das ist erwartbar und wird ignoriert. Beim .NET-Speichercheck lag die Zeit in der Garbage Collection zeitweise bei 11 bis 27 Prozent und damit über den Schwellen von 10 und 15 Prozent. Die Spitzen kamen von meinen eigenen WinRM-Sitzungen, also habe ich die Schwellen auf 30 und 50 Prozent gesetzt.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht, deine IP-Adresse wird nicht gespeichert. Kommentare erscheinen erst nach Freigabe. Was mit deinen Angaben passiert, steht in der Datenschutzerklärung. Pflichtfelder sind mit * markiert.