複数のログファイルをディレクトリに集約する

複数のログファイルをディレクトリに集約する

マシン上で k3s シングルノード クラスターを実行しています。ログ記録インフラストラクチャはまだ設定されていないため、今のところは将来の学習経験として残しておきます。

その k3s で、各ジョブのログを個別のファイルに作成するいくつかの cron ジョブを実行します。/var/log/containers/cron-job-*ホスト マシンでそれらを観察できます。これらのログは、一定時間 (successfulJobsHistoryLimit: 3) が経過すると消えます。新しいジョブ インスタンスによって、新しいログ ファイルが作成されます。

できればファイル名パターンを使用して、ログ ディレクトリを監視し、作成される新しいファイルを含む小さなジョブ ログを 1 つのログ ファイルにストリーム/結合できるシンプルなツールを見つけることができません。ファイル名が失われてもかまいませんが、ログ行が 1 つのファイルにまとめられ、すべてのジョブ実行のアーカイブとして機能するようにしたいだけです。

私が検討したことは何ですか?

これらのファイルを cat して、間隔を空けてターゲット ファイルに追加するスクリプトを追加することもできますが、ジョブが同期されなくなったり、cron 間隔が変更されたりした場合に備えて、どのファイルがすでに挿入されているかを追跡する必要があります。また、この機能を「長時間実行」のポッドに拡張したい場合もあり、その場合は、ログ内の更新された行を追跡する必要があります。

私が見つけた例はすべて、画面上でのリアルタイムのテーリングを扱っていますが、これは私が必要としているものではありません。ターゲット ログ ファイルへのマルチ テーリングが必要です。

何かアイデアはありますか? (Kubernetes の簡単なログ フックの例も歓迎します)

答え1

私が自分で選んだ 1 つの解決策を紹介します。これは私が探していた答えではありませんが、流れに乗ったようです。これを一般的な Unix コマンドで処理できるかどうか、まだ興味があります。

とにかく、私がやったことは次のとおりです:

一般的な方法は、流暢これにより、さまざまなソースからログを収集し、適切な場所に転送できるようになります。これは、ログの ETL のようなものです。

すでに syslog サーバーが稼働していたため、ログを syslog サーバーに送信することを選択しましたが、ここから出力プラグインのいずれかを選択することもできます。出力プラグイン追加のプラグインも多数あります:すべてのプラグイン

ステップ1

remote_syslog プラグインがインストールされた Fluentd セットアップを入手します。これは公式の Docker イメージには付属していませんが、自分でセットアップできます。

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

イメージをビルドし、レジストリにプッシュします。

ステップ2

次に、ポッド ログにアクセスするための読み取り専用ボリューム クレームを持つ Fluentd デプロイメント マニフェストを設定します。実際のファイルは /var/log/pods/* にあり、/var/log/containers には実際のシンボリック リンクが含まれています。実際のファイルが必要です。これらのログはホスト マシンの root が所有しており、通常の Fluent ユーザーに読み取りアクセス権はありません。セキュリティ コンテキストをいくつか設定する必要があります。うまく動作させるために、fsGroup に root グループを使用しました。セキュリティの観点から、さらに深く掘り下げて最適なソリューションを見つけたりコメントしたりしてください。

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

この gist で私の完全なマニフェストを参照してください:fluentd デプロイメント

ステップ3

デプロイする前に、 を設定しfluent.conf、そこにいくつかのルールを記述する必要もあります。

私の場合は、次のようなログ行と一致するように設定されています。

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

tail プラグインの詳細については、以下を参照してください。しっぽ

    <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>

ここで重要な設定属性の 1 つは、read_from_head trueログ ファイルを上から読み取ることです。このシナリオでは、ポッド ログがローテーションされるため、最後の更新行だけでなく、完全なポッド ログを Fluentd が読み取る必要があります。短い cron ジョブの場合、ログ ファイルが表示されるだけで、tail はログ ファイルの最初の行を報告しません。

ステップ4

構成をいじって、何度も試してください。configMap で構成を更新した後は、デプロイメントを再起動することを忘れないでください。

捜索の痕跡からいくつか抜粋:

関連情報