📘

FluentdをDockerで試してみる

2021/07/02に公開

Fluentdって何?

オープンソースのデータコレクター(収集)です。

日本人が元を作成していて、日本語の資料も多いです。
とりあえず、Dockerで試してみる。(ダラダラと試していくのでご了承ください。)

ダラダラと試してみる。

Fluentdサーバの公式のイメージ

公式から探すと下記が公式イメージらしい
https://hub.docker.com/r/fluent/fluentd/

とりあえず起動するだけなら下記でOK
利用するポート:-p 24224:24224 -p 24224:24224/udp
利用するディレクトリ:-v /data:/fluentd/log

(この時点の推測だと、このフォルダにログ情報のJSONが吐き出されると思う…)

docker run -d -p 24224:24224 -p 24224:24224/udp -v /data:/fluentd/log fluent/fluentd:v1.3-debian-1

コマンドで起動してみる
/dataを作成するのをお忘れなく…

問題なく動いていることを確認

$ docker ps
CONTAINER ID   IMAGE                          COMMAND                  CREATED       STATUS       PORTS                                                          NAMES
5593ee22994f   fluent/fluentd:v1.3-debian-1   "tini -- /bin/entryp…"   2 hours ago   Up 2 hours   5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp   peaceful_wescoff

Fluentdのクライアント?

td-agentという名前があったのでそちらがクライアント側(ログを転送する機能があるもの)だと思ったのですが、そもそもtd-agentFluentdは同じものらしい。
標準でFluentdはローカルのログを転送する機能を持っていて、それをFluentd間で転送して集約するような仕組みになっているような気がする。

ということはconfigがかなり重要で、そこでカスタマイズができるはずと思い公式のドキュメントを確認してみる。
https://docs.fluentd.org/configuration/config-file

ここでsourceにファイルを選択する方法があると思ったが無いっぽい。
説明も少ないし…

NginxのログをFluentdで利用する場合の方法を探してみる。
https://docs.fluentd.org/parser/nginx

parserというpluginが存在しているっぽい。
これが各ソリューションで用意されている場合はこれを使えばOKという感じ?

設定方法はこちらにありました。
https://docs.fluentd.org/parser

まず、ネットワーク的に接続する必要があるので、下記でネットワークを作成します。

docker network create net2
docker network connect net2 peaceful_wescoff

ログを出力するDocker Image(nginx)

ログを出力するやつとして、nginxのコンテナを作成します。
一旦ログの場所を確認するために、コンテナ作成。

docker run --rm -itd -p 80:80 nginx 

動いているっぽい
対象にアタッチしてみる。

docker ps 
CONTAINER ID   IMAGE                          COMMAND                  CREATED          STATUS          PORTS                                                          NAMES
89dd4a5ceac0   nginx                          "/docker-entrypoint.…"   52 seconds ago   Up 50 seconds   0.0.0.0:80->80/tcp                                             focused_franklin
5593ee22994f   fluent/fluentd:v1.3-debian-1   "tini -- /bin/entryp…"   10 hours ago     Up 10 hours     5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp   peaceful_wescof
docker exec -it peaceful_wescoff bash
>ls /var/log/
alternatives.log  apt  btmp  dpkg.log  faillog	lastlog  wtmp

うーん…
nginxはログを標準でDockerのフォワグランド的な所に出力しているっぽくて標準では出されていないっぽいですね。

このコンテナを削除して、新しくubuntu的なコンテナを起動して、そっちでnginxを起動させてみます。

from ubuntu
run apt update && apt install -y nginx
cmd nginx -g "daemon off;"
docker build -t mynginx .
docker run -itd --rm --name nginx -p80:80 mynginx 

無事に80番ポートで動いている様子。

docker exec -it nginx bash
root@0af38faf85d6:/# cd /var/log/nginx
root@0af38faf85d6:/var/log/nginx# ls
access.log  error.log

