Kubernetes überwachen

1. Einleitung

Der große Erfolg von Docker hat dazu geführt, dass Leute Docker in immer größerem Maßstab einsetzen. Der im Gegensatz zu virtuellen Maschinen ala VMWare sehr geringe Overhead macht den Container „billig“ und damit quasi zur Massenware. Dass dabei ein gutes Werkzeug für die Orchestrierung der Container essentiell ist, versteht sich von selbst. Für die Mehrheit ist das Open-Source-Tool Kubernetes das Mittel der Wahl.

Checkmk unterstützt ab Version 1.5.0p12 die Überwachung von Kubernetes. Der Schwerpunkt liegt aktuell dabei auf Zuständen und Metriken, die vor allem für den Administrator interessant sind. Folgende Checkplugins sind in Version 1.5.0p12 verfügbar:

Dies ist allerdings nur ein erster Schritt. Zukünftige Versionen von Checkmk werden das Monitoring von Kubernetes weiter ausbauen und verfeinern. Dabei kann es auch sein, dass wir die Architektur der Überwachung nochmal ändern und Sie Ihre Konfiguration dabei anpassen müssen.

2. Einrichten der Überwachung

2.1. Service-Account

Um einen Kubernetes-Cluster in Checkmk einzurichten, benötigen Sie zunächst einen Service-Account und eine damit verbundene Clusterrolle in Kubernetes, damit Checkmk auf die API zugreifen kann. Wir stellen für Sie als Schablone die Datei check_mk_rbac.yaml bereit, die Sie in den „Treasures“ finden, und zwar im Verzeichnis share/doc/check_mk/treasures/kubernetes. Deren Anfang sieht etwa so aus:

share/doc/check_mk/treasures/kubernetes/check_mk_rbac.yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: check-mk
---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: check-mk
  namespace: check-mk
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: check-mk
rules:

Wir verwenden hier als Name und Namespace jeweils check-mk.

Spielen Sie diese Datei auf Ihrem Kubernetes-Cluster mit dem Befehl kubectl ein:

user@host:~$ kubectl apply -f check_mk_rbac.yaml
namespace/check-mk created
serviceaccount/check-mk created
clusterrole.rbac.authorization.k8s.io/check-mk created
clusterrolebinding.rbac.authorization.k8s.io/check-mk created

Falls Sie die Google Kubernetes-Engine verwenden, kann es sein, dass Sie den Fehler "Error from server (Forbidden): error when creating "check_mk_rbac.yaml": bekommen. In diesem Fall müssen Sie zuvor die Berechtigungen Ihres Benutzers erweitern. Das geht mit folgendem Befehl (wobei Sie MYNAME durch Ihren Loginnamen bei Google ersetzen):

user@host:~$ kubectl create clusterrolebinding MYNAME-cluster-admin-binding --clusterrole=cluster-admin --user=MYNAME@example.org

Wenn alles gut gegangen ist, können Sie den neuen Service-Account mit kubectl get serviceaccounts abfragen:

user@host:~$ kubectl get serviceaccounts check-mk -n check-mk -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"check-mk","namespace":"check-mk"}}
  creationTimestamp: "2019-01-23T08:16:05Z"
  name: check-mk
  namespace: check-mk
  resourceVersion: "4004661"
  selfLink: /api/v1/namespaces/check-mk/serviceaccounts/check-mk
  uid: 218179a3-1ee7-11e9-bf43-080027a5f141
secrets:
- name: check-mk-token-z9hbp

Dort finden Sie dann auch den Namen des zugehörigen Secrets. Dies hat die Form „check-mk-token-ID“ (hier im Beispiel check-mk-token-z9hbp). Die ID für das Secret wird von Kubernetes automatisch generiert. Den Inhalt des Secrets können Sie anschließend mit get secrets abfragen:

