2018年9月6日木曜日

Docker コンテナのログを fluentd を経由して外部の ElasticSearch に送信する方法

概要

fluentd を docker 上で動かしてログを外部の ElasticSearch に送ってみたいと思います
外部というのは fluentd コンテナが動作しているホストとは別のホストのことで例えば ElasticSearch はコンテナではなく VM の上で動作している場合などを想定しています
もちろん ElasticSearch の API のエンドポイントには fluentd コンテナからアクセスできる必要があります

環境

  • macOS 10.13.6
  • docker 18.06.0-ce
  • fluentd (v1.2)
  • ElasticSearch (docker.elastic.co/elasticsearch/elasticsearch:6.4.0)
  • Kibana (docker.elastic.co/kibana/kibana:6.2.4)

Elasticsearch Output Plugin

Dockerhub で公開されている fluentd には基本的にプラグインがインストールされていません
なので ElasticSearch のプラグインがインストールされたイメージを作成します

  • vim Dockerfile
FROM fluent/fluentd

RUN apk add --update --virtual .build-deps \
        sudo build-base ruby-dev \
 && sudo gem install \
        fluent-plugin-elasticsearch \
 && sudo gem sources --clear-all \
 && apk del .build-deps \
 && rm -rf /var/cache/apk/* \
           /home/fluent/.gem/ruby/2.4.0/cache/*.gem
  • docker build -t my_fluentd .

fluent.conf の作成

インストールしたプラグインを使って ElasticSearch にログを送信する設定ファイルを作成します

  • vim fluent.conf
<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

<match docker.**>
  @type copy
  <store>
    @type stdout
  </store>
  <store>
    @type elasticsearch
    host 192.168.99.1
    port 9200
    index_name fluentd
    type_name fluentd
  </store>
</match>

ElasticSearch にログを送るには @type elasticsearch を使います
そして host で外部の ElasticSearch の IP を指定します
今回は copy を使って stdout にも出力していますが不要であれば削除してください

この設定ファイルを使って fluentd コンテナを起動します

fluentd コンテナの起動

  • docker run -d -p 24224:24224 -p 24224:24224/udp -v $(pwd):/fluentd/etc -e FLUENTD_CONF=fluent.conf my_fluentd

先程作成した fluent.conf があるディレクトリを /fluentd/etc にマウントします
そして設定ファイル名を指定するための環境変数 FLUENTD_CONF に設定ファイル名を指定します

あとは TCP/UCP で 24224 をオープンすれば OK です
この 24224 ポートに対して各コンテナはログを投げつけます

動作確認

適当にログを投げつけるコンテナを作成しましょう

  • docker run --rm --log-driver=fluentd --log-opt fluentd-address=192.168.99.1:24224 --log-opt tag="docker.{{.Name}}" alpine /bin/sh -c "while :;do date; sleep 3; done;"

ポイントとなる必須のオプションは 3 つです

  • --log-driver=fluentd
  • --log-opt fluentd-address=192.168.99.1:24224
  • --log-opt tag="docker.{{.Name}}"

1 つ目はロギングドライバを指定するオプションです
2 つ目は外部にある ElasticSearch のエンドポイントです
当然ですがコンテナからアクセスできる必要があります
3 つ目は tag では fluent.conf に定義した match に合わせる必要があります

これでコンテナの stdout が fluentd に拾われて ElasticSearch に投げられます

Kibana を見てみる

ElasticSearch が Kibana と連携しているのであればあとはインデックス (fluentd) を作成するだけでログが見れるようになります

Kibana にアクセスしてインデックスを作成しましょう
ちなみに ElasticSearch に送信されるインデックス名は fluent.conf の index_name fluentd で指定することができます

「index pattern」に「fluentd」と入力して「Next step」を選択します
fluentd_to_es_on_docker1.png

「Create index pattern」を選択します
fluentd_to_es_on_docker2.png

あとは Discover などを見れば ElasticSearch にあるログが確認できると思います
fluentd_to_es_on_docker3.png

最後に

Docker 上で fluentd を動かして各コンテナから受け取ったログを外部の ElasticSearch に送信する方法を紹介しました
各コンポーネントがバラバラに動作しているケースには今回紹介した方法が使えると思います

多くのコンテナからログを受けつける場合には fluentd コンテナのサイズなどを調整しましょう
fluentd クラスタなどを組んでも良いですが今回は紹介しないので興味があれば調べてみてください

1 件のコメント:

  1. docker-compose でロギングドライバを指定する場合は以下のように指定します

    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: docker.container_1

    返信削除