This entry is part 8 of 8 in the series Kubernetes - so startest Du durch!

Die wichtigsten Bausteine zum Starten deiner Anwendung kennst du bereits aus unserer Blogserie. Für den Betrieb fehlen dir noch Metriken und Logs deiner Anwendungen? Nach diesem Blogpost kannst du letzteres abhaken.

Logging mit Loki und Grafana in Kubernetes – ein Überblick

Zum Sammeln und Verwalten deiner Logs bieten sich auch für Kubernetes eine der wohl bekanntesten, schwergewichtigen Lösungen an. Diese bestehen in der Regel aus Logstash oder Fluentd zum Sammeln, gepaart mit Elasticsearch zum Speichern und Kibana bzw. Graylog zur Visualisierung deiner Logs.

Neben dieser klassischen Kombination gibt es seit wenigen Jahren mit Loki und Grafana einen neuen, leichtgewichtigeren Stack! Die grundlegende Architektur unterscheidet sich kaum zu den bekannten Setups.

Promtail sammelt auf jedem Kubernetes Node die Logs aller Container und sendet diese an eine zentrale Loki-Instanz. Diese aggregiert alle Logs und schreibt diese in ein Storage-Backend. Zur Visualisierung wird Grafana verwendet, welches sich die Logs direkt von der Loki-Instanz holt.

Der größte Unterschied zu den bekannten Stacks liegt wohl im Verzicht auf Elasticsearch. Dies spart Ressourcen und Aufwand, da somit auch kein dreifach replizierter Volltext-Index gespeichert und administriert werden muss. Und gerade wenn man beginnt, seine Anwendung aufzubauen, hört sich ein schlanker und einfacher Stack vielsprechend an. Wächst die Anwendungslandschaft, werden einzelne Komponenten von Loki in die Breite skaliert, um die Last auf mehrere Schultern zu verteilen.

Kein Volltextindex? Wie funktioniert das?

Zur schnellen Suche verzichtet Loki natürlich nicht auf einen Index, aber es werden nur noch Metadaten (ähnlich wie bei Prometheus) indexiert. Der Aufwand, den Index zu betreiben, wird dadurch sehr verkleinert. Für dein Kubernetes-Cluster werden somit hauptsächlich Labels im Index gespeichert und deine Logs werden automatisch anhand derselben Metadaten organisiert wie auch deine Anwendungen in deinem Kubernetes-Cluster. Anhand eines Zeitfensters und den Labels findet Loki schnell und einfach deine gesuchten Logs.

Zum Speichern des Index kann aus verschiedenen Datenbanken gewählt werden. Neben den beiden Cloud-Datenbanken BigTable und DynamoDB kann Loki seinen Index auch lokal in Cassandra oder BoltDB ablegen. Letztere unterstützt keine Replikation und ist vor allem für Entwicklungsumgebungen geeignet. Loki bietet mit boltdb-shipper eine weitere Datenbank an, welche aktuell noch in Entwicklung ist. Diese soll vor allem Abhängigkeiten zu einer replizierten Datenbank entfernen und regelmäßig Snapshots des Index im Chunk-Storage speichern (siehe unten).

Ein kleines Beispiel

Ein pod produziert mit stdout und stderr zwei Log-Streams. Diese Log-Streams werden in sogenannte Chunks zerlegt und komprimiert, sobald eine gewisse Größe erreicht wurde oder ein Zeitfenster abgelaufen ist.

Ein Chunk enthält somit komprimierte Logs eines Streams und wird auf eine maximale Größe und Zeiteinheit beschränkt. Diese komprimierten Datensätze werden dann im Chunk-Storage gespeichert.

Label vs. Stream

Eine Kombination aus exakt gleichen Labels (inkl. deren Werte) definiert einen Stream. Ändert man ein Label oder dessen Wert, entsteht ein neuer Stream. Die Logs aus stdout eines nginx-Pods be finden sich z.B. in einem Stream mit den Labels: pod-template-hash=bcf574bc8, app=nginx und stream=stdout.

Im Index von Loki werden diese Chunks mit den Labels des Streams und einem Zeitfenster verknüpft. Bei einer Suche muss im Index somit nur nach Labels und Zeitfenster gefiltert werden. Entspricht eine dieser Verknüpfungen den Suchkriterien, wird der Chunk aus dem Storage geladen und enthaltene Logs werden entsprechend der Suchanfrage gefiltert.

Chunk Storage

Im Chunk Storage werden die komprimierten und zerstückelten Log-Streams gespeichert. Wie beim Index kann auch hier zwischen verschiedenen Storage-Backends gewählt werden. Aufgrund der Größe der Chunks wird ein Object Store wie GCS, S3, Swift oder unser Ceph Object Store empfohlen. Die Replikation ist damit automatisch mit inbegriffen und die Chunks werden anhand eines Ablaufdatums auch selbständig vom Storage entfernt. In kleineren Projekten oder Entwicklungsumgebungen kann man aber natürlich auch mit einem lokalen Dateisystem beginnen.

Visualisierung mit Grafana