user@host:~$ kubectl get secrets check-mk-token-z9hbp -n check-mk -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQVRBTkJna3Foa2lHO...
  namespace: Y2hlY2stbWs=
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObG...
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: check-mk
    kubernetes.io/service-account.uid: 218179a3-1ee7-11e9-bf43-080027a5f141
  creationTimestamp: "2019-01-23T08:16:06Z"
  name: check-mk-token-z9hbp
  namespace: check-mk
  resourceVersion: "4004660"
  selfLink: /api/v1/namespaces/check-mk/secrets/check-mk-token-z9hbp
  uid: 2183cee6-1ee7-11e9-bf43-080027a5f141
type: kubernetes.io/service-account-token

In der Ausgabe ist unter anderem das base64-kodierte CA-Zertifikat (ca.crt) und das base64-kodierte Token (token) für den Account enthalten. Sie können das Zertikat aus der Ausgabe von get secret z. B. mit folgendem Befehl ausschneiden und gleich in die Form umwandeln, die Sie für den Import in Checkmk benötigen:

user@host:~$ kubectl get secrets check-mk-token-z9hbp -n check-mk -o yaml | grep "ca.crt" | cut -f4 -d' ' | base64 --decode
-----BEGIN CERTIFICATE-----
MIIC5zCCAc+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p
a3ViZUNBMB4XDTE4MDkxMDE2MDAwMVoXDTI4MDkwODE2MDAwMVowFTETMBEGA1UE
AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK9Z
iG0gNZK5VU94a0E6OrUqxOQRdkv6S6vG3LnuozdgNfxsEetR9bMGu15DWaSa40JX
FbC5RxzNq/W9B2pPmkAlAguqHvayn7lNWjoF5P+31tucIxs3AOfBsLetyCJQduYD
jbe1v1/KCn/4YUzk99cW0ivPqnwVHBoMPUfVof8yA00RJugH6lMZL3kmOkD5AtRH
FTThW9riAlJATBofLfkgRnUEpfb3u1xF9vYEDwKkcV91ealZowJ/BciuxM2F8RIg
LdwF/vOh6a+4Cu8adTyQ8mAryfVPDhFBhbsg+BXRykhNzNDPruC+9wAG/50vg4kV
4wFpkPOkOCvB8ROYelkCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW
MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQAeNwON8SACLl2SB8t8P4/heKdR3Hyg3hlAOSGjsyo396goAPS1
t6IeCzWZ5Z/LsF7o8y9g8A7blUvARLysmmWOre3X4wDuPvH7jrYt+PUjq+RNeeUX
5R1XAyFfuVcWstT5HpKXdh6U6HfzGpKS1JoFkySrYARhJ+MipJUKNrQLESNqdxBK
4gLCdFxutTTFYkKf6crfIkHoDfXfurMo+wyEYE4Yeh8KRSQWvaKTdab4UvMwlUbO
+8wFZRe08faBqyvavH31KfmkBLZbMMM5r4Jj0Z6a56qZDuiMzlkCl6rmKynQeFzD
KKvQHZazKf1NdcCqKOoU+eh6q6dI9uVFZybG
-----END CERTIFICATE-----

2.2. Zertifikat in Checkmk importieren

Damit Checkmk dem CA-Zertifikat von Kubernetes vertraut, müssen Sie dieses in WATO unter Global Settings ➳ Site Management ➳ Trusted certificate authorities for SSL hinzufügen.

Ohne den korrekten Import der CA wird später der Checkmk-Service des Kubernetes-Clusters mit bad handshake und certificate verify failed fehlschlagen:

2.3. Passwort (Token) im Checkmk hinterlegen

Das Token des Service-Accounts können Sie nun am besten im Passwortspeicher von WATO hinterlegen. Das ist die sicherste Variante, da Sie Hinterlegung und Benutzung des Passworts organisatorisch trennen können. Alternativ geben Sie es beim Anlegen der Regel (siehe weiter unten) direkt im Klartext an.

Folgende Befehlszeile schneidet das Passwort direkt aus der Ausgabe von get secrets aus:

