Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

6.7. Fluentd の設定

OpenShift Container Platform は Fluentd を使用して、OpenShift Container Platform が Kubernetes Pod および Namespace メタデータで拡充したクラスターから操作およびアプリケーションログを収集します。

ログローテーション、ログの位置を設定し、外部のログアグリゲーターを使用し、他の設定を行うことができます。

注記

特に指示がない場合は、これらの設定を実行する前にクラスターロギングを管理外の状態に設定する必要があります。詳細は、「クラスターロギングの管理状態の変更」を参照してください。

6.7.1. Fluentd Pod の表示

oc get pods -o wide コマンドを使用して、Fluentd Pod がデプロイされるノードを表示できます。

手順

openshift-logging プロジェクトで以下のコマンドを実行します。

$ oc get pods -o wide | grep fluentd

NAME                         READY     STATUS    RESTARTS   AGE     IP            NODE                           NOMINATED NODE
fluentd-5mr28                1/1       Running   0          4m56s   10.129.2.12   ip-10-0-164-233.ec2.internal   <none>
fluentd-cnc4c                1/1       Running   0          4m56s   10.128.2.13   ip-10-0-155-142.ec2.internal   <none>
fluentd-nlp8z                1/1       Running   0          4m56s   10.131.0.13   ip-10-0-138-77.ec2.internal    <none>
fluentd-rknlk                1/1       Running   0          4m56s   10.128.0.33   ip-10-0-128-130.ec2.internal   <none>
fluentd-rsm49                1/1       Running   0          4m56s   10.129.0.37   ip-10-0-163-191.ec2.internal   <none>
fluentd-wjt8s                1/1       Running   0          4m56s   10.130.0.42   ip-10-0-156-251.ec2.internal   <none>

6.7.2. Fluentd ログの表示

ログの表示方法は、LOGGING_FILE_PATH の設定によって異なります。

  • LOGGING_FILE_PATH がファイルを参照する場合、デフォルトで、logs ユーティリティーを Pod が置かれているプロジェクトから使用し、Fluentd ログファイルの内容を出力します。

    $ oc exec <any-fluentd-pod> -- logs 1
    1
    Fluentd Pod の名前を指定します。logs の前にスペースがあることに注意してください。

    例:

    $ oc exec fluentd-ht42r -n openshift-logging -- logs

    現在の設定を表示するには、以下を実行します。

    oc -n openshift-logging set env daemonset/fluentd --list | grep LOGGING_FILE_PATH
  • LOGGING_FILE_PATH=console を使用している場合、Fluentd はログを stdout/stderr に書き込みます。oc logs [-f] <pod_name> コマンド (-f はオプション) を使用して、Pod が置かれているプロジェクトからログを取得できます。

    $ oc logs -f <any-fluentd-pod> 1
    1
    Fluentd Pod の名前を指定します。-f オプションを使用してログに書き込まれている内容をフォローします。

    以下は例になります。

    $ oc logs -f fluentd-ht42r -n openshift-logging

    ログファイルの内容は最も古いログから順番に出力されます。

6.7.3. Fluentd CPU およびメモリー制限の設定

それぞれのコンポーネント仕様は、CPU とメモリーの両方への調整を許可します。

手順

  1. openshift-logging プロジェクトでクラスターロギングのカスタムリソース (CR) を編集します。

    $ oc edit ClusterLogging instance
    $ oc edit ClusterLogging instance
    
    apiVersion: "logging.openshift.io/v1"
    kind: "ClusterLogging"
    metadata:
      name: "instance"
    
    ....
    
    spec:
      collection:
        logs:
          fluentd:
            resources:
              limits: 1
                cpu: 250m
                memory: 1Gi
              requests:
                cpu: 250m
                memory: 1Gi
    1
    必要に応じて CPU およびメモリー制限を指定します。表示される値はデフォルト値です。

6.7.4. Fluentd ログの場所の設定

Fluentd は、LOGGING_FILE_PATH 環境変数に応じて、指定されたファイルか、またはデフォルトの場所の /var/log/fluentd/fluentd.log にログを書き込みます。

前提条件

クラスターロギングを管理外の状態に設定する。

手順

