Fluentdからの記事

序章

Fluentdとは何ですか?

Fluentdは、ロギングインフラストラクチャを統合するために設計されたオープンソースのデータコレクターです。 ログの収集と保存をシンプルかつスケーラブルにすることで、運用エンジニア、アプリケーションエンジニア、データエンジニアを結び付けるように設計されています。

Fluentdの前

Messy logging structure showing relationships between many programs

Fluentdの後

Fluentd collects application and access logs from many sources and funnels them to many analysis, archiving, and metrics outputs

主な機能

Fluentdには、クリーンで信頼性の高いロギングパイプラインの構築に適した4つの主要な機能があります。

  • JSONを使用した統合ログ: Fluentdは、データを可能な限りJSONとして構造化しようとします。 これにより、Fluentdは、ログデータの処理のすべての側面(複数のソースと宛先にわたるログの収集、フィルタリング、バッファリング、および出力)を統合できます。 JSONを使用すると、厳密なスキーマを強制せずにアクセスできる十分な構造があるため、ダウンストリームのデータ処理がはるかに簡単になります。
  • プラグイン可能なアーキテクチャー: Fluentdには、コミュニティがその機能を拡張できるようにする柔軟なプラグインシステムがあります。 300以上のコミュニティ提供プラグインは、数十のデータソースを数十のデータ出力に接続し、必要に応じてデータを操作します。 プラグインを使用することで、ログをすぐに有効に活用できます
  • 必要な最小限のリソース:ユーザーがビジー状態のマシンで快適に実行できるように、データコレクターは軽量である必要があります。 FluentdはCとRubyの組み合わせで記述されており、最小限のシステムリソースしか必要としません。 バニラインスタンスは30〜40 MBのメモリで実行され、13,000イベント/秒/コアを処理できます
  • 組み込みの信頼性:データが失われることはありません。 Fluentdは、ノード間のデータ損失を防ぐために、メモリベースおよびファイルベースのバッファリングをサポートしています。 Fluentdは堅牢なフェイルオーバーもサポートしており、高可用性を実現するように設定できます

目標:Fluentdを使用して一元化されたDockerコンテナログを収集する

Dockerコンテナーが本番環境でロールアウトされるにつれて、コンテナーのログをコンテナーよりも一時的でない場所に保持する必要性が高まっています。

このチュートリアルでは、Fluentdをインストールし、それを使用してDockerコンテナーからログを収集し、コンテナーが停止した後にデータを保存できるようにそれらを外部に保存する方法を示します。 同じUbuntu14.04サーバー上でElasticsearchを実行している別のコンテナーにデータをストリーミングします。

KubernetesのGitHubレポジトリで概説されているように、このアーキテクチャは、各コンテナのDockerデーモンによって生成されたJSON-per-lineログファイルを追跡および解析するFluentdの機能を使用します。 最小限の設定については、このレシピを参照してください。

このチュートリアルの最後に、さらに2つのユースケースについて説明します。 この記事を読んだ後は、Fluentdの基本的な使い方を知っておく必要があります。

前提条件

チュートリアルのこれらの前提条件を必ず完了してください。

ステップ1—Fluentdのインストール

Fluentdをデプロイする最も一般的な方法は、td-agentパッケージを使用することです。 Fluentdの元の作者であるTreasureDataは、Fluentdを独自のRubyランタイムでパッケージ化するため、ユーザーはFluentdを実行するために独自のRubyをセットアップする必要がありません。

現在、td-agentは次のプラットフォームをサポートしています。

  • Ubuntu:明快で、正確で、信頼できる
  • Debian:WheezyとSqueeze
  • RHEL / Centos:5、6、7
  • Mac OSX:10.9以降

このチュートリアルでは、Ubuntu 14.04 LTS(Trusty)を実行しているDigitalOceanDropletを使用していることを前提としています。

次のコマンドでtd-agentをインストールします。

curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-trusty-td-agent2.sh | sh

td-agentを開始します:

sudo /etc/init.d/td-agent start

ログをチェックして、正常にインストールされたことを確認します。

tail /var/log/td-agent/td-agent.log

次のような出力が表示されます。

	port 24230
  </source>
</ROOT>
2015-02-22 18:27:45 -0500 [info]: adding source type="forward"
2015-02-22 18:27:45 -0500 [info]: adding source type="http"
2015-02-22 18:27:45 -0500 [info]: adding source type="debug_agent"
2015-02-22 18:27:45 -0500 [info]: adding match pattern="td.*.*" type="tdlog"
2015-02-22 18:27:45 -0500 [info]: adding match pattern="debug.**" type="stdout"
2015-02-22 18:27:45 -0500 [info]: listening fluent socket on 0.0.0.0:24224
2015-02-22 18:27:45 -0500 [info]: listening dRuby uri="druby://127.0.0.1:24230" object="Engine"