user@host:~$ kubectl get secrets check-mk-token-z9hbp -n check-mk -o yaml | grep "token:" | cut -f4 -d' ' | base64 --decode
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJjaGVjay1tayIsI
mt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjaGVjay1tay10b2tlbi16OWhicCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5
hbWUiOiJjaGVjay1tayIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjIxODE3OWEzLTFlZTctMTFlOS1iZjQzLTA4MDAyN2E1ZjE0MSIsInN1YiI6I
nN5c3RlbTpzZXJ2aWNlYWNjb3VudDpjaGVjay1tazpjaGVjay1tayJ9.gcLEH8jjUloTeaAj-U_kRAmRVIiETTk89ujViriGtllnv2iKF12p0L9ybT1fO-1Vx7XyU8jneQRO9lZw8JbhVmaPjrkEc8
kAcUdpGERUHmVFG-yj3KhOwMMUSyfg6wAeBLvj-y1-_pMJEVkVbylYCP6xoLh_rpf75JkAicZTDmhkBNOtSf9ZMjxEmL6kzNYvPwz76szLJUg_ZC636OA2Z47qREUtdNVLyutls7ZVLzuluS2rnfoP
JEVp_hN3PXTRei0F5rNeA01wmgWtDfo0xALZ-GfvEQ-O6GjNwHDlsqYmgtz5rC23cWLAf6MtETfyeEJjRqwituhqUJ9Jp7ZHgQ%

Wenn Sie direkt unter Linux arbeiten können Sie hinten noch ein | xsel --clipboard hinzufügen. Dann wird das Passwort garnicht ausgegeben, sondern direkt auf Clipboard kopiert (also als ob Sie das mit der Maus kopiert hätten):

user@host:~$ kubectl get secrets check-mk-token-z9hbp -n check-mk -o yaml | grep "token:" | cut -f4 -d' ' | base64 --decode | xsel --clipboard

Tipp: Falls Sie das Kommandozeilenbwerkzeug jq installiert haben, geht das Ganze etwas einfacher. jq ist z. B. bei Debian/Ubuntu im gleichnamigen Paket. Es ist ein Programm, das strukturiert auf JSON-Daten zugreifen kann. Hiermit lautet die Befehlszeile dann:

user@host:~$ kubectl get secrets check-mk-token-z9hbp -n check-mk -o yaml | jq -r .secrets[0].name

Das „Passwort“ ist wirklich so lang. Fügen Sie das z. B. unter der ID kubernetes in den Passwortspeicher ein:

2.4. Kubernetes-Cluster ins Monitoring aufnehmen

Die Überwachung von Checkmk geschieht in zwei Ebenen. Der Kubernetes-Cluster selbst wird als ein Host überwacht. Für die einzelnen Kubernetes-Nodes verwenden wir das Piggyback-Prinzip. Das bedeutet, dass jeder Node als ein eigener Host in Checkmk überwacht wird. Die Monitoringdaten dieser Hosts werden aber nicht separat von Kubernetes abgerufen, sondern aus den Daten vom Kubernetes-Cluster abgezweigt.

Da Kubernetes nicht über den normalen Checkmk-Agenten abgefragt werden kann, benötigen Sie dafür den Kubernetes-Spezialagenten, welcher auch als Datenquellenprogramm bezeichnet wird. Hierbei kontaktiert Checkmk den Zielhost nicht wie üblich über TCP Port 6556, sondern ruft stattdessen ein Hilfsprogramm auf, welches mit dem Zielsystem über ein die anwendungsspezifische API von Kubernetes kommuniziert.

Deswegen benötigen Sie noch einen weiteren Schritt: Legen Sie eine Regel an, welche Ihrem Kubernetes-Host diesen Spezialagenten zuordnet. Diese finden Sie in WATO unter Host & Service Parameters ➳ Datasource Programs ➳ Kubernetes. In den Eigenschaften der Regel geben Sie entweder das Passwort im Klartext an oder Sie wählen das über den Passwortspeicher aus, falls Sie es vorhin dort abgelegt haben.

