Fluentd の Docker のサンプルを動かしてみた話

Fluentd の Docker のサンプルを動かしてみた話

うちの会社では複数あるサーバのログ集約に Fluentd を使っている。 サーバが多数あってもログファイルが1個のサーバに集まっていればログを確認するときに便利だ。 いままではなんとなく見よう見まねで使っていたが、ここいらで一つ本家ドキュメントを読んでおこう。

ここだな…

https://docs.fluentd.org/

Fluentd とは

  • ログ集約と配布をやってくれるミドルウェア。
  • 多様な入力と出力の機能や、フィルタリングや、バッファリングの機能がある。
  • それぞれプラグインがあって、どこと繋げるとか抽出の機能を外付けできる。

設定でよく見かける 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して…と。

>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 はどうなっているかというと…

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 のログ設定が

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 に固定したぜ!(重要なところだけ記載。)

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

起動してみよう。

>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 をインストールしてと…

>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

設定してみよう。

logging:
  driver: "fluentd"
  options:
    fluentd-address: 10.10.10.10:24224
    tag: httpd.access
    fluentd-async: "true"

さあどうかな?

>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 のサービスなんか動いてないのに。

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 の外にでているのだ。そういうことだったのか!

fluentd:
  build: ./fluentd
  volumes:
    - ./fluentd/conf:/fluentd/etc
  links:
    - "elasticsearch"
  ports:
    - "24224:24224"
    - "24224:24224/udp"

まとめ

とにかく動かすことができた。設定ファイルの書式もわかってきた。次はfluentdをテスト用AWSアカウントで実際に立ててみよう。

続きはまた別の機会に。

前の記事
«
次の記事
»

技術カテゴリの最新記事