注:あるいは、FluentdはRuby gemとして利用可能であり、gem install fluentdと一緒にインストールできます。 sudo権限がない場合は、Rubyをインストールして(たとえば、ここでRuby をインストールするを参照)、次のコマンドを実行してください。

gem install fluentd --no-rdoc --no-ri

ステップ2—Dockerをインストールする

次に、Dockerをインストールします。 このチュートリアルは、Dockerv1.5.0でテストされました。

Dockerリポジトリのキーを追加して、最新のDockerパッケージを取得できるようにします。

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9

ソースにリポジトリを追加します。

sudo sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"

システムを更新します。

sudo apt-get update

Dockerをインストールします。

sudo apt-get install lxc-docker

バージョンを確認して、Dockerがインストールされていることを確認します。

docker --version

次のような出力が表示されます。

Docker version 1.5.0, build a8a31ef

ステップ3—Dockerグループにユーザーを追加する

Dockerはrootとして実行されるため、dockerコマンドを発行するには、sudoユーザーをdockerグループに追加します。 sammyを選択したユーザーに置き換えます。

sudo gpasswd -a sammy docker

次に、Dockerを再起動します。

sudo service docker restart

最後に、現在sudoユーザーとしてログインしている場合は、ログアウトしてから再度ログインする必要があります。

ステップ4—Fluentdイメージの構築

このセクションでは、FluentdDockerコンテナーのDockerイメージを作成します。 Docker全般について詳しく知りたい場合は、この入門チュートリアルをお読みください。

Fluentd Dockerリソース用の新しいディレクトリを作成し、そのディレクトリに移動します。

mkdir ~/fluentd-docker && cd ~/fluentd-docker

次のDockerfileを作成します。

sudo nano Dockerfile

次の内容をファイルに正確に追加します。 このファイルは、DockerにDockerコンテナを更新し、Ruby、Fluentd、Elasticsearchをインストールするように指示します。

FROM ruby:2.2.0
MAINTAINER [email protected]
RUN apt-get update
RUN gem install fluentd -v "~>0.12.3"
RUN mkdir /etc/fluent
RUN apt-get install -y libcurl4-gnutls-dev make
RUN /usr/local/bin/gem install fluent-plugin-elasticsearch
ADD fluent.conf /etc/fluent/
ENTRYPOINT ["/usr/local/bundle/bin/fluentd", "-c", "/etc/fluent/fluent.conf"]

また、同じディレクトリにfluent.confファイルを作成する必要があります。

sudo nano fluent.conf

fluent.confファイルは次のようになります。 このファイルを正確にコピーできます。