Fluentd ログの出力の場所を設定するには、以下を実行します。

  1. fluentd daemonset で LOGGING_FILE_PATH パラメーターを編集します。特定のファイルまたは console を指定できます。

    spec:
      template:
        spec:
          containers:
              env:
                - name: LOGGING_FILE_PATH
                  value: console 1
    
    LOGGING_FILE_PATH= 2
    1
    ログの出力方法を指定します。
    • console を使用して Fluentd のデフォルトの場所を使用します。oc logs [-f] <pod_name> コマンドでログを取得します。
    • <path-to-log/fluentd.log> を使用してログ出力を指定されたファイルに送信します。`oc exec <pod_name> — logs コマンドでログを取得します。これはデフォルトの設定です。

      または、CLI を使用します。

      oc -n openshift-logging set env daemonset/fluentd LOGGING_FILE_PATH=console

6.7.5. Fluentd ログのスロットリング

とくに詳細なプロジェクトについては、管理者は処理される前の Fluentd によるログの読み取り速度を減速することができます。スロットリングによってログの読み取り速度が遅くなり、Kibana がレコードを表示するのにより長い時間がかかる可能性があります。

警告

スロットリングは設定されたプロジェクトのログ集計が遅れる一因になる可能性があります。Fluentd が追い付く前に Pod が削除された場合、ログエントリーが消失する可能性があります。

注記

Systemd ジャーナルをログソースとして使用している場合、スロットリングは機能しません。スロットリングの実装は、各プロジェクトの個々のログファイルの読み取りを調整できる機能によって決まります。ジャーナルからの読み取り時に、単一のログソースしか存在せず、ログファイルが存在しないと、ファイルベースのスロットリングは利用できません。Fluentd プロセスに読み込まれるログエントリーを制限する方法はありません。

前提条件

クラスターロギングを管理外の状態に設定する。

手順

  1. Fluentd を特定プロジェクトを制限するように設定するには、デプロイメント後に Fluentd ConfigMap でスロットル設定を編集します。

    $ oc edit configmap/fluentd

    throttle-config.yaml キーの形式は、プロジェクト名と、各ノードでのログの読み取りに必要な速度が含まれる YAML ファイルです。デフォルトはノードごとに一度に 1000 行です。例:

throttle-config.yaml: |
  - opensift-logging:
      read_lines_limit: 10
  - .operations:
      read_lines_limit: 100

6.7.6. Fluentd のバッファーチャンクの制限について

Fluentd ロガーが多数のログを処理できない場合、メモリーの使用量を減らし、データ損失を防ぐためにファイルバッファリングに切り換える必要があります。

Fluentd ファイルバッファリングは、記録を chunks に保管します。チャンクは buffers に保管されます。

Fluentd buffer_chunk_limit は、デフォルト値が 8m の環境変数 BUFFER_SIZE_LIMIT によって決定されます。出力ごとのファイルのバッファーサイズは、デフォルト値が 256Mi の環境変数 FILE_BUFFER_LIMIT によって決定されます。永続的なボリュームサイズは、FILE_BUFFER_LIMIT に出力を乗算した結果よりも大きくなければなりません。

Fluentd Pod では、永続ボリューム /var/lib/fluentd は PVC または hostmount などによって作成する必要があります。その領域はファイルバッファーに使用されます。

buffer_type および buffer_path は、以下のように Fluentd 設定ファイルで設定されます。

$ egrep "buffer_type|buffer_path" *.conf
output-es-config.conf:
  buffer_type file
  buffer_path `/var/lib/fluentd/buffer-output-es-config`
output-es-ops-config.conf:
  buffer_type file
  buffer_path `/var/lib/fluentd/buffer-output-es-ops-config`

Fluentd buffer_queue_limit は変数 BUFFER_QUEUE_LIMIT の値です。この値はデフォルトで 32 になります。

環境変数 BUFFER_QUEUE_LIMIT(FILE_BUFFER_LIMIT / (number_of_outputs * BUFFER_SIZE_LIMIT)) として計算されます。

BUFFER_QUEUE_LIMIT 変数にデフォルトの値のセットが含まれる場合、以下のようになります。

  • FILE_BUFFER_LIMIT = 256Mi
  • number_of_outputs = 1
  • BUFFER_SIZE_LIMIT = 8Mi

buffer_queue_limit の値は 32 になります。buffer_queue_limit を変更するには、FILE_BUFFER_LIMIT の値を変更する必要があります。

この数式では、number_of_outputs は、すべてのログが単一リソースに送信され、追加のリソースごとに 1 つずつ増分する場合に 1 になります。たとえば、number_of_outputs の値は以下のようになります。

  • 1: すべてのログが単一の Elasticsearch Pod に送信される場合
  • 2: アプリケーションログが Elasticsearch Pod に送信され、運用ログが別の Elasticsearch Pod に送信される場合
  • 4: アプリケーションログが Elasticsearch Pod に送信され、運用ログが別の Elasticsearch Pod に送信される場合で、それらがどちらも他の Fluentd インスタンスに転送される場合

6.7.7. Fluentd JSON 構文解析の設定

Fluentd を、メッセージが JSON 形式であるかどうかを判別するために各ログメッセージを検査し、そのメッセージを Elasticsearch に送信された JSON ペイロードドキュメントにマージできるよう設定します。この機能はデフォルトでは無効にされています。

この機能は、fluentd daemonset で MERGE_JSON_LOG 環境変数を編集することによって有効にしたり、無効にしたりできます。

重要

この機能を有効することには、以下を含むリスクが伴います。

  • Elasticsearch が整合性のないタイプのマッピングによりドキュメントを拒否することでログが失われる可能性があります。
  • 拒否されるメッセージの繰り返し処理によってバッファーストレージ不足が生じる可能性があります。
  • 同じ名前を持つフィールドのデータが上書きされます。

このトピックの機能は、経験のある Fluentd および Elasticsearch ユーザーによってのみ使用される必要があります。

前提条件

クラスターロギングを管理外の状態に設定する。

手順

以下のコマンドを使用してこの機能を有効にします。

oc set env ds/fluentd MERGE_JSON_LOG=true 1
1
これを false に設定してこの機能を無効にするか、または true に設定してこの機能を有効にします。

MERGE_JSON_LOG および CDM_UNDEFINED_TO_STRING の設定

MERGE_JSON_LOG および CDM_UNDEFINED_TO_STRING 環境変数を true に設定する場合、Elasticsearch 400 エラーを受信する可能性があります。このエラーは、`MERGE_JSON_LOG=true` の場合に Fluentd がフィールドに 文字列 以外のデータタイプを追加するために発生します。CDM_UNDEFINED_TO_STRING=true を設定する場合、Fluentd はそれらのフィールドに 文字列 の値を追加することを試行し、これにより Elasticsearch 400 エラーが生じます。このエラーはインデックスが翌日にロールオーバーされるとクリアされます。

Fluentd が次の日のログのインデックスをロールオーバーする場合、全く新しいインデックスが作成されます。フィールドの定義は更新され、400 エラーは発生しません。

スキーマ違反やデータ破損などの ハード (hard) エラーのあるレコードについては、再試行できません。Fluent はエラー処理のためにレコードを送信します。最後に表示される <label> のように Fluentd 設定に <label @ERROR> セクションを追加 する場合、それらのレコードを随時処理することができます。

例:

data:
  fluent.conf:

....

    <label @ERROR>
      <match **>
        @type file
        path /var/log/fluent/dlq
        time_slice_format %Y%m%d
        time_slice_wait 10m
        time_format %Y%m%dT%H%M%S%z
        compress gzip
      </match>
    </label>

このセクションではエラーレコードを Elasticsearch dead letter queue (DLQ) ファイル に書き込みます。ファイル出力についての詳細は fluentd のドキュメント を参照してください。

次に、レコードを手動でクリーンアップし、ファイルを Elasticsearch /_bulk index API で使用し、cURL を使用してそれらのレコードを追加できるようにファイルを編集することができます。Elasticsearch Bulk API についての詳細は Elasticsearch のドキュメント を参照してください。

6.7.8. ログコレクターによってログを正規化する方法の設定

クラスターロギングは、データベーススキーマなどの特定のデータモデルを使用して、ログレコードとそのメタデータをロギングストアに格納します。このデータについてはいくつかの制限があります。

  • 実際のログメッセージが含まれる "message" フィールドがなければなりません。
  • RFC 3339 形式のログレコードのタイムスタンプを含む "@timestamp" フィールドがなければなりません (ミリ秒以上の単位の使用が望ましい)。
  • errinfounknown などのログレベルが含まれる "level" フィールドがなければなりません。
注記

データモデルの詳細については、「Exported Fields」を参照してください。

これらの要件により、異なるサブシステムから収集されるログデータで競合や不整合が生じる場合があります。

たとえば、MERGE_JSON_LOG 機能 (MERGE_JSON_LOG=true) を使用する場合、アプリケーションの出力のログを JSON で記録し、ログコレクターが Elasticsearch 内でデータを自動的に解析し、インデックス化すると非常に便利です。ただし、これにより、以下のような問題が発生します。

  • フィールド名が空になることや、Elasticsearch で使用できない文字が含まれる可能性があります。
  • 同じ namespace の異なるアプリケーションが、同じフィールド名を異なる値データタイプで出力する可能性があります。
  • アプリケーションが過剰にフィールドを出力する可能性があります。
  • フィールドはクラスターロギングのビルトインフィールドと競合する可能性があります。

以下の表で、Fluentd ログコレクターの daemonset、Fluentd または Rsyslog を編集し、環境変数を設定することで、クラスターロギングが異種ソースからフィールドを処理する方法を設定できます。

  • 未定義のフィールド。異種システムのログデータに関する問題の 1 つとして、一部のフィールドが ViaQ データモデルで認識されない可能性があります。このようなフィールドは undefined と呼ばれます。ViaQ では、すべての最上位フィールドが定義され、記述される必要があります。

    パラメーターを使用して OpenShift Container Platform が、undefined という最上位フィールド以下のすべての未定義のフィールドを移動し、既知の ViaQ の最上位フィールドとの競合を避けます。未定義フィールドを最上位フィールドに追加し、他のフィールドを undefined コンテナーに移動できます。

    また、未定義のフィールドで特殊文字を置き換えることができ、未定義フィールドを JSON 文字列表現に変換することもできます。JSON 文字列に変換しても値の構造を維持されるため、値を後で取得してマップまたは配列に戻すことができます。

    • 番号やブール値などの簡単なスカラー値は、引用符で囲まれた文字列に変更されます。たとえば、10"10" に、 3.1415"3.1415"` に、 false"false" になります。
    • map/dict の値と配列の値は JSON 文字列表現に変換されます: "mapfield":{"key":"value"}"mapfield":"{\"key\":\"value\"}"に、"arrayfield":[1,2,"three"]"arrayfield":"[1,2,\"three\"]" に変換されます。
  • 定義されたフィールド。ログの最上位に表示する定義されたフィールドを設定することもできます。

    CDM_DEFAULT_KEEP_FIELDS パラメーターで定義されるデフォルトの最上位のフィールドは次のとおりです: CEE, time@timestampaushapeci_jobcollectddockerfedora-cifileforemangeoiphostnameipaddr4ipaddr6kuberneteslevelmessagenamespace_namenamespace_uuidoffsetopenstackovirtpidpipeline_metadatarsyslogservicesystemdtagstestcasetlogviaq_msg_id

    ${CDM_DEFAULT_KEEP_FIELDS} または ${CDM_EXTRA_KEEP_FIELDS} に含まれないフィールドはすべて、CDM_USE_UNDEFINEDtrue の場合、${CDM_UNDEFINED_NAME} に移動されます。

    注記

    CDM_DEFAULT_KEEP_FIELDS パラメーターは、上級ユーザーのみが使用するか、Red Hat サポートによって使用することが指示された場合に使用されることが想定されます。

  • 空のフィールド。異種ログから保持する空のフィールドを決定することができます。

表6.3 ログの正規化に使用する環境パラメーター

パラメーター定義

CDM_EXTRA_KEEP_FIELDS

CDM_DEFAULT_KEEP_FIELDS に加えて、ログの最上位に保持する定義されたフィールドの追加セットを指定します。デフォルトは "" です。

CDM_EXTRA_KEEP_FIELDS="broker"

CDM_KEEP_EMPTY_FIELDS

CSV 形式で空のままでも保持するフィールドを指定します。空の定義されたフィールドで指定されないものはドロップされます。デフォルトは 「message」で、空のメッセージを維持します。

CDM_KEEP_EMPTY_FIELDS="message"

CDM_USE_UNDEFINED

未定義のフィールドを undefined の最上位フィールドに移動するには、true に設定します。デフォルトは false です。true の場合、CDM_DEFAULT_KEEP_FIELDS および CDM_EXTRA_KEEP_FIELDS の値は undefined に移動されません。

CDM_USE_UNDEFINED=true

CDM_UNDEFINED_NAME

CDM_USE_UNDEFINEDを使用する場合は、未定義の最上位フィールドの名前を指定します。デフォルトは `undefined` です。CDM_USE_UNDEFINEDtrue の場合にのみ有効にされます。

CDM_UNDEFINED_NAME="undef"

