56 Logging in Kubernetes

56.1 Motivation

Logging ist ein kritischer Aspekt des Systemmanagements und der Betriebsüberwachung in Kubernetes. Es ermöglicht Entwicklern und Systemadministratoren, Einblick in das Verhalten von Anwendungen und die Leistung von Clustern zu erhalten. Die Protokollierung unterstützt bei:

56.2 Cluster-Level Logging

Cluster-Level Logging in Kubernetes bezieht sich auf das Sammeln und Speichern von Log-Daten auf einer Ebene, die unabhängig von einzelnen Knoten, Pods oder Containern ist. Dieses Konzept ist wichtig, da:

56.2.1 Kubernetes Native Logging-Lösungen

Kubernetes selbst bietet keine native Speicherlösung für Log-Daten. Stattdessen können Administratoren und Entwickler auf verschiedene externe Lösungen zurückgreifen, wie:

56.2.2 Best Practices

Um ein effektives Logging-System in Kubernetes zu implementieren, sollten folgende Best Practices beachtet werden:

56.3 Application Level Logging in Kubernetes

56.3.1 Handhabung von Application Level Logging

Application Level Logging in Kubernetes konzentriert sich auf die Erfassung und Verwaltung von Protokollen, die speziell von den Anwendungen innerhalb der Pods erzeugt werden. Diese Form des Loggings ist entscheidend für die Analyse und das Verständnis des Anwendungsverhaltens sowie der Performance. Es liefert detaillierte Informationen zu Vorgängen auf Anwendungsebene und ist eine wichtige Ergänzung zum Cluster-Level Logging für eine umfassende Überwachung und sollte daher mit Bedacht implementiert und gepflegt werden.

Es umfasst:

56.3.2 Speicherung der Daten

Die Daten für das Application Level Logging werden oft wie folgt vorgehalten:

56.3.3 Unterschiede zum Cluster-Level Logging

56.3.4 Best Practices für Application Level Logging

56.4 Aufbau einer Logging-Pipeline in Kubernetes

56.4.1 Data Source

Die Quelle der Log-Daten in einem Kubernetes-Cluster sind typischerweise:

56.4.2 Aggregator

Ein Log-Aggregator sammelt Logs von verschiedenen Quellen und bereitet sie für die Speicherung vor. Beispiele sind:

56.4.3 Log Storage

Nach der Aggregation werden Logs in einem zentralen Speichersystem abgelegt. Beliebte Optionen sind:

56.4.4 Visualization

Visualisierungswerkzeuge helfen dabei, die gesammelten Daten zu analysieren und verständlich darzustellen:

56.4.5 Beispiel einer Logging-Pipeline

Logging Pipeline
  1. Erfassung: Container schreiben stdout und stderr, die von einem Sidecar-Container oder einem Node-Agent wie Fluent Bit erfasst werden.
  2. Aggregation: Fluent Bit leitet die Logs an einen zentralen Fluentd-Aggregator weiter, der die Daten filtert und bereinigt.
  3. Speicherung: Fluentd sendet die aufbereiteten Logs an Elasticsearch, wo sie indiziert und gespeichert werden.
  4. Analyse und Visualisierung: Kibana verbindet sich mit Elasticsearch, um die Daten zu visualisieren und Benutzern das Durchführen von Abfragen zu ermöglichen.

56.4.6 Wichtige Überlegungen

56.5 Kubernetes Logging: Praktischer Leitfaden

56.5.1 Abrufen von Logs auf Cluster-Ebene

56.5.1.1 API-Server-Logs

API-Server-Logs sind essentiell, um die Aktionen zu verstehen, die auf dem Cluster ausgeführt wurden:

kubectl logs kube-apiserver-master -n kube-system

Beispieloutput:

I1104 19:00:00.123456 1 get.go:238] Reviewing request: /api/v1/namespaces/default/pods

56.5.1.2 Controller-Manager-Logs

Diese Logs sind nützlich, um die Arbeitsweise des Controllers zu beobachten:

kubectl logs kube-controller-manager-master -n kube-system

Beispiel output:

I1104 19:05:00.654321 1 replica_set.go:450] Too few replicas for ReplicaSet default/my-replicaset, need 2, creating 1

56.5.1.3 Scheduler-Logs

Scheduler-Logs helfen Ihnen, zu verstehen, wie und warum Pods auf bestimmte Knoten platziert werden:

kubectl logs kube-scheduler-master -n kube-system

Beispiel output:

I1104 19:10:00.789012 1 scheduler.go:207] Successfully assigned default/my-pod to worker-node1

56.5.1.4 Etcd-Logs

Etcd ist die konsistente und hochverfügbare Datenbank, die Kubernetes für alle Clusterdaten verwendet:

kubectl logs etcd-master -n kube-system

Beispiel output:

I1104 19:15:00.890123 1 snapshot.go:278] Saved snapshot at index 100000

56.5.2 Application-Level Logging

56.5.2.1 Container-Logs abrufen

Für das Debugging auf Anwendungsebene ist der Zugriff auf Container-Logs erforderlich:

kubectl logs <POD-NAME> -n <NAMESPACE>

Beispiel output:

2023-11-04T19:20:00.987654Z INFO Started POST "/api/v1/items"
2023-11-04T19:20:01.123456Z ERROR Failed to retrieve data: Timeout

56.5.2.2 Logs aller Container in einem Pod

Mit diesem Befehl erhalten Sie Logs von allen Containern in einem Pod:

kubectl logs <POD-NAME> -n <NAMESPACE> --all-containers=true