Im Normalfall benötigen Sie keine weiteren Angaben. Die Bedeutung der weiteren Optionen erfahren Sie am besten aus der Onlinehilfe.

Wenn Sie jetzt die Servicekonfiguration für den Kubernetes-Cluster abrufen, sollten Sie bereits einige der Services finden:

2.5. Überwachung der Nodes

Damit auch die Nodes überwacht werden, müssen Sie diese ebenfalls im WATO als Host anlegen. Dies können Sie (ab Version 1.6.0 von Checkmk) mit dem neuen Dynamic Configuration Daemon (DCD) erledigen lassen. Oder Sie legen diese einfach von Hand als Hosts an.

Dabei ist es wichtig, dass die Hostnamen im Checkmk exakt mit den Namen der Kubernetesnodes übereinstimmen. Sie können diese Namen einfach aus dem Nodes-Service des Kubernetes-Hosts ablegen.

Sofern Sie auf den Nodes selbst keinen Checkmk-Agenten installiert haben (was auch in der Regel eher ungewöhnlich wäre), müssen Sie den Check_MK Agent auf No agent einstellen.

3. Hardware-/Softwareinventur

Die Kubernetesintegration von Checkmk unterstützt auch die Hardware-/Softwareinventur. In Version 1.5.0p12 beschränkt sich dies auf die Kubernetes-Rollen. Weitere Plugins sind geplant.

4. Checkmk entfernen

Wenn Sie den Service-Account und die Custerrolle von Checkmk wieder aus Kubernetes entfernen wollen, können Sie das mit folgenden Befehlen tun:

user@host:~$ kubectl -f check_mk_rbac.yaml
namespace "check-mk" deleted
serviceaccount "check-mk" deleted
clusterrole.rbac.authorization.k8s.io "check-mk" deleted
clusterrolebinding.rbac.authorization.k8s.io "check-mk" deleted

5. Kubernetes in OpenShift-Installationen

5.1. Projekt anlegen

OpenShift ist eine von Red Hat entwickelte Produktreihe von Container-Anwendungsplattformen für Cloud-Computing, welche unter anderem auf Kubernetes aufbaut.

Ab Version 1.5.0p13 kann Checkmk auch ein OpenShift-basiertes Kubernetes überwachen. Das Vorgehen ist sehr ähnlich wie oben beschrieben, weicht aber beim Aufsetzen des Clusters für das Monitoring in einigen Details ab. Für das Monitoring können Sie in OpenShift ein eigenes Projekt anlegen. Das get über die Kommandozeile mit:

root@linux# oc new-project check-mk
Now using project "check-mk" on server "https://192.168.42.62:8443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app centos/ruby-25-centos7~https://github.com/sclorg/ruby-ex.git

to build a new example application in Ruby.

5.2. Serviceaccount anlegen

Der nächste Schritt ist das Anlegen eines Serviceaccounts. Dies geht mit:

root@linux# oc create serviceaccount check-mk
serviceaccount/check-mk created

5.3. Clusterrolle zuordnen

In Openshift gibt es bereits die ClusterRole cluster-reader mit Leserechten, die Sie für den Serviceaccount nutzen können. Also ist es nicht notwendig, extra eine neue ClusterRole einzurichten. Dem Serviceaccount können Sie mit dem folgenden Befehl die ClusterRole cluster-reader zugeordnen:

oc adm policy add-cluster-role-to-user cluster-reader -z check-mk
cluster role "cluster-reader" added: "check-mk"

5.4. Weiteres Vorgehen

Die restlichen Schritte für die Aufnahme des Clusters in das Monitoring sind wie am Anfang des Artikels beschrieben. Allerdings benutzen Sie als Kommandozeilenbefehl immer das Tool von Openshift, als oc, anstelle des im Artikel beschriebenen kubectl. (z. B. bei der Abfrage des Serviceaccounts und des Tokens). Die IP-Adresse und den Port des Clusters können Sie sich mit oc status ausgeben lassen.