CDM_UNDEFINED_MAX_NUM_FIELDS

未定義フィールドの数がこの数を超える場合、未定義のフィールドはすべて JSON 文字列表現に変換され、CDM_UNDEFINED_NAME フィールドに保存されます。レコードに未定義フィールド値を超える数が含まれる場合、これらのフィールドでの処理はこれ以上実行されません。代わりに、フィールドは最上位の CDM_UNDEFINED_NAME フィールドに保存された単一文字列の JSON 値に変換されます。デフォルトの -1 を維持することで、未定義フィールドの無制限の値が許可されますが、これは推奨されません。

注記

このパラメーターは CDM_USE_UNDEFINED が false の場合でも有効です。

CDM_UNDEFINED_MAX_NUM_FIELDS=4

CDM_UNDEFINED_TO_STRING

未定義フィールドをすべて JSON 文字列表現に変換するには、true に設定します。デフォルトは false です。

CDM_UNDEFINED_TO_STRING=true

CDM_UNDEFINED_DOT_REPLACE_CHAR

未定義フィールドでドット文字 '.' の代わりに使用する文字を指定します。MERGE_JSON_LOGtrue である必要があります。デフォルトは UNUSED です。MERGE_JSON_LOG パラメーターを true に設定した場合は、以下の注を参照してください。

