🦢

今さらながらDocker + Fluentdを試す

2025/01/11に公開

前書き

業務で使用しているFluentdですが、自分が直接触る機会が無いので、今回いろいろ試してみました。
現在はアプリケーションの動作環境もDockerで構築することが多いと思うので、Dockerと組み合わせて使ってみます。

試してみること

  • Docker
  • Fluentd
    • Input
      • forward
        • 他のFluentdからのイベントを受けるためのプラグインです。Fluentdを使用する場合は1つのサーバーにログを集約することが多いと思うので、基本的に1環境に1つ以上は使用することになると思います。具体的には以下に挙げた出力を受けることが出来ます。
          • 他のFluentdノードからのOutput-forward
          • DockerのFluentdロギングドライバからの出力
          • fluent-catからの出力
      • exec
        • 外部プログラムからのログを受けるためのプラグインです。外部プログラムは Unixコマンド / 外部の実行可能なプログラム(RubyやJavaなどの、コマンドラインから実行可能なもの)を含みます。
    • Output
      • copy
        • 複数の出力を指定するのに使用するプラグインです。この複数の出力とは、FluentdのOutputプラグインのことです。そのため、後述するプラグインを組み合わせて、複数の方法でイベントを利用することができます。
      • forward
        • 他のFluentdノードへイベントを送出するためのプラグインです。Inputのforwardの逆バージョンと考えるとシンプルです。
      • file
        • Inputで受けた内容をファイルに書き出すためのプラグインです。ファイルはfluentdユーザーで書かれるので、パーミッションに注意する必要があります。

試してみる

コードはこちら

コンテナを立ち上げると、ログ集約コンテナ (log-aggregator) の/var/log/fluentd/executor/var/log/fluentd/httpdにログが出力されます。
以下のディレクトリには、

  • httpd: localhost にブラウザでアクセスするとログが出力される
  • executor: 1秒ごとに実行するcommandの結果が出力される

上記の動作が出力されます。

Fluentd ロギングドライバ

docker-compose.yml
  web:
    image: httpd
    container_name: httpd
    ports:
      - "80:80"
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: httpd.access
        fluentd-async: "true"

docker-compose.ymlでloggingを指定し、Fluentdロギングドライバを利用するための記述をします。ドキュメントを見ると色々設定できますが、とりあえず試すのであればこれだけで十分です。
必要なポイントを以下に挙げます。

  • fluentd-async: コンテナ起動時に、fluentdの接続先へのコネクションの確立に失敗すると、コンテナが立ち上がりません。本項目をtrueにすることで再接続を試行するようになるので、コンテナの起動順に関係なく立ち上げることが出来るようになります。
  • tag: 受信側のmatchで指定するタグと、ここで一致するtagが一致しないと、受信側で受けることができません。 (WARNINGでno patterns matched tag=...というログが受信側で出力されます)

input_exec to output_forward

<source>
  @type exec
  format json
  tag executor.log
  command echo '{ "key" : "value" }'
  run_interval 1s
</source>

<match executor.**>
  @type forward
  flush_interval 1s
  <server>
    host log-aggregator
    port 24224
  </server>
</match>

<source>ディレクティブでは、commandに指定したコマンドを実行します。この時、外部プログラムも実行可能ですが、とりあえず動かせればよいので、Unixコマンドのechoにしています。ここでも、受信側で受けられるようにtagを指定します。

<match>ディレクティブでは、<source>ディレクティブの結果をどうするかを指定します。
ログ収集コンテナに送信したいので、ログ収集コンテナ向けに@type forwardを指定します。
このとき、flush_intervalに注意が必要なポイントがあります。

flush_interval: outputの@type forwardでは、flush_intervalに指定した時間分だけ送信を遅延させます。デフォルトは60秒です。そのため、何も指定しないと、fluentdが送信するのが、コンテナが起動してから約60秒後になります。これを知らないと「何も書かれないな…」と困惑することになるので注意です。

input_forward to output_file with copy

<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

<match httpd.**>
  @type copy
  <store>
    @type file
    path /var/log/fluentd/log/httpd
  </store>
</match>

<match executor.**>
  @type copy
  <store>
    @type file
    path /var/log/fluentd/log/executor
  </store>
</match>

<source>ディレクティブで、@type forwardを指定することで、他のfluentdがforwardしたもの・Fluentdロギングドライバで出力したものを受けることが出来ます。

<match>ディレクティブで@type copyを指定することで、<store>ディレクティブを指定した分の送信先を指定できます。複数の方法で書き出したい時に利用するとよいです。
ここでは@type fileを指定することでファイルに書き出すのみにしています。
fluentdがファイル出力する際には、fluentdのプロセスがファイルを書き出せるように、fluentdユーザーのディレクトリをあらかじめ作成しています。
(pathで指定したディレクトリにfluentdユーザーが書き込めるパーミッションが無いと、コンテナが立ち上がりません)

Discussion