うちの会社では複数あるサーバのログ集約に Fluentd を使っている。 サーバが多数あってもログファイルが1個のサーバに集まっていればログを確認するときに便利だ。 いままではなんとなく見よう見まねで使っていたが、ここいらで一つ本家ドキュメントを読んでおこう。
ここだな…
Fluentd とは
- ログ集約と配布をやってくれるミドルウェア。
- 複数のサーバでそれぞれ出力されるログを1台のサーバに集めてくれて便利。わざわざたくさんあるサーバにssh使ってログを見に行かなくて良い。
- 多様な入力と出力の機能や、フィルタリングや、バッファリングの機能がある。
- それぞれプラグインがあって、どこと繋げるとか抽出の機能を外付けできる。
- 拡張性
設定でよく見かける 24224
ポートは forward というプラグインのデフォルトのポートだ。これはfluentd 間の通信で使われる。 例えば これ はJavaのロガーでロガーがfluentdサーバにログメッセージを送る。
でもこれ直接使うとアプリケーションから org.fluentd.logger.FluentLogger
を直接使うことになるから、何らかのロガーのアペンダーとして提供されているほうが出力先を切り替えたいときに楽かもね。
Dockerも fluentd の機能を持っている。設定を入れると指定されたfluentdのサーバにログメッセージを送れる。https://docs.docker.com/config/containers/logging/fluentd/
1個のログメッセージをfluentdでは event
と呼んでいる。event
は タグと時刻とメッセージ内容で構成される。時刻はそのまま時刻だ。タグは event
の分類に使われる。メッセージはJSON形式になるらしい。https://docs.fluentd.org/quickstart/life-of-a-fluentd-event#event-structure
docker-compose でのサンプルを動かしてみる
うむうむなるほど。ドキュメントには動作するサンプルもあるな。https://docs.fluentd.org/container-deployment/docker-compose やってみよう。
これは EFK Stackの例らしい。 ElasticSearch, Fluentd, Kibanaでの分析基盤が動かせるのだな。 コードはここにあるからcloneして…と。
1 2 3 4 5 6 7 8 9 |
>docker-compose up -d Creating elasticsearch ... done Creating fluentd-elastic-kibana_kibana_1 ... done Creating fluentd-elastic-kibana_fluentd_1 ... done Creating fluentd-elastic-kibana_web_1 ... error ERROR: for fluentd-elastic-kibana_web_1 Cannot start service web: failed to initialize logging driver: dial tcp [::1]:24224: connect: connection refused ERROR: for web Cannot start service web: failed to initialize logging driver: dial tcp [::1]:24224: connect: connection refused ERROR: Encountered errors while bringing up the project. > |
エラーになった。どうしてだ? web から fluentd に繋げないのか。 docker-compose.yaml はどうなっているかというと…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
version: "3" services: web: image: httpd ports: - "80:80" links: - fluentd logging: driver: "fluentd" options: fluentd-address: localhost:24224 tag: httpd.access fluentd: build: ./fluentd volumes: - ./fluentd/conf:/fluentd/etc links: - "elasticsearch" ports: - "24224:24224" - "24224:24224/udp" elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.13.1 container_name: elasticsearch environment: - "discovery.type=single-node" expose: - "9200" ports: - "9200:9200" kibana: image: docker.elastic.co/kibana/kibana:7.13.1 links: - "elasticsearch" ports: - "5601:5601" |
web のログ設定が
1 2 3 4 5 |
logging: driver: "fluentd" options: fluentd-address: localhost:24224 tag: httpd.access |
になっているな。これはさっき見たような docker が直接ログドライバーとして fluentd サーバにログを送る設定だ。 接続先と流すタグの設定をしている。
設定を変えて動かしてみる
接続先が localhost
とはどういう意味だろう?というか、links
を使っていてあまりよろしくないかもな。サービス全部同じネットワークに入れて、fluentd のIPアドレスを固定するように設定すればよいだろう。やってみよう。
https://docs.docker.com/compose/compose-file/compose-file-v3/#links
<<ドタドタバタリ>>
よしこれでどうだ。 links
やめて、efk_stack_network
というネットワーク設定してIPアドレスを 10.10.10.10
に固定したぜ!(重要なところだけ記載。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
version: "3" services: web: image: httpd ports: - "80:80" logging: driver: "fluentd" options: fluentd-address: 10.10.10.10:24224 tag: httpd.access networks: efk_stack_network: fluentd: build: ./fluentd volumes: - ./fluentd/conf:/fluentd/etc networks: efk_stack_network: ipv4_address: 10.10.10.10 (略) networks: efk_stack_network: ipam: driver: default config: - subnet: 10.10.10.0/24 |
起動してみよう。
1 2 3 4 5 6 7 8 9 10 |
>docker-compose up -d Creating network "fluentd-elastic-kibana_efk_stack_network" with the default driver Creating fluentd-elastic-kibana_kibana_1 ... done Creating fluentd-elastic-kibana_web_1 ... error Creating fluentd-elastic-kibana_fluentd_1 ... done Creating elasticsearch ... done ERROR: for fluentd-elastic-kibana_web_1 Cannot start service web: failed to initialize logging driver: dial tcp 10.10.10.10:24224: i/o timeout ERROR: for web Cannot start service web: failed to initialize logging driver: dial tcp 10.10.10.10:24224: i/o timeout ERROR: Encountered errors while bringing up the project. > |
つながらない。いやいやいやそんなことはないぞ。試しに ping 打ってみるか。web
がコケてるから一旦ログドライバー設定消して、もう一度起動しよう。まずは ping
をインストールしてと…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
>docker exec -it fluentd-elastic-kibana_web_1 /bin/bash root@b15fc9396cf2:/usr/local/apache2# apt-get update Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB] (略) Processing triggers for libc-bin (2.31-13+deb11u2) ... root@b15fc9396cf2:/usr/local/apache2# ping 10.10.10.10 PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data. 64 bytes from 10.10.10.10: icmp_seq=1 ttl=64 time=0.123 ms 64 bytes from 10.10.10.10: icmp_seq=2 ttl=64 time=0.050 ms 64 bytes from 10.10.10.10: icmp_seq=3 ttl=64 time=0.035 ms 64 bytes from 10.10.10.10: icmp_seq=4 ttl=64 time=0.100 ms 64 bytes from 10.10.10.10: icmp_seq=5 ttl=64 time=0.036 ms ^C --- 10.10.10.10 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4184ms rtt min/avg/max/mdev = 0.035/0.068/0.123/0.036 ms root@b15fc9396cf2:/usr/local/apache2# |
ping 通るな…
もっと設定を変えて動かしてみる
じゃあなんでつながらない?コンテナの起動タイミング的な何かかな? 設定オプションでそれっぽいのないだろうか?
<<ドタドタバタリ>>
あ、 fluentd-async
てのがあるな。メッセージはコネクションが確立されるまでバッファされます。か。
https://docs.docker.com/config/containers/logging/fluentd/#fluentd-async
設定してみよう。
1 2 3 4 5 6 7 |
logging: driver: "fluentd" options: fluentd-address: 10.10.10.10:24224 tag: httpd.access fluentd-async: "true" |
さあどうかな?
1 2 3 4 5 6 7 |
>docker-compose up -d Creating network "fluentd-elastic-kibana_efk_stack_network" with the default driver Creating fluentd-elastic-kibana_web_1 ... done Creating fluentd-elastic-kibana_kibana_1 ... done Creating elasticsearch ... done Creating fluentd-elastic-kibana_fluentd_1 ... done > |
おお起動した!その後のhttp アクセスもちゃんとKibana に拾われているぞ。これでいいんだ。
うーむなるほど。EFKの構成もこのぐらいの docker-compose.yml
で作れるなら学習にもとっつきやすそうだ。
localhostはどこなのか
それにしても…もともとの設定だと接続先が localhost
だったがこれはどういう意味なのだろう? web コンテナで fluentd のサービスなんか動いてないのに。
1 2 3 4 5 6 |
logging: driver: "fluentd" options: fluentd-address: localhost:24224 tag: httpd.access |
<<ドタドタバタリ>>
わかった!この記事によると localhost
ってホスト側のOSを指すらしい。https://blg.dai-it-system.com/2021/09/docker_log_fluentd/ それで、ポートバインディングでホストのポート24224
とfluentd のポート24224
を繋いでいる。つまり通信が一旦 docker の外にでているのだ。そういうことだったのか!
1 2 3 4 5 6 7 8 9 10 |
fluentd: build: ./fluentd volumes: - ./fluentd/conf:/fluentd/etc links: - "elasticsearch" ports: - "24224:24224" - "24224:24224/udp" |
まとめ
とにかく動かすことができた。設定ファイルの書式もわかってきた。次はfluentdをテスト用AWSアカウントで実際に立ててみよう。
続きはまた別の機会に。