<source>
  type tail
  read_from_head true
  path /var/lib/docker/containers/*/*-json.log
  pos_file /var/log/fluentd-docker.pos
  time_format %Y-%m-%dT%H:%M:%S
  tag docker.*
  format json
</source>
# Using filter to add container IDs to each event
<filter docker.var.lib.docker.containers.*.*.log>
  type record_transformer
  <record>
    container_id ${tag_parts[5]}
  </record>
</filter>

<match docker.var.lib.docker.containers.*.*.log>
  type elasticsearch
  logstash_format true
  host "#{ENV['ES_PORT_9200_TCP_ADDR']}" # dynamically configured to use Docker's link feature
  port 9200
  flush_interval 5s
</match>

このファイルの目的は、他のDockerコンテナーのログの場所をFluentdに通知することです。

次に、fluentd-esという名前のDockerイメージをビルドします。

docker build -t fluentd-es .

これが完了するまでに数分かかります。 イメージが正常に作成されたことを確認します。

docker images

次のような出力が表示されます。

REPOSITORY      	TAG             	IMAGE ID        	CREATED         	VIRTUAL SIZE
fluentd-es      	latest          	89ba1fb47b23    	2 minutes ago   	814.1 MB
ruby            	2.2.0           	51473a2975de    	6 weeks ago     	774.9 MB

ステップ5—Elasticsearchコンテナを起動する

次に、Elasticsearchコンテナのホームディレクトリまたは優先ディレクトリに戻ります。

cd ~

Elasticsearchコンテナをダウンロードして起動します。 このための自動ビルドはすでにあります:

docker run -d -p 9200:9200 -p 9300:9300 --name es dockerfile/elasticsearch

コンテナイメージがダウンロードされて開始するのを待ちます。

次に、Dockerプロセスをチェックして、Elasticsearchコンテナが正しく実行されていることを確認します。

docker ps

次のような出力が表示されます。

CONTAINER ID    	IMAGE                         	COMMAND            	CREATED         	STATUS          	PORTS                                        	NAMES
c474fd99ce43    	dockerfile/elasticsearch:latest   "/elasticsearch/bin/   4 minutes ago   	Up 4 minutes    	0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es

ステップ6—FluentdからElasticsearchへのコンテナーの起動

次に、Fluentdを実行するコンテナーを起動し、ログを収集してElastcisearchに送信します。

docker run -d --link es:es -v /var/lib/docker/containers:/var/lib/docker/containers fluentd-es

上記のコマンドでは、--link es:es部分がElasticsearchコンテナーをFluentdコンテナーにリンクしています。 ホストコンテナのログディレクトリをFluentdコンテナにマウントするには、-v /var/lib/docker/containers:/var/lib/docker/containersの部分が必要です。これにより、Fluentdは、コンテナの作成時にログファイルを調整できます。

最後に、アクティブなDockerプロセスをチェックして、コンテナーが実行されていることを確認します。

docker ps

今回は、Elasticsearchコンテナーと新しいfluentd-esコンテナーの両方が表示されます。

CONTAINER ID    	IMAGE                         	COMMAND            	CREATED         	STATUS          	PORTS                                        	NAMES
f0d2cac81ac8    	fluentd-es:latest             	"/usr/local/bundle/b   2 seconds ago   	Up 2 seconds                                                     	stupefied_brattain
c474fd99ce43    	dockerfile/elasticsearch:latest   "/elasticsearch/bin/   6 minutes ago   	Up 6 minutes    	0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es

ステップ7—Elasticsearchがイベントを受信していることを確認する

最後に、Elasticsearchがイベントを受信していることを確認しましょう。

curl -XGET 'http://localhost:9200/_all/_search?q=*'

出力には、次のようなイベントが含まれている必要があります。

{"took":66,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
{"took":59,"timed_out":false,"_shards":{"tod","_id":"AUwLaKjcnpi39wqZnTXQ","_score":1.0,"_source":{"log":"2015-03-12 00:35:44 +0000 [info]: following tail of /var/lib/docker/containers/6abeb6ec0019b2198ed708315f4770fc7ec6cc44a10705ea59f05fae23b81ee9/6abeb6ec0019b2198ed708315f4770fc7ec6cc44a10705ea59f05fae23b81ee9-json.log\n","stream":"stdout","container_id":"6abeb6ec0019b2198ed708315f4770fc7ec6cc44a10705ea59f05fae23b81ee9","@timestamp":"2015-03-12T00:35:44+00:00"}}]}}

設定によっては、かなりの数のイベントがログに記録される場合があります。 単一のイベントは{"took":で始まり、タイムスタンプで終わる必要があります。

この出力が示すように、Elasticsearchはデータを受信しています。 (コンテナIDは上記のものとは異なります!)

ステップ8—イベントログを次のレベルに引き上げる

コンテナイベントがElasticsearchによって保存されているので、次に何をしますか? Elasticsearchには便利なことがたくさんあります。 あなたがアイデアを探しているなら、あなたはチェックしたいかもしれません:

結論

Dockerコンテナーからログを収集することは、Fluentdを使用する1つの方法にすぎません。 このセクションでは、Fluentdの他の2つの一般的なユースケースを紹介します。

ユースケース1:リアルタイムのログ検索とログアーカイブ

多くのユーザーがFluentdにアクセスして、リアルタイムのログ検索と長期保存の両方を行うロギングパイプラインを構築しています。 アーキテクチャは次のようになります。

Funnelling logs from multiple backends to Elasticsearch, MongoDB, and Hadoop

このアーキテクチャは、データストリームをコピーして複数のストレージシステムに出力するFluentdの機能を利用しています。 上記の設定では、Elasticsearchはリアルタイム検索に使用され、MongoDBやHadoopはバッチ分析と長期保存に使用されます。

ユースケース2:一元化されたアプリケーションロギング

Webアプリケーションは多くのログを生成し、それらは多くの場合任意にフォーマットされ、ローカルファイルシステムに保存されます。 これは2つの理由で悪いです:

  • ログはプログラムで解析するのが難しく(多くの正規表現が必要)、統計分析(A / Bテスト、不正検出など)を通じてユーザーの行動を理解したい人はあまりアクセスできません。
  • テキストログはストレージシステムに一括ロードされるため、ログにリアルタイムでアクセスすることはできません。 また、サーバーのディスクが一括読み込みの間に破損した場合、ログは失われたり破損したりします

Fluentdは、次の方法でこれらの問題を解決します。

  • 一貫性のあるAPIを使用してさまざまなプログラミング言語用のロガーライブラリを提供します。各ロガーはトリプル(タイムスタンプ、タグ、JSON形式のイベント)をFluentdに送信します。 現在、Ruby、Node.js、Go、Python、Perl、PHP、Java、C++用のロガーライブラリがあります
  • アプリケーションが「ファイアアンドフォーゲット」できるようにする:ロガーはFluentdに非同期でログを記録でき、Fluentdはバックエンドシステムにアップロードする前にログをバッファリングします。

資力: