今さらながらDocker + Fluentdを試す
前書き
業務で使用しているFluentdですが、自分が直接触る機会が無いので、今回いろいろ試してみました。
現在はアプリケーションの動作環境もDockerで構築することが多いと思うので、Dockerと組み合わせて使ってみます。
試してみること
- Docker
-
Fluentd ロギングドライバ
- DockerのログをFluentd向けに送信するためのロギングドライバ
-
Fluentd ロギングドライバ
- Fluentd
- Input
-
forward
- 他のFluentdからのイベントを受けるためのプラグインです。Fluentdを使用する場合は1つのサーバーにログを集約することが多いと思うので、基本的に1環境に1つ以上は使用することになると思います。具体的には以下に挙げた出力を受けることが出来ます。
- 他のFluentdノードからのOutput-forward
- DockerのFluentdロギングドライバからの出力
- fluent-catからの出力
- 他のFluentdからのイベントを受けるためのプラグインです。Fluentdを使用する場合は1つのサーバーにログを集約することが多いと思うので、基本的に1環境に1つ以上は使用することになると思います。具体的には以下に挙げた出力を受けることが出来ます。
-
exec
- 外部プログラムからのログを受けるためのプラグインです。外部プログラムは Unixコマンド / 外部の実行可能なプログラム(RubyやJavaなどの、コマンドラインから実行可能なもの)を含みます。
-
forward
- Output
- Input
試してみる
コンテナを立ち上げると、ログ集約コンテナ (log-aggregator) の/var/log/fluentd/executorと/var/log/fluentd/httpdにログが出力されます。
以下のディレクトリには、
- httpd: localhost にブラウザでアクセスするとログが出力される
- executor: 1秒ごとに実行するcommandの結果が出力される
上記の動作が出力されます。
Fluentd ロギングドライバ
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