Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Lassen Sie uns die Grundlagen des Loggings in Docker und Kubernetes besprechen und anschließend zwei Werkzeuge betrachten, die sich bedenkenlos in der Produktion verwenden lassen: Grafana Loki und den EFK-Stack (Elasticsearch + Fluent Bit + Kibana).

Der Material des Artikels ist eine Zusammenfassung aus einer offenen Vorlesung der Schule „Slyerm“. Wenn Sie interessiert sind und vor allem einen Produktionsbedarf haben, können Sie eine vollständige Schulung absolvieren – melden Sie sich für den Kurs an über Monitoring und Logging der Infrastruktur in Kubernetes.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Logging in Docker

Auf der Kubernetes-Ebene laufen Anwendungen in Pods, aber auf einer tieferen Ebene arbeiten sie normalerweise in Docker. Daher muss das Logging so eingerichtet werden, dass Protokolle von den Containern gesammelt werden. Docker startet die Container – also müssen wir klären, wie das Logging auf Docker-Ebene funktioniert.

Ich hoffe, jeder Leser weiß: Die Anwendungsprotokolle sollten in stdout/stderr und nicht im Container selbst geschrieben werden. Die Protokolle werden vom Docker Daemon aggregiert, der genau mit den Protokollen arbeitet, die an stdout/stderr gesendet werden. Darüber hinaus kann das Schreiben von Protokollen im Container zu Problemen führen: Der Container wächst aufgrund des zunehmenden Protokolls (da im Container wahrscheinlich kein Logrotate vorhanden ist), und der Docker Daemon ist sich dieses Protokolls nicht bewusst.

Docker bietet mehrere Log-Treiber oder Plugins zum Sammeln von Container-Protokollen. In der kostenlosen Version Docker Community Edition (CE) gibt es weniger Log-Treiber als in der kommerziellen Docker Enterprise Edition (EE).

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Docker EE habe ich noch nie praktisch verwendet: In Southbridge halten wir uns an Open-Source-Lösungen, und die meisten unserer Kunden benötigen die zusätzlichen Funktionen von Docker EE nicht.

Log-Treiber in Docker CE:

local — Protokollierung in interne Docker Daemon-Dateien;
json-file — Erstellung einer json-Logdatei im Verzeichnis jedes Containers;
journald — Versenden von Protokollen an journald.

Die Protokollierungseinstellungen in Docker befinden sich in der Datei daemon.json.

Im Feld "log-driver" wird das Plugin angegeben, und im Feld "log-opts" dessen Einstellungen. Im obigen Beispiel wurde das Plugin "json-file" angegeben, die Größenbegrenzung für das Protokoll — "max-size": "10m"; die Dateibegrenzung (Rotiereinstellungen) — "max-file": "3"; und auch die Werte, die den Protokollen hinzugefügt werden.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Einige Einstellungen des Log-Treibers können über das Befehlszeilen-Tool festgelegt werden. Das ist praktisch, wenn ein einzelner Container mit einem anderen Log-Treiber gestartet werden muss.

So sieht das Protokollierungsschema in Docker aus:

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

So funktioniert das Schema: Der Log-Treiber, beispielsweise json-file, erstellt Dateien. Die Log-Collector (Rsyslog, Fluentd, Logagent und andere) sammeln diese Dateien und übertragen sie zur Speicherung in Elastic, Sematext oder andere Speicher.

Besonderheiten des Loggings in Kubernetes

Vereinfacht sieht das Logging-Schema in Kubernetes so aus: Es gibt einen Pod, in dem ein Container läuft, der die Logs an stdout/stderr sendet. Dann erstellt Docker eine Datei und protokolliert die Logs, die anschließend rotiert werden können.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Betrachten wir die Besonderheiten des Loggens in Kubernetes.

Logs zwischen Deployments speichern. Dies ist eine Voraussetzung für die korrekte Konfiguration des Loggings. Wenn Logs zwischen Deployments nicht gespeichert werden, werden beim Upgrade auf eine neue Version der Anwendung die Logs der vorherigen Version überschrieben, auch ein Neustart des Containers kann den Verlust von Logs zur Folge haben. Kubernetes verfügt über den Schalter —previous, mit dem die Logs der Anwendung vor dem letzten Neustart des Pods eingesehen werden können, aber nicht tiefer.

Logs von allen Instanzen aggregieren. Wenn Mikrodienste in der Cloud gehostet werden, liegt die Systemüberwachung beim Cloud-Anbieter. Wenn Mikrodienste auf eigener Hardware laufen, müssen neben den Container-Logs auch die Logs des Systems gesammelt werden.