Beispiel output:

Container 1:
2023-11-04T19:25:00.345678Z INFO Accepting connections on port 8080

Container 2:
2023-11-04T19:25:00.456789Z WARN Memory usage is on the high side: 80% of limit

56.5.2.3 Logs mit journalctl

journalctl ermöglicht es Ihnen, systemd-journald-Ereignisse zu sehen, einschließlich der Logs von Container-Runtimes:

journalctl -u kubelet

Beispieloutput:

Nov 04 19:30:00 master-node kubelet[1234]: I1104 19:30:00.567890 kubelet.go:213] Starting kubelet main sync loop.

56.5.2.4 Logs aus /var/log

Direkter Zugriff auf Logdateien für ältere Systeme ohne systemd:

cat /var/log/kube-apiserver.log

Beispieloutput:

I1104 19:35:00.678901 server.go:154] Handling request: /api/v1/nodes

56.5.3 Persistente Log-Archivierung

56.5.3.1 Einrichten von Fluentd für die Log-Sammlung

Einrichten eines DaemonSets, das Fluentd auf allen Nodes installiert, um Logs zu sammeln:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
spec:
  ...

56.5.3.2 Einrichten von Elasticsearch zum Speichern der Logs

Elasticsearch als Backend zum Speichern und Indizieren der Logs:

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: kube-system
spec:
  ...

56.5.3.3 Kibana für das Log-Monitoring verwenden

Kibana bietet eine Web-Oberfläche, um die in Elasticsearch gespeicherten Logs zu durchsuchen und zu visualisieren:

apiVersion: v1
kind: Service
metadata:
  name: kibana
  namespace: kube-system
spec:
  ...

56.5.4 Beispiel

Das nachfolgende Beispiel zeigt die Logfile Analyse eines Multicontainer PODS

kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
webserver            2/2     Running   0          26h
log-app              2/2     Running   0          26h
redis-st-1           1/1     Running   0          26h
ambassador-example   2/2     Running   0          26h
redis-st-0           1/1     Running   0          26h

Mit folgendem Befehl werden die Logs des ersten Containers im POD gelesen.

kubectl logs webserver
Defaulted container "webserver" out of: webserver, adapter
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
.
.
.

In der Regel soll aber gezielt ein bestimmter Container angesprochen. Dazu wird erst per kubectl describe die Container ID herausgesucht.

kubectl describe pod/webserver
Name:             webserver
Namespace:        default
.
.
Containers:
  webserver:
    Container ID:   
    .
    .
  adapter:
    Container ID:  
    .
    .

Mit dem Kommando

kubectl logs pods/webserver -c webserver

wird auf die bereits bekannten Logs des webserver Container zugegriffen und mit dem Kommando

kubectl logs pods/webserver -c adapter

sind auch die Logfiles des zweiten Container erreichbar.

2023/11/04 10:39:52 Starting NGINX Prometheus Exporter Version=0.4.2 GitCommit=f017367
2023/11/04 10:39:53 NGINX Prometheus Exporter has successfully started

Der Logoutput kann dabei mit den üblichen Filterkommandos der verwendeten Shell reduziert werden und es stehen Filteroptionen des log Kommandos zur Verfügung.

Beispiel: Das folgende Kommando zeigt die Logging Einträge der vergangenen Stunde an:

kubectl logs pods/webserver -c adapter --since 1h

kubectl logs <pod-name> --since=<time>: Zeigt Logs seit einem bestimmten Zeitraum an (z.B. 1h für eine Stunde).

kubectl logs <pod-name> --tail=<number>: Zeigt die letzten <number> Zeilen des Logs.

kubectl logs <pod-name> --since-time=<RFC3339-timestamp>: Zeigt Logs seit einem exakten Zeitpunkt im RFC3339 Format.

kubectl logs <pod-name> --timestamps: Fügt jedem Logeintrag einen Zeitstempel hinzu.

kubectl logs <pod-name> -f: Streamt die Logs in Echtzeit (follow).

kubectl logs <pod-name> --previous: Zeigt Logs des zuletzt gestoppten Containers an.

kubectl logs <pod-name> -c <container-name> --limit-bytes=<number>: Begrenzt die Logausgabe auf eine bestimmte Anzahl von Bytes.

Reference

56.6 Kubernetes Logging im k3s Cluster

56.6.1 k3s Cluster-Level Logs

Für das Log-Management in einem k3s-Cluster, einer auf Edge, IoT und CI/Workloads spezialisierten, ressourcenschonenden Kubernetes-Distribution, ist Kenntnis der Systemkomponenten und korrekter Befehle notwendig. Diese ermöglichen eine effektive Überwachung des Clusterzustands und erlauben zeitnahe Eingriffe bei auftretenden Problemen.

56.6.1.1 Zustand der k3s Cluster-Komponenten prüfen

sudo k3s kubectl get pods -n kube-system

56.6.1.2 Logs von k3s Cluster-Komponenten abrufen

56.6.2 Node-Level Logs

Unter k3s sind die Node-Level Logs ähnlich denen eines traditionellen Kubernetes-Clusters:

56.6.3 Pod- und Container-Level Logs

Um Logs von Pods und Containern in einem k3s Cluster abzurufen, nutzen Sie das k3s-Äquivalent von kubectl:

56.6.4 Persistente Logs

k3s unterstützt auch die Konfiguration von persistentem Logging. Logs können in einem Persistent Volume gespeichert oder an externe Logging-Dienste wie ELK Stack oder Splunk weitergeleitet werden.