ログも/var/log/nginxaccess.logerror.logで出力されていることを確認しました。
一旦、このnginxを消して、/var/log/nginxをホスト側のフォルダ(/Users/hashito/fdata2)としてマウントさせます。

docker stop nginx
docker run -itd --rm --name nginx -v /Users/hashito/fdata2:/var/log/nginx -p80:80 mynginx 
cd ~/fdata2/
ls
access.log	error.log

マウントさせたfdata2内にファイルが生成されている事がわかります。
次は、fluentdfdata2をマウントさせて、且つもう一つのfluentd(サーバ)へ送るように設定します。

送り側の設定は下記?
https://docs.fluentd.org/output/forward

送り側のサーバは下記

 docker network inspect net2
[
    {
        "Name": "net2",
        "Id": "5267ef40e51bc6fe7e7b03161a2b02921566bfff6f9be6244c975f6d61b3b128",
        "Created": "2021-06-30T20:18:48.0879944Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5593ee22994f24d42a2529e6a5c76f43c0ea0b3a7a9c31d8d2a2650695a6e937": {
                "Name": "peaceful_wescoff",
                "EndpointID": "4df958118451083c8939887743a6808407e56527d43047ab9fc9ee5330846b88",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
td-agent.conf
<source>
  @type tail
  path /in/access.log     
  <parse>
    @type nginx
    keep_time_key true
  </parse>
</source>

<match *>
  @type forward
  send_timeout 60s
  recover_wait 10s
  hard_timeout 60s

  <server>
    name myserver1
    host 172.19.0.2 
    port 24224
    weight 60
  </server>
  <secondary>
    @type file
    path /var/log/fluent/forward-failed
  </secondary>
</match>
docker run -d -v /Users/hashito/fdata2:/in -v /Users/hashito/wk:/fluentd/etc  --network net2 fluent/fluentd:v1.3-debian-1 fluentd -c /fluentd/etc/td-agent.conf 

動かしては見たが…

その結果、下記のようなエラーが発生する…
設定内容が良くないっぽいです。特に入力側

2021-07-02 00:04:22 +0000 [info]: parsing config file is succeeded path="/fluentd/etc/td-agent.conf"
2021-07-02 00:04:22 +0000 [warn]: secondary type should be same with primary one primary="Fluent::Plugin::ForwardOutput" secondary="Fluent::Plugin::FileOutput"
2021-07-02 00:04:22 +0000 [info]: adding forwarding server 'myserver1' host="172.19.0.2" port=24224 weight=60 plugin_id="object:3fd89dda9110"
2021-07-02 00:04:22 +0000 [error]: config error in:
<source>
  @type tail
  path "/in/access.log"
  <parse>
    @type nginx
    keep_time_key true
  </parse>
</source>

2021-07-02 00:04:22 +0000 [error]: config error file="/fluentd/etc/td-agent.conf" error_class=Fluent::ConfigError error="'tag' parameter is required"

なんかtagがないですと言っている。
そこで、初心に戻り記事を探索した所、参考になりそうなものを見つける。

<fluentdのnginxアクセスログ取得をdockerで試す>
https://medium.com/nyle-engineering-blog/fluentdのnginxアクセスログ取得をdockerで試す-bf600b1f3389

このあたりの設定を参考に設定を書き換えてみる。
https://github.com/sankaku/docker-fluentd-examples/blob/master/nginx2file/fluentd/my_fluentd.conf

<source>
  @type tail
  path /in/access.log
  tag nginx.access
  <parse>
    @type nginx
    keep_time_key true
  </parse>
</source>
 docker ps
CONTAINER ID   IMAGE                          COMMAND                  CREATED          STATUS          PORTS                                                          NAMES
683168ad64d4   fluent/fluentd:v1.3-debian-1   "tini -- /bin/entryp…"   48 seconds ago   Up 44 seconds   5140/tcp, 24224/tcp                                            vigorous_jemison
1ba7a53294e4   mynginx                        "/bin/sh -c 'nginx -…"   34 hours ago     Up 34 hours     0.0.0.0:80->80/tcp                                             nginx
5593ee22994f   fluent/fluentd:v1.3-debian-1   "tini -- /bin/entryp…"   2 days ago       Up 2 days       5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp   peaceful_wescoff

次は問題なく動いてはいるが、データが上手く送信できてない様子。
(アクセスしても、受け側にデータが確認できない)

2021-07-02 14:10:01 +0000 [warn]: #0 no patterns matched tag="nginx.access"
2021-07-02 14:10:01 +0000 [warn]: #0 no patterns matched tag="nginx.access"

こんな感じのワーニングを見つける。
tag名がパーターンに一致しませんでした。
という意味だと思うので、matchも少し変更

<source>
  @type tail
  path /in/access.log
  tag nginx.access
  <parse>
    @type nginx
    keep_time_key true
  </parse>
</source>

<match nginx.access>
  @type forward
  send_timeout 60s
  recover_wait 10s
  hard_timeout 60s

  <server>
    name myserver1
    host 172.19.0.2
    port 24224
    weight 60
  </server>
  <secondary>
    @type file
    path /var/log/fluent/forward-failed
  </secondary>
</match>

match nginx.accessとして、マッチさせるようにしてみる。

動いた!

nginxにブラウザでアクセスして暫く待つと、受け側のファイルに出力が確認できました。

MacBook-Pro:fdata hashito$ ls -al
total 16
drwxr-xr-x   5 hashito  staff   160  7  2 23:15 .
drwxr-xr-x+ 65 hashito  staff  2080  7  1 12:35 ..
-rw-r--r--@  1 hashito  staff  2312  7  2 23:15 data.b5c62498149d47710b881a6fd26c9854d.log
-rw-r--r--   1 hashito  staff    68  7  2 23:15 data.b5c62498149d47710b881a6fd26c9854d.log.meta
lrwxr-xr-x   1 hashito  staff    55  7  2 23:15 data.log -> /fluentd/log/data.b5c62498149d47710b881a6fd26c9854d.log
MacBook-Pro:fdata hashito$ 
MacBook-Pro:fdata hashito$ cat data.b5c62498149d47710b881a6fd26c9854d.log
2021-07-02T14:14:50+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:14:50 +0000","method":"GET","path":"/","code":"200","size":"396","referer":"-","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
2021-07-02T14:14:50+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:14:50 +0000","method":"GET","path":"/favicon.ico","code":"404","size":"197","referer":"http://localhost/","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
2021-07-02T14:15:22+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:15:22 +0000","method":"GET","path":"/","code":"304","size":"0","referer":"-","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
2021-07-02T14:15:24+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:15:24 +0000","method":"GET","path":"/","code":"200","size":"396","referer":"-","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
2021-07-02T14:15:24+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:15:24 +0000","method":"GET","path":"/favicon.ico","code":"404","size":"197","referer":"http://localhost/","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
2021-07-02T14:15:36+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:15:36 +0000","method":"GET","path":"/","code":"200","size":"396","referer":"-","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
2021-07-02T14:15:36+00:00	nginx.access	{"remote":"172.17.0.1","host":"-","user":"-","time":"02/Jul/2021:14:15:36 +0000","method":"GET","path":"/favicon.ico","code":"404","size":"197","referer":"http://localhost/","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}

検証した結論

色々と使えそう。

  • Fluentdはログを収集するものではなく受け流す役割を持っているイメージ
  • FluentdはClientやAgentの役割のものは無く、Fluentd→Fluentdはもちろん、「ファイル」「DB」「HTTP要求」などへ流す事ができる
  • 全て設定ファイルに依存して行われ「source」と「match」が一番重要っぽい
  • tag中間処理など便利なものが色々とありそう
  • ってか内部的なAPIとかこれで済む場合も多いのでは?

Discussion