CDM_UNDEFINED_DOT_REPLACE_CHAR="_"

注記

ログコレクター daemonset の MERGE_JSON_LOG パラメーターおよび CDM_UNDEFINED_TO_STRING 環境変数を true に設定した場合、Elasticsearch 400 エラーを受信する可能性があります。このエラーは、`MERGE_JSON_LOG=true` の場合に、ログコレクターがフィールドに文字列以外のデータタイプを追加するために発生します。CDM_UNDEFINED_TO_STRING=trueを設定する場合、ログコレクターはそれらのフィールドへの文字列の値の追加を試行し、これにより Elasticsearch 400 エラーが生じます。ログコレクターが翌日のログにインデックスをロールオーバーすると、エラーはクリアされます。

ログコレクターがインデックスをロールオーバーする場合、完全に新規のインデックスが作成されます。フィールドの定義は更新され、400 エラーは発生しません。

手順

CDM_* パラメーターを使用して、未定義および空のフィールドの処理を設定します。

  1. 必要に応じてフィールドの処理方法を設定します。

    1. CDM_EXTRA_KEEP_FIELDS を使用して移動するフィールドを指定します。
    2. CSV 形式で CDM_KEEP_EMPTY_FIELDS パラメーターで保持する空のフィールドをすべて指定します。
  2. 必要に応じて未定義フィールドの処理方法を設定します。

    1. CDM_USE_UNDEFINEDtrue に設定し、未定義のフィールドを最上位の undefined フィールドに移動します。
    2. CDM_UNDEFINED_NAME パラメーターを使用して、未定義フィールドの名前を指定します。
    3. CDM_UNDEFINED_MAX_NUM_FIELDS をデフォルトの -1 以外の値に設定し、単一レコードにおける未定義フィールド数の上限を設定します。
  3. CDM_UNDEFINED_DOT_REPLACE_CHAR を指定して、未定義フィールド名のすべてのドット (.) 文字を別の文字に変更します。たとえば、CDM_UNDEFINED_DOT_REPLACE_CHAR=@@@ の場合で、foo.bar.baz という名前のフィールドがある場合、そのフィールドは foo@@@bar@@@baz に変換されます。
  4. UNDEFINED_TO_STRINGtrue に設定し、未定義フィールドを JSON 文字列表現に変換します。
注記

CDM_UNDEFINED_TO_STRING または CDM_UNDEFINED_MAX_NUM_FIELDS パラメーターを設定する場合、CDM_UNDEFINED_NAME を使用して未定義フィールドの名前を変更します。CDM_UNDEFINED_TO_STRING または CDM_UNDEFINED_MAX_NUM_FIELDS が未定義フィールドの値タイプを変更する可能性があるため、このフィールドは必要になります。CDM_UNDEFINED_TO_STRING または CDM_UNDEFINED_MAX_NUM_FIELDS が true に設定されていて、ログにさらに多くの未定義フィールドがある場合、値タイプは stringになります。値タイプが変更される場合、Elasticsearch はレコードの受け入れを停止します (JSON から JSON 文字列への変更など)。

たとえば、CDM_UNDEFINED_TO_STRINGfalse であるか、または CDM_UNDEFINED_MAX_NUM_FIELDS がデフォルトの-1 の場合、未定義フィールドの値タイプは json になります。CDM_UNDEFINED_MAX_NUM_FIELDS をデフォルト以外の値に変更し、ログにさらに多くの未定義フィールドがある場合、値タイプは string (json string) になります。値タイプが変更された場合、Elasticsearch はレコードの受け入れを停止します。

6.7.9. 環境変数の使用による Fluentd の設定

環境変数を使用して Fluentd 設定を変更することができます。

前提条件

クラスターロギングを管理外の状態に設定する。

手順

必要に応じて Fluentd 環境変数のいずれかを設定します。

oc set env ds/fluentd <env-var>=<value>

例:

oc set env ds/fluentd LOGGING_FILE_AGE=30