この記事は MicroAd Advent Calendar 2022 の7日目の記事です。
概要
Fluentdでログデータの収集をDocker環境で試す手順について書きます。
想定読者
- Dockerに環境があり、Dockerの基本操作が分かる
- Fluentdについて初心者
Fluentdとは
Fluentdは、ログデータの収集、集約、変換などを担うOSSです。
例えば、NginxやApacheなどのWebサーバのアクセスログをFluentdを使ってMySQLやElasticSearchに転送することができます。
ちなみに)td-agent との違い
Fluentdの説明にはよく 「td-agent」 が出てきますが、これはFluentdの安定版にした配布用パッケージで、Treasure Data社が提供しているものです。
以下のような違いがあります。
- FluentdはRuby gemsかソースコードで配布、td-agentはRPMやDEBで配布されている
- Fluentdは設定は素のままでinitスクリプトもないが、td-agentはいくつかは推奨設定がされておりinitスクリプトもある
そのため、実際は運用しやすさからtd-agentを使うことが多いかと思いますが、本体の挙動自体は同じなため多くの部分ではFluentd=td-agentに読み替えが可能です。
詳細は、公式FAQに記載がありますのでそちらをご確認ください。
What are the differences between td-agent and Fluentd?
さらに余談ですが、最近は 「calyptia-fluentd」 というパッケージも用意されています。
こちらは、Calyptia社がメンテナンスしており同梱されているRubyのバージョンが3系で新しく、高速化、最適化の恩恵を受けられるようです。
Dockerで動かしてみる
準備
以下のようにファイルを準備します。
❯ tree
.
├── config
│ └── fluent.conf
└── docker-compose.yml
1 directory, 2 files
version: '3'
services:
nginx:
image: nginx:latest
ports:
- 80:80
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: "docker.{{.Name}}"
depends_on:
- fluentd
fluentd:
image: fluent/fluentd:v1.15.3-1.0
volumes:
- ./config:/fluentd/etc
ports:
- 24224:24224
- 24224:24224/udp
<source>
@type forward
</source>
<match docker.**>
@type stdout
</match>
動作
以下でコンテナを起動させ、ログを見れる状態にしておきます。
docker compose up -d
docker compose logs -f
この状態で、ブラウザか別ターミナルでcurl
コマンドを用いてlocalhost
にアクセスします。
すると、以下のようにログが出力されるかと思います。
01-nginx-1 | 172.18.0.1 - - [07/Dec/2022:02:08:26 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.74.0" "-"
01-fluentd-1 | 2022-12-07 02:08:26.000000000 +0000 docker.01-nginx-1: {"source":"stdout","log":"172.18.0.1 - - [07/Dec/2022:02:08:26 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"curl/7.74.0\" \"-\"","container_id":"e50625bf3a1cfeae0bea0fbf3c724761eb16a37838ef297f854115e004664196","container_name":"/01-nginx-1"}
Nginxにアクセスした際のアクセスログがfluentdのDockerコンテナに転送されているのが確認できればOKです。
解説: ログを収集される側(Nginx)
Nginxの部分の説明は省略し、以下のロギングドライバについて説明します。
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: "docker.{{.Name}}"
Dockerにはロギング・ドライバ(logging driver)というコンテナのログを記録するための仕組みがあります。
ログの形式は、driverオプションを指定することで選択できます。デフォルトでは、driver: json-file
となっており、JSON形式で記録されています。
今回は、docker-compose.ymlで明示的にFluentdロギングドライバを指定しました。
指定方法は見たとおりですが、driver: fluentd
の部分で、Fluentdのためのいくつかのオプションを設定しています。
fluentd-address
は送信先となるFluentdのアドレスです。今回はFluentdのコンテナを24224番ポートでポートバインディングしているため、localhost:24224
を指定することでFluentdのコンテナに接続できようになっています。
tag
は、ログ出力を識別するために設定しています。"docker.{{.Name}}"
と指定することで、docker.<コンテナ名>
のような形式でタグが付与されログ出力されます。デフォルトでは、コンテナIDの先頭12文字となります。
コンテナ名以外にイメージ名などをタグに入れることが可能です。詳細は以下をご参照ください。
注意として、Nginxのコンテナが起動した際にFluentdに接続できるようになっていないとログの記録に失敗します。
以下のように起動順序を制御するか、起動後に docker compose restart nginx
を実行し、Nginxを起動し直す必要があります。
depends_on:
- fluentd
解説: ログを収集する側(Fluentd)
Dockerとしては以下を設定しています。
- Fluentd公式イメージを指定(執筆時点での最新バージョンを指定しています)
- 設定ファイルが含まれるディレクトリをバインドマウント
- Fluentdへの接続のため24224番ポートをポートバインド
fluentd:
image: fluent/fluentd:v1.15.3-1.0
volumes:
- ./config:/fluentd/etc
ports:
- 24224:24224
- 24224:24224/udp
Fluentdの設定ファイルは、HTMLのような構造をしています。
各設定のまとまりをディレクティブと呼び、ディレクティブはタグとパラメータで構成されます。
以下の例では、<source>
ディレクティブと<match>
ディレクティブがあり、<source>
ディレクティブ内には<source>
タグと@type
パラメータが指定されている構成となっています。
タグは引数を取るものがあり、<match>
タグのdocker.**
の部分が引数です。
<source>
@type forward
</source>
<match docker.**>
@type stdout
</match>
<source>
ディレクティブの設定では、ログをFluentdに取り込むための入力のための設定です。
typeではforward
を指定しているため、in_forward
プラグインによってネットワーク経由でのログの読み込みを行います。また、in_forward
プラグインはデフォルトで24224番ポートを利用するため、今回Dockerのポートバインドで指定していました。
<match>
ディレクティブの設定では、取り込んだログをどう処理し出力するかを設定します。引数では、処理対象を識別するタグを設定でき、今回はDockerのロギング・ドライバで指定したタグとマッチするように指定しています。
処理内容は、stdout
プラグインを用いて標準出力で出力するのみを設定しています。そのため、動作確認時ではFluentdのコンテナで標準出力として受け取ったNginxのアクセスログが出力されました。
まとめ
かなり簡単にではありますが、FluentdをDockerで動かして挙動を確認してみるまでについて書いてみました。
拙い文章ではありますが、誰かの参考になれば幸いです。