Früher gab es keine praktischen Werkzeuge zur Sammlung von Logs sowohl vom System als auch von Mikroservices. Normalerweise sammelte ein Werkzeug die Systemlogs (zum Beispiel Rsyslog), während ein anderes die Logs von Docker (zum Beispiel journal-bit mit einer Konfiguration des Log-Treibers Docker auf journald) erfasste. Wir haben versucht, journal-bit zu verwenden, um Logs sowohl von Containern (im Log-Treiber von Docker anzugeben, dass die Logs in journald geschrieben werden sollen) als auch vom System zu sammeln (in CentOS 7 gibt es bereits systemd und journald). Die Lösung funktioniert, ist aber nicht ideal. Wenn es viele Logs gibt, beginnt journal-bit zu ruckeln und Nachrichten gehen verloren.

Die Experimente gingen weiter – und ich fand einen anderen Weg. In CentOS 7 werden die Hauptsystemlogs (messages, audit, secure) in var-logs in Form von Dateien dupliziert. Auch in Docker kann man das Speichern der Logs in json-Dateien konfigurieren. Dementsprechend können diese Dateien aus CentOS 7 und Docker zusammen gesammelt werden.

Im Laufe der Zeit wurde die Lösung ELK Stack populär. Dies ist eine Kombination mehrerer Werkzeuge: Elasticsearch, Logstash und Kibana.

Elasticsearch speichert die Logs von Containern, Logstash sammelt die Logs von Instanzen, und Kibana ermöglicht die Verarbeitung der erhaltenen Logs sowie das Erstellen von Diagrammen. Eine Zeit lang wurde der ELK Stack aktiv genutzt, aber meiner Meinung nach geht seine Zeit zu Ende. Warum, erzähle ich später.

Metadaten hinzufügen. Pods, Anwendungen und Container können überall ausgeführt werden. Darüber hinaus kann eine Anwendung mehrere Instanzen haben. Die Protokolle werden in einem einheitlichen Format aufgezeichnet, und wir müssen verstehen, welche genau diese Replik ist, welcher Pod es schreibt und in welchem Namespace er sich befindet. Deshalb ist es erforderlich, Metadaten zu den Protokollen hinzuzufügen.

Protokolle analysieren. Lustig, aber die Kosten für die Unterstützung eines Protokollierungs- und Überwachungssystems können die Ausgaben für die Hauptanwendung übersteigen. Wenn Sie Dutzende oder Hunderttausende von Protokollen pro Sekunde verarbeiten, erscheint das nachvollziehbar, aber man muss dennoch die Grenze kennen. Eine Möglichkeit, diese Grenze zu finden, ist die Analyse der Protokolle.

In der Regel sollten nicht alle Protokolle gesammelt und gespeichert werden; es ist ausreichend, nur einen Teil zu speichern — zum Beispiel Protokolle mit dem Status 'Warnung' oder 'Fehler'. Wenn es um Protokolle von Nginx oder Ingress-Controllern geht, sollten nur die Protokolle gespeichert werden, deren Status von 200 abweicht. Das ist jedoch kein universeller Ratschlag: Wenn Sie irgendwie Analysen zu Nginx-Protokollen durchführen, sollten diese offensichtlich gesammelt werden.

Es wird nicht empfohlen, Protokolle blind zu filtern, da die gefilterten Daten möglicherweise nicht ausreichen, um eine ordnungsgemäße Analyse durchzuführen. Auf der anderen Seite könnte es sinnvoll sein, die Analyse nicht auf der Ebene des Loggings, sondern auf der Ebene der Metrik-Sammlung durchzuführen. Dann müssen keine Hunderttausend Zeilen mit dem Code 200 gespeichert werden. Ein Ansatz wäre, Informationen über Traffic und Fehler aus den Metriken der Ingress-Controller zu beziehen.

Insgesamt sollte man gut darüber nachdenken, was man speichern möchte und wie lange, da sonst eine Situation entstehen kann, in der das Logging-System mehr Ressourcen verbraucht als das Hauptprojekt.

Derzeit gibt es keine standardisierte Lösung für das Logging.Im Gegensatz zum Monitoring, wo es eine am weitesten verbreitete Lösung, Prometheus, gibt, existiert im Logging kein Standard.

Im Rahmen dieser Vorlesung werden wir zwei Werkzeuge betrachten: eines ist populär, das andere gewinnt an Popularität. Neben diesen gibt es auch andere, die wir in diesem Artikel jedoch nicht behandeln werden.

Angesichts aller oben genannten Eigenschaften kann das Logging in Kubernetes nun in einem solchen Schema dargestellt werden:

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Der Container-Log bleibt bestehen, die Rotation ist aktiv, aber ein Sammler-Agent wird eingeführt, der die Logs aufnimmt und zur Speicherung sendet (in der Darstellung — zum Logging Backend). Der Agent läuft auf jedem Knoten und wird in der Regel in Kubernetes ausgeführt.

Jetzt betrachten wir die Logging-Tools.

Grafana Loki

Grafana Loki er ist kürzlich erschienen, hat sich aber bereits einen gewissen Bekanntheitsgrad erarbeitet. Seine Vorteile: einfache Installation, geringer Ressourcenverbrauch, keine Notwendigkeit zur Installation von Elasticsearch, da er die Daten in einer TSDB (zeitbasierten Datenbank) speichert. In meinem vorherigen Artikel erwähnte ich, dass Prometheus Daten in einer solchen Datenbank speichert, und das ist eine der vielen Ähnlichkeiten zwischen den beiden Produkten. Die Entwickler behaupten sogar, dass Loki das 'Prometheus für die Logging-Welt' ist.

Ein kleiner Einschub über TSDB für diejenigen, die nicht gelesen haben. den vorherigen Artikel: TSDB eignet sich hervorragend zur Speicherung großer Datenmengen und Zeitreihen, ist jedoch nicht für die langfristige Speicherung gedacht. Wenn Sie aus irgendeinem Grund Logs länger als zwei Wochen speichern müssen, ist es besser, deren Übertragung in eine andere Datenbank einzurichten.

Ein weiterer Vorteil von Loki ist, dass zur Datenvisualisierung Grafana verwendet wird. Es ist sehr praktisch: In Grafana sehen wir die Überwachungsdaten und können dort auch, verbunden mit Loki, die Protokolle einsehen. Anhand der Protokolle können Grafiken erstellt werden.

Die Architektur von Loki sieht ungefähr so aus:

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Mit einem DaemonSet wird auf allen Servern des Clusters ein Agent — Promtail oder Fluent Bit — bereitgestellt. Der Agent sammelt die Protokolle. Loki holt sie ab und speichert sie in seiner TSDB. Gleichzeitig werden den Protokollen Metadaten hinzugefügt, was praktisch ist: Man kann nach Pods, Namespaces, Containernamen und sogar Labels filtern.

Installationsanleitung für Loki

Loki funktioniert in der vertrauten Benutzeroberfläche von Grafana. Loki hat sogar eine eigene Abfragesprache, die LogQL genannt wird — benannt nach und im Syntax ähnlich zu PromQL in Prometheus. In der Benutzeroberfläche von Loki gibt es Vorschläge für Abfragen, sodass man sie nicht auswendig wissen muss.

Dokumentation zur Sprache LogQL

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs
Loki in der Benutzeroberfläche von Grafana

Mit Filtern kann man in Loki Codes finden ("400", "404" und jeden anderen); die Protokolle von allen Nodes ansehen; alle Protokolle filtern, die das Wort "error" enthalten. Wenn man auf ein Protokoll klickt, öffnet sich eine Karte mit allen Informationen zum Ereignis.

In Loki gibt es ausreichend Werkzeuge, um die benötigten Logs zu extrahieren, obwohl es technisch gesehen ruhig mehr davon geben könnte. Momentan entwickelt sich Loki aktiv weiter und gewinnt an Popularität.

Elastic + Fluent Bit + Kibana (EFK-Stack)

Der EFK-Stack ist ein klassisches und zugleich sehr beliebtes Logging-Tool.

Am Anfang des Artikels wurde das ELK (Elasticsearch + Logstash + Kibana) erwähnt, aber dieser Stack ist veraltet, da Logstash nicht sehr leistungsfähig und gleichzeitig ressourcenintensiv ist. Stattdessen wird nun der leichtere und leistungsfähigere Fluentd eingesetzt, dem später noch Fluent Bit — ein noch leichterer und leistungsfähigerer Collector-Agent — zur Seite steht.

Wenn man den Entwicklern glauben kann, ist Fluent Bit über 100 Mal leistungsfähiger als Fluentd: „Wo Fluentd 20 MB RAM benötigt, benötigt Fluent Bit nur 150 KB“ — ein direktes Zitat aus der Dokumentation. Angesichts dieser Tatsache wird Fluent Bit häufiger verwendet.

Fluent Bit hat weniger Funktionen als Fluentd, deckt jedoch die grundlegenden Anforderungen ab, weshalb wir hauptsächlich Fluent Bit nutzen.

Das EFK-Stack-Arbeitsdiagramm: Der Agent sammelt Protokolle von allen Pods (in der Regel handelt es sich um ein DaemonSet, das auf allen Cluster-Servern ausgeführt wird) und sendet sie an den Speicher (Elasticsearch, PostgreSQL oder Kafka). Kibana verbindet sich mit dem Speicher und ruft alle benötigten Informationen ab.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Kibana stellt die Informationen in einer benutzerfreundlichen Weboberfläche dar. Es gibt Grafiken, Filter und vieles mehr.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Aus den Protokollen können ganze Dashboards erstellt werden.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Die Möglichkeiten von Fluent Bit

Da Fluent Bit im Allgemeinen weniger bekannt ist als Logstash, wollen wir etwas genauer darauf eingehen. Fluent Bit kann logisch in 6 Module unterteilt werden, wobei einige Module mit Plugins ausgestattet werden können, die die Möglichkeiten von Fluent Bit erweitern.

Protokollierung in Kubernetes: So sammeln, speichern, analysieren und verarbeiten Sie Logs

Input-Modul sammelt Protokolle aus Dateien, systemd-Diensten und sogar über TCP-Sockets (man muss nur den Endpunkt angeben, und Fluent Bit beginnt, dorthin zu gehen). Diese Funktionen sind ausreichend, um Protokolle sowohl vom System als auch von Containern zu sammeln.

In der Produktion verwenden wir am häufigsten Plugins tail (man kann es auf einen Ordner mit Protokollen richten) und systemd (man kann angeben, aus welchen Diensten Protokolle gesammelt werden sollen).

Parser-Modul bringt die Protokolle in ein einheitliches Format. Standardmäßig sind die Nginx-Protokolle Zeichenfolgen. Mit dem Plug-in kann diese Zeichenfolge in JSON umgewandelt werden: Felder und deren Werte können festgelegt werden. Mit JSON lässt sich viel einfacher arbeiten als mit der Zeichenprotokollierung, da es flexiblere Sortiermöglichkeiten bietet.

Filtermodul. In diesem Schritt werden unnötige Protokolle herausgefiltert. Zum Beispiel werden nur Protokolle mit dem Wert „warning“ oder bestimmten Labels zur Speicherung weitergeleitet. Die ausgewählten Protokolle gelangen in den Puffer.

Puffermodul. Fluent Bit hat zwei Arten von Puffern: Arbeitsspeicherpuffer und Festplattenspeicher. Der Puffer ist ein temporärer Speicher für Protokolle, der im Fall von Fehlern oder Störungen benötigt wird. Jeder möchte RAM sparen, daher wird oft der Festplattenspeicher gewählt. Es muss jedoch berücksichtigt werden, dass die Protokolle vor dem Speichern auf der Festplatte dennoch im Arbeitsspeicher abgelegt werden.

Routing-/Ausgabemodul enthält Regeln und Adressen für das Senden von Protokollen. Wie bereits erwähnt, können Protokolle an Elasticsearch, PostgreSQL oder beispielsweise Kafka gesendet werden.

Interessant ist, dass Sie Fluent Bit-Protokolle in Fluentd senden können. Da die erste Option leichter und weniger funktionsreich ist, können Sie über sie Protokolle sammeln und an Fluentd senden, wo sie mithilfe zusätzlicher Plugins weiterverarbeitet und in Speicherorte gesendet werden können.

Wenn Sie vorhaben, Elasticsearch zu verwenden...

Zum Abschluss zwei Tipps für diejenigen, die planen, Elasticsearch als Protokollspeicher in der Produktion zu verwenden.

  1. Richten Sie Benachrichtigungen mit ElastAlertein. Dieses Programm extrahiert wichtige Nachrichten aus dem Gesamtstrom der Protokolle und erstellt Alarme per E-Mail oder über einen anderen Kanal. Kürzlich gab es jedoch eine tragische Nachricht, dass das Projekt möglicherweise bald eingestellt wird..
  2. Rotieren Sie Protokolle mithilfe der Anwendung Curator oder API-Anfragen an Elasticsearch. Im Grunde genommen macht Elastic derzeit beträchtliche Fortschritte im Management der Lebenszyklen von Indizes, ohne auf externe Tools zurückgreifen zu müssen. Generell macht es keinen Sinn, Protokolle lange aufzubewahren: Es ist unwahrscheinlich, dass irgendein Log nach zwei Wochen noch benötigt wird — wenn es tatsächlich kritisch ist, wird es in diesen zwei Wochen bestimmt bereits bearbeitet sein. Im schlimmsten Fall können alte Logs archiviert und irgendwo für die Langzeitlagerung geschickt werden. Ich habe von speziellen Logs gehört, die gesetzlich bis zu 5 Jahre aufbewahrt werden müssen. Persönlich habe ich mit so etwas nicht zu tun gehabt, aber ich würde diese Informationen nicht mit normalen Logs gleichsetzen und würde sie möglicherweise sogar separat aufbewahren.

Die Fortsetzung folgt…

Autor: Marsel Ibraev, zertifizierter Kubernetes-Administrator, praktizierender Ingenieur bei der Firma Southbridge, Sprecher und Kursentwickler Slurm.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster