これは、なにをしたくて書いたもの?
以前、FluentdをDockerのlogging driverとして使ってみたことがありました。
Docker環境で、コンテナのログをFluentdに出力する(Docker logging driverとして使う) - CLOVER🍀
今回は、Fluent BitをDockerのlogging driverとして使ってみたいと思います。
Fluentd logging driver
Dockerでは、Fluentdをlogging driverとして使うように設定できます。
Fluentd logging driver | Docker Documentation
ここでログの送信先をFluentdではなく、Fluent Bitに変更してみるのが今回やってみることです。
Fluent Bitの記事にも、Dockerコンテナから受け取ったログを、Elasticsearchに送信するサンプルが書かれたりしています。
Fluent Bit - Docker Logging & Elasticsearch
それでは、ちょっと試してみましょう。
環境
今回の環境は、こちら。
$ uname -srvmpio Linux 4.15.0-99-generic #100-Ubuntu SMP Wed Apr 22 20:32:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic $ docker -v Docker version 19.03.8, build afacb8b7f0 $ /opt/td-agent-bit/bin/td-agent-bit --version Fluent Bit v1.4.4
Ubuntu Linux 18.04、Fluent Bitは1.4.4を使用します。
お題
今回のお題は、nginxのDockerコンテナに対してFluentd logging driverを設定し、Fluent Bitに送信してみたいと思います。
Fluent BitとDockerは同じホスト(192.168.33.10)で動作させますが、Fluent Bitはネットワーク越しにログを受け取るように
設定します。
Fluent Bitを設定する
では、最初にFluent Bitの設定を行います。
結果は、こんな感じに。
$ grep -v '^ *#' /etc/td-agent-bit/td-agent-bit.conf [SERVICE] Flush 5 Daemon Off Log_Level info Parsers_File parsers.conf Plugins_File plugins.conf HTTP_Server Off HTTP_Listen 0.0.0.0 HTTP_Port 2020 [INPUT] Name forward Host 0.0.0.0 Port 24224 [OUTPUT] Name stdout Match * Format json_lines
ポイントは、INPUTをfowardにしていることですね。
[INPUT] Name forward Host 0.0.0.0 Port 24224
Forward - Fluent Bit: Official Manual
バインドするアドレスは、「0.0.0.0」で設定。
こちらで、Dockerコンテナのログを受け取ります。
結果は、標準出力で確認することにしました。
[OUTPUT] Name stdout Match * Format json_lines
journalctlで、Fluent Bitのログを確認しておきます。
$ sudo journalctl -u td-agent-bit.service -f
Dockerコンテナを起動する
続いて、Fluent Bitにログを送信するDockerコンテナを起動します。
こんな感じで起動。
$ docker container run \ -d -p 80:80 --name nginx \ --log-driver=fluentd \ --log-opt fluentd-address=tcp://192.168.33.10:24224 \ --log-opt tag=docker.{{.ImageName}}.{{.Name}}.{{.ID}} \ nginx:1.17.10
「--log-driver」を「fluentd」とすることで、Fluentd logging driverを利用することができます。
指定しているオプションは、このあたりを参照。
Fluentd logging driver / Options
今回は、Fluent Bitへの送信先を「fluentd-address」で、Fluent Bitで利用するタグを「tag」で指定しました。
タグはこちらのフォーマットで指定しているのですが、今回はFluent Bit側のMatchでタグを見ていないので、あんまり関係が
なかったり…。
Customize log driver output | Docker Documentation
確認する
それでは、確認してみます。
nginxコンテナにアクセス。
$ curl localhost
少し待っていると、Fluent Bit側のログ(というか標準出力)に、こんな感じで出力されれば成功です。
May 17 10:55:25 ubuntu1804.localdomain td-agent-bit[3848]: {"date":1589712924,"container_name":"/nginx","source":"stdout","log":"172.17.0.1 - - [17/May/2020:10:55:24 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"curl/7.58.0\" \"-\"","container_id":"fa127da978b1895c40d20d851502d42d1bacee5053e9075e4bf6eeca02023379"}
コンテナ名や、コンテナのIDなども要素として含まれます。
ちなみに、この状態だと「docker container logs」コマンドでは、コンテナのログは見れなくなることに注意してください。
$ docker container logs nginx Error response from daemon: configured logging driver does not support reading
ログをパースしてみる
これだけで終わっても少し物足りない気もするので、ここからさらに、Parserを使ってnginxのログをパースしてみましょう。
Fluent Bitのparsers.confに、nginx向けのParserが定義してあるので、こちらを使います。
/etc/td-agent-bit/parsers.conf
[PARSER] Name nginx Format regex Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)") Time_Key time Time_Format %d/%b/%Y:%H:%M:%S %z
Fluent Bitの設定は、このように変更。
[INPUT] Name forward Host 0.0.0.0 Port 24224 Tag docker.driver.log [FILTER] Name parser Match * Key_Name log Parser nginx Preserve_Key Off Reserve_Data On Tag docker.nginx.log [OUTPUT] Name stdout Match * Format json_lines
先ほどの結果として、nginxのログそのものは「log」というキーで出力されているので
May 17 10:55:25 ubuntu1804.localdomain td-agent-bit[3848]: {"date":1589712924,"container_name":"/nginx","source":"stdout","log":"172.17.0.1 - - [17/May/2020:10:55:24 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"curl/7.58.0\" \"-\"","container_id":"fa127da978b1895c40d20d851502d42d1bacee5053e9075e4bf6eeca02023379"}
Parserの適用先の「Key_Name」を「log」に指定します。Parserで指定するのは、パーサーの名前ですね(今回はnginx)。
[FILTER] Name parser Match * Key_Name log Parser nginx Preserve_Key Off Reserve_Data On Tag docker.nginx.log
ここまで設定したらFluent Bitを再起動して、nginxに再度アクセスしてみます。
ログが以下のような感じに分解されて、Fluent Bit側で出力されます。
May 17 12:34:57 ubuntu1804.localdomain td-agent-bit[5033]: {"date":1589718895,"remote":"172.17.0.1","host":"-","user":"-","method":"GET","path":"/","code":"200","size":"612","referer":"-","agent":"curl/7.58.0","source":"stdout","container_id":"7ea3b9cc2b7ac65d2729e722bacbc2b8efc150ec51ccc37405ebf4f313156a42","container_name":"/nginx"}
デフォルトではTime_KeepがOffなのでアクセス時刻はdateフィールドに変換された後に削除されていますが、今回は
これでも良しとしましょう。
また、Parserを使った時に「Reserve_Data」をOnにしておかないと、パースした結果以外のキーは削除されてしまうので注意しましょう。
パース対象となったキー「log」は、今回は残らなくてもいいので「Preserve_Key」をOffにしています(これはデフォルトの挙動)。