Zur Darstellung wird Grafana verwendet. Vorkonfigurierte Dashboards können leicht importiert werden. Als Query Language wird LogQL verwendet. Diese Eigenkreation von Grafana Labs lehnt sich stark an PromQL von Prometheus an und ist genauso schnell gelernt. Eine Abfrage besteht hierbei aus zwei Teilen:
Zuerst filtert man mithilfe von Labels und dem Log Stream Selector nach den entsprechenden Chunks. Mit = macht man hier immer einen exakten Vergleich und =~ erlaubt die Verwendungen von Regex. Wie üblich wird mit ! die Selektion negiert.
Nachdem man seine Suche auf bestimmte Chunks eingeschränkt hat, kann man diese mit einer Search Expression erweitern. Auch hier kann man mit verschiedenen Operatoren wie |= und |~ das Ergebnis weiter einschränken. Ein paar Beispiele zeigen wohl am schnellsten die Möglichkeiten:

Log Stream Selector:

{app = "nginx"}
{app != "nginx"}
{app =~ "ngin.*"}
{app !~ "nginx$"}
{app = "nginx", stream != "stdout"}
Search Expression:


{app = "nginx"} |= "192.168.0.1"
{app = "nginx"} != "192.168.0.1"
{app = "nginx"} |~ "192.*" 
{app = "nginx"} !~ "192$"

Weitere Möglichkeiten wie Aggregationen werden ausführlich in der offiziellen Dokumentation von LogQL erklärt.

Nach dieser kurzen Einführung in die Architektur und Funktionsweise von Grafana Loki legen wir natürlich gleich mit der Installation los. Viele weitere Informationen und Möglichkeiten zu Grafana Loki gibt es natürlich in der offiziellen Dokumentation.

Get it running!

Du willst Loki einfach ausprobieren?

Mit dem NWS Managed Kubernetes Cluster kannst du auf die Details verzichten! Mit einem Klick startest du deinen Loki Stack und hast dein Kubernetes Cluster immer voll im Blick!

 

Wie üblich mit Kubernetes ist ein laufendes Beispiel schneller deployed als die Erklärung gelesen. Mithilfe von Helm und einigen wenigen Variablen ist dein schlanker Logging Stack schnell installiert. Zuerst initialisieren wir zwei Helm-Repositories. Neben Grafana fügen wir auch noch das offizielle Helm stable Charts-Repository hinzu. Nach zwei kurzen helm repo add Befehlen haben wir Zugang zu den benötigten Loki und Grafana Charts.

Helm installieren

$ brew install helm
$ apt install helm
$ choco install kubernetes-helm

Dir fehlen die passenden Quellen? Auf helm.sh findest du eine kurze Anleitung für dein Betriebssystem.

 

$ helm repo add loki https://grafana.github.io/loki/charts
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/

 

Loki und Grafana installieren

Für deinen ersten Loki-Stack benötigst du keine weitere Konfiguration. Die Default-Werte passen sehr gut und helm install erledigt den Rest. Vor der Installation von Grafana setzen wir zuerst noch dessen Konfiguration mithilfe der bekannten Helm-Values-Dateien. Speichere diese mit dem Namen grafana.values ab.

Neben dem Passwort für den Administrator wird auch das eben installierte Loki als Datenquelle gesetzt. Zur Visualisierung importieren wir gleich noch ein Dashboard und die dafür benötigten Plugins. Somit installiert du gleich ein für Loki konfiguriertes Grafana und kannst direkt nach dem Deploy loslegen.

grafana.values:

---
adminPassword: supersecret

datasources:
  datasources.yaml:
    apiVersion: 1
    datasources:
    - name: Loki
      type: loki
      url: http://loki-headless:3100
      jsonData:
        maxLines: 1000

plugins:
  - grafana-piechart-panel

dashboardProviders:
  dashboardproviders.yaml:
    apiVersion: 1
    providers:
      - name: default
        orgId: 1
        folder:
        type: file
        disableDeletion: true
        editable: false
        options:
          path: /var/lib/grafana/dashboards/default

dashboards:
  default:
    Logging:
      gnetId: 12611
      revison: 1
      datasource: Loki

 

Die eigentliche Installation erfolgt mithilfe von helm install. Der erste Parameter ist ein frei wählbarer Name. Mit dessen Hilfe kannst du dir auch schnell einen Überblick verschaffen:

$ helm install loki loki/loki-stack
$ helm install loki-grafana stable/grafana -f grafana.values
$ kubectl get all -n kube-system -l release=loki

 

Nach dem Deployment kannst du dich als admin mit dem Passwort supersecret einloggen. Damit du direkt auf das Grafana Webinterface zugreifen kannst, fehlt dir noch noch ein port-forward:

$ kubectl --namespace kube-system port-forward service/loki-grafana 3001:80

Die Logs deiner laufenden Pods sollten sofort im Grafana sichtbar sein. Probier doch die Queries unter Explore aus und erkunde das Dashboard!

 

Logging mit Loki und Grafana in Kubernetes – das Fazit

Grafana Labs bietet mit Loki einen neuen Ansatz für ein zentrales Logmanagement. Durch die Verwendung von kostengünstigen und leicht verfügbaren Object Stores wird eine aufwändige Administration eines Elasticsearch-Clusters überflüssig. Das einfache und schnelle Deployment ist auch ideal für Entwicklungsumgebungen geeignet. Zwar bieten die beiden Alternativen Kibana und Graylog ein mächtiges Featureset, aber für manche Administratoren ist Loki mit seinem schlanken und einfachen Stack vielleicht verlockender.

Achim Ledermüller
Achim Ledermüller
Lead Senior Systems Engineer

Der Exil Regensburger kam 2012 zu NETWAYS, nachdem er dort sein Wirtschaftsinformatik Studium beendet hatte. In der Managed Services Abteilung ist unter anderem für die Automatisierung des RZ-Betriebs und der Evaluierung und Einführung neuer Technologien zuständig.