So haben Sie mehrere Protokolldatenströme im Docker

21

Wir haben eine Anwendung, die drei Arten von Protokollen in drei separate Dateien schreibt: Zugriffsprotokolle, allgemeine Anwendungsprotokolle und Systemprotokolle. Das Format (und der Zweck) dieser Protokolle sind sehr unterschiedlich. Und wir haben separate Logforwarder, die sie separat an unser zentrales Logging-System senden.

Basierend auf dem Prinzip, dass Protokolle als Ereignisströme behandelt werden, überlegen wir, von der Verwendung von Dateien zur Standardausgabe überzugehen. Obwohl wir einige Vorteile dieses Ansatzes kennen, würde dies auch bedeuten, dass wir einen zusammengeführten Stream der unterschiedlich formatierten Protokolle erhalten, die wir entweder erneut teilen müssen, bevor wir sie an unser zentrales System (Kibana / Splunk) senden können / etc.) oder drinnen.

Wir fragen uns, ob es Tools oder Empfehlungen gibt, wie wir mit dieser Situation umgehen sollen.

SztupY
quelle
4
Ich denke nicht, dass es das wert ist. Warum sollte man sich mehr Mühe geben, um Protokolldatenströme zusammenzuführen und dann zu teilen, nur weil es ein Prinzip gibt? Dateien sind gut. Dateien funktionieren. Das klingt überarbeitet. Ich würde sagen, dass vielleicht alle Protokolle mit unterschiedlichen Tags usw. in syslog geleitet werden, aber ich muss sagen, wenn jemand in meinem Team dies vorschlägt. Ich wäre enttäuscht.
Assaf Lavie
Da bei der Verwendung von Dateien einige andere Arten von Verwaltungsalpträumen auftreten, insbesondere, wenn sie aus einem Docker-Container generiert werden.
Derzeit scheinen
3
Ich weiß nichts über "Albträume". Ich weiß, dass dies schon eine Weile so ist, und es gibt eine Menge Software, die Ihnen dabei hilft. Protokolldateien werden gedreht und mit Prüfpunkten gelesen - eine Datei ist hierfür eine großartige Abstraktion. Ich würde mich nicht auf ein Prinzip einlassen, das mir aus Angst vor alten, vertrauten Mustern neue Alpträume verkauft. Ihre Protokolldatensätze werden entweder in eine Datei geschrieben oder im Speicher verwaltet (zumindest solange sie im Container verschoben werden). Viel Glück beim Erreichen der Zuverlässigkeit von Protokolldateien mit In-Memory-Stream-Splittern und Fusionen.
Assaf Lavie
@AssafLavie Du solltest es in eine Antwort schreiben, die hochgestuft werden kann. Meiner Meinung nach ist dies eine absolut gültige Sichtweise.
Dan Cornilescu
2
Ich bin mit der gleichen Frage hergekommen. Die einfache Tatsache ist, dass die integrierte Protokollierungsfunktionalität von Docker von allem abhängt, was mit stdout / stderr zu tun hat, daher auch der Protokollierungstreiber und das Ökosystem der Tools von Drittanbietern, die darauf aufbauen. Ich bin versucht, alle meine Protokolle auch auf einem Host-Volume abzulegen, aber ich weiß, dass ich das immer wieder tun muss, wenn meine Container auf k8s oder openshift oder gke oder was auch immer umsteigen, während ich dem Hafenarbeiter folge Ein guter Ansatz wird viel reibungsloser sein. In der Zwischenzeit werde ich nach einer Antwort auf diese berechtigte Frage suchen
Rhabarber

Antworten:

13

Ich bin immer noch auf der Suche nach einem Zusammenführungs- / Aufteilungsansatz, aber mittlerweile scheint dieser in der Kubernetes-Dokumentation empfohlene Ansatz eine vernünftige Lösung zu sein: Verwenden Sie für jedes Ihrer separaten Protokolle einen Beiwagen-Container .

Ein "Beiwagen" ist ein Docker-Container, den Sie neben einem anderen Docker-Container verwenden, um auf irgendeine Weise damit zu arbeiten. In diesem Fall hätten Sie für jedes Ihrer drei Protokolle einen separaten Container, der die Protokolle und Ausgaben auf stdout scannt oder abfängt.

Auf diese Weise hat jeder Ihrer log-sidecar-Container ein eigenes Docker-Log von seinem eigenen Standard. Da Sie auf diese Weise getrennt sind, können Sie Standardmethoden für Docker (und Kubernetes usw.) zum Trennen oder Zusammenfassen verwenden. Das sagt die Kubernetes-Seite:

Mit diesem Ansatz können Sie mehrere Protokolldatenströme von verschiedenen Teilen Ihrer Anwendung trennen, von denen einige das Schreiben in stdout oder stderr möglicherweise nicht unterstützen. Die Logik für das Umleiten von Protokollen ist minimal, sodass es sich kaum um einen signifikanten Overhead handelt. Da stdout und stderr vom kubelet verarbeitet werden, können Sie außerdem integrierte Tools wie kubectl-Protokolle verwenden.

Die "separaten Protokolldatenströme" sind auf die integrierte Kennzeichnung zurückzuführen, die Docker für Protokolle aus verschiedenen Containern anwendet. Eine Beschreibung finden Sie in der Docker-Dokumentation hier:

Die Tag-Protokolloption gibt an, wie ein Tag formatiert werden soll, mit dem die Protokollnachrichten des Containers identifiziert werden. Standardmäßig verwendet das System die ersten 12 Zeichen der Container-ID. Geben Sie eine Tag-Option an, um dieses Verhalten zu überschreiben

Rhabarber
quelle
Erwähnenswert ist die Kehrseite dieses Ansatzes für log-sidecar-containers. Ich frage mich, ob jemand diesen Ansatz in der Praxis versucht.
Yusong
8

Die Idee, sie zu einem Stream zusammenzuführen, um sie später aufzuteilen, klingt schmerzhaft. Ich hatte keinen Grund, dies selbst zu tun, aber hier fange ich an:

  • Wenn Sie den Docker-Container ausführen, erstellen Sie ein Volume, sodass Protokolle vom Host aus problemlos angezeigt / versendet werden können.
  • Verwenden Sie so etwas wie remote_syslog2 , um die Protokolle an Ihren Protokollsammler zu senden

Es fühlt sich nicht gerade elegant an, auch auf dem Host etwas einrichten zu müssen, aber wenn Sie so etwas wie Ansible verwenden, bei dem Sie ein Playbook ausführen und dieses während der Bereitstellung auf der Box einrichten können, sollte es nicht so sein Schlecht.

Bradym
quelle
Diese Lösung kann mit Named Pipes kombiniert werden. Das einzige Problem bei Named Pipes ist, dass sie derzeit nicht auf allen Systemen funktionieren. Sie arbeiten nicht daran Mac
Jens