Mehrere Protokolldateien in einem Verzeichnis zusammenfassen

Mehrere Protokolldateien in einem Verzeichnis zusammenfassen

Auf einer meiner Maschinen läuft ein K3s-Einzelknotencluster. Ich habe noch keine Protokollierungsinfrastruktur eingerichtet und würde dies vorerst als zukünftige Lernerfahrung aufheben.

Auf diesem K3s führe ich einige Cron-Jobs aus, die Protokolle für jeden der Jobs in einer separaten Datei erstellen. Ich kann sie auf /var/log/containers/cron-job-*dem Host-Computer beobachten. Diese Protokolle verschwinden nach einer bestimmten Zeit (successfulJobsHistoryLimit: 3). Neue Jobinstanzen erstellen neue Protokolldateien.

Ich kann kein einfaches Tool finden, das dieses Protokollverzeichnis überwachen könnte, vorzugsweise mit einem Dateinamenmuster, und diese kleinen Jobprotokolle in einer einzigen Protokolldatei streamen/zusammenführen könnte, einschließlich der neu erstellten Dateien. Es macht mir nichts aus, wenn der Dateiname verloren geht, ich möchte nur, dass die Protokollzeilen in einer Datei enden, die als Archiv aller Jobläufe dient.

Was habe ich beachtet?

Ich könnte einfach ein Skript hinzufügen, um diese Dateien zu caten und mit einem Intervall in eine Zieldatei anzuhängen, aber ich müsste verfolgen, welche Dateien bereits eingefügt wurden, falls die Jobs nicht mehr synchron sind oder sich das Cron-Intervall ändert. Außerdem möchte ich diese Funktionalität möglicherweise für Pods erweitern, die „lang laufen“, und in diesem Fall müsste ich anfangen, aktualisierte Zeilen in Protokollen zu verfolgen.

Alle Beispiele, die ich gefunden habe, befassen sich mit Echtzeit-Tailing auf dem Bildschirm, was nicht das ist, was ich brauche. Ich brauche eher Multi-Tailing in eine Zielprotokolldatei.

Irgendwelche Ideen? (Ich würde auch eine Art einfaches Beispiel für einen Kubernetes-Logging-Hook akzeptieren)

Antwort1

Ich biete eine Lösung an, die ich jetzt für mich selbst ausgewählt habe. Es ist nicht die Antwort, nach der ich gesucht habe, aber eine, die mit dem Strom zu schwimmen scheint. Ich bin immer noch neugierig, ob dies mit einem gängigen Unix-Befehl erledigt werden könnte.

Wie dem auch sei, ich habe Folgendes getan:

Der übliche Weg scheint ein Werkzeug namensFluentd, mit dem Sie Protokolle aus verschiedenen Quellen sammeln und sie an einen beliebigen Ort transportieren können – eine Art ETL für Protokolle.

Ich habe mich dafür entschieden, die Protokolle an einen Syslog-Server zu senden, da ich bereits einen laufenden Server hatte, aber Sie können hier auch jedes der Ausgabe-Plugins auswählen:Ausgabe-Plugins. Es gibt auch eine große Anzahl zusätzlicher Plugins:Alle Plugins

Schritt 1

Holen Sie sich ein Fluentd-Setup, auf dem das Plugin remote_syslog installiert ist. Das ist nicht im offiziellen Docker-Image enthalten, aber Sie können es selbst einrichten.

FROM fluent/fluentd:v1.14.0-1.0
USER root

# https://github.com/fluent-plugins-nursery/fluent-plugin-remote_syslog
RUN fluent-gem install fluent-plugin-remote_syslog

USER fluent

Erstellen Sie das Image und übertragen Sie es in Ihr Register.

Schritt 2

Als nächstes richten Sie ein Fluentd-Bereitstellungsmanifest mit schreibgeschützten Volume-Ansprüchen ein, um auf Pod-Protokolle zuzugreifen. Die eigentlichen Dateien befinden sich in /var/log/pods/* und /var/log/containers enthält tatsächlich symbolische Links. Wir brauchen eigentliche Dateien. Diese Protokolle gehören dem Root auf dem Hostcomputer und ein einfacher Fluent-Benutzer hat keinen Zugriff, um sie zu lesen. Wir müssen einige Sicherheitskontexte festlegen. Damit alles funktioniert, habe ich die Root-Gruppe für die fsGroup verwendet. Sie können gerne tiefer graben und die optimale Lösung in Bezug auf die Sicherheit finden/kommentieren.

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      securityContext:
        fsGroup: 0
      volumes:
        - name: varlogpods-pv
          persistentVolumeClaim:
            claimName: pvc-var-log-pods
            ...
      containers:
        - name: fluentd
          image: your/fluentd-image

Mein vollständiges Manifest finden Sie in diesem Gist:Fluentd-Bereitstellung

Schritt 3

Vor der Bereitstellung müssen Sie dort auch einige Regeln einrichten fluent.confund beschreiben.

Meines ist so eingestellt, dass es mit einer Protokollzeile wie dieser übereinstimmt:

2022-04-26T20:05:00.847016854+03:00 stderr F time="2022-04-26 17:05:00" level=info msg="processing 3 records ..."

Weitere Informationen zum Tail-Plugin:Schwanz

    <source>
      @type tail
      @id in_tail_container_logs
      path "/var/log/pods/default_cron-*/*/*.log"
      pos_file "/tmp/cron_.log.pos"
      read_from_head true
      tag cron
      <parse>
        @type regexp
        expression /^(?<logtime>[^ ]*) .* level=(?<level>[^ ]*) msg="(?<message>[^"]*)"$/ 
        time_key logtime
        time_format %FT%T.%N%:z
      </parse>
    </source>
    
    <match cron>
     @type remote_syslog
     host 172.16.3.10
     port 514
     protocol udp
     severity info
     program "fluentd"
     hostname "k3sserver"
     
     <buffer>
     </buffer>
     
     <format>
      @type single_value
      message_key message
     </format>
    </match>

Ein wichtiges Konfigurationsattribut hier ist, read_from_head truedass die Protokolldateien von oben gelesen werden. Dies ist für dieses Szenario erforderlich, da die Pod-Protokolle rotieren. Wir möchten, dass Fluentd das vollständige Pod-Protokoll liest und nicht nur einige Aktualisierungszeilen am Ende. Bei kurzen Cron-Jobs wird die Protokolldatei einfach angezeigt und Tail meldet keine Anfangszeilen darin.

Schritt 4

Probieren Sie die Konfiguration aus und versuchen Sie es immer wieder. Vergessen Sie nicht, Ihre Bereitstellung neu zu starten, nachdem Sie die Konfiguration in configMap aktualisiert haben.

Einige Auszüge aus der Suchspur:

verwandte Informationen