Ubuntu16.04でFluentdとElasticSearchを使用してDockerログを一元化する方法
Fluentdからの記事
序章
Dockerコンテナーを本番環境にロールインすると、コンテナーよりも一時的でない場所にログを保持する必要性が高まります。 DockerにはFluentd用のネイティブログドライバーが付属しており、これらのログを簡単に収集して、 Elasticsearch などの別の場所にルーティングできるため、データを分析できます。
Fluentd は、ロギングインフラストラクチャを統合するために設計されたオープンソースのデータコレクターです。 ログの収集と保存をシンプルかつスケーラブルにすることで、運用エンジニア、アプリケーションエンジニア、データエンジニアを結び付けます。
Fluentdには、クリーンで信頼性の高いロギングパイプラインの構築に適した4つの主要な機能があります。
- JSONを使用した統合ログ: Fluentdは、データを可能な限りJSONとして構造化しようとします。 これにより、Fluentdは、ログデータの処理のすべての側面(複数のソースと宛先にわたるログの収集、フィルタリング、バッファリング、および出力)を統合できます。 JSONを使用すると、厳密なスキーマを強制せずにアクセスできる十分な構造があるため、ダウンストリームのデータ処理がはるかに簡単になります。
- プラグイン可能なアーキテクチャー: Fluentdには、コミュニティがその機能を拡張できるようにする柔軟なプラグインシステムがあります。 300以上のコミュニティ提供プラグインが、数十のデータソースを数十のデータ出力に接続し、必要に応じてデータを操作します。 プラグインを使用すると、ログをすぐに有効に活用できます。
- 必要な最小限のリソース:データコレクターは、ビジー状態のマシンで快適に実行できるように軽量である必要があります。 FluentdはCとRubyの組み合わせで記述されており、最小限のシステムリソースしか必要としません。 バニラインスタンスは30〜40 MBのメモリで実行され、13,000イベント/秒/コアを処理できます。
- 組み込みの信頼性:データが失われることはありません。 Fluentdは、ノード間のデータ損失を防ぐために、メモリベースおよびファイルベースのバッファリングをサポートしています。 Fluentdは堅牢なフェイルオーバーもサポートしており、高可用性を実現するように設定できます。
このチュートリアルでは、Fluentdをインストールし、Dockerコンテナーからログを収集するように構成する方法を学習します。 次に、同じUbuntu 16.04サーバーでElasticsearchを実行している別のコンテナーにデータをストリーミングし、ログをクエリします。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Ubuntu16.04初期サーバーセットアップガイドに従ってセットアップされた1つの4GBUbuntu 16.04サーバー(sudo非rootユーザーとファイアウォールを含む)。 これはElasticsearchのメモリ要件を満たします。
- Ubuntu 16.04にDockerをインストールして使用する方法に従って、サーバーにDockerをインストールします。 root以外のユーザーとして実行するようにDockerを構成してください。
ステップ1—Fluentdのインストール
Fluentd をインストールする最も一般的な方法は、td-agent
パッケージを使用することです。 Fluentdの元の作者であるTreasureData は、Fluentdを自己完結型のRubyランタイムでパッケージ化するため、Fluentdを実行するためにRuby環境をセットアップする必要はありません。 また、リポジトリを構成してパッケージをインストールする最新のtd-agent
パッケージを取得するためのスクリプトも提供します。
root以外のユーザーとしてサーバーにログインします。
- ssh sammy@your_server_ip
次に、TreasureDataが提供するスクリプトを使用してtd-agent
をインストールします。 まず、スクリプトをダウンロードします。
- \curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh -o install-td-agent.sh
スクリプトを監査する場合は、テキストエディタでスクリプトを開きます。
- nano install-td-agent.sh
スクリプトの内容に慣れたら、スクリプトを実行してtd-agent
をインストールします。
- sh install-td-agent.sh
インストールが完了したら、td-agent
を開始します。
- sudo systemctl start td-agent
ログをチェックして、正常にインストールされたことを確認します。
- tail /var/log/td-agent/td-agent.log
次のような出力が表示されます。
Output port 8888
</source>
<source>
@type debug_agent
bind 127.0.0.1
port 24230
</source>
</ROOT>
2016-12-02 19:45:31 +0000 [info]: listening fluent socket on 0.0.0.0:24224
2016-12-02 19:45:31 +0000 [info]: listening dRuby uri="druby://127.0.0.1:24230" object="Engine"
次に、td-agent-gem
コマンドを使用してFluentd用のElasticsearchプラグインをインストールします。
- sudo td-agent-gem install fluent-plugin-elasticsearch
注:あるいは、FluentdはRuby gemとして利用可能であり、gem install fluentd
と一緒にインストールできます。 すでにRuby環境が構成されている場合は、gem
コマンドを使用してFluentdとElasticsearchプラグインをインストールできます。
- gem install fluentd --no-rdoc --no-ri
- gem install fluentd-plugin-elasticsearch --no-rdoc --no-ri
これで、Fluentdがデフォルト構成で稼働しています。 次に、Fluentdを構成して、Dockerイベントをリッスンし、Elasticsearchインスタンスに配信できるようにします。
ステップ2—Fluentdの設定
Fluentdは、情報をどこから収集し、どこに配信するかを知る必要があります。 これらのルールは、/etc/td-agent/td-agent.conf
にあるFluentd構成ファイルで定義します。
このファイルをテキストエディタで開きます。
- sudo nano /etc/td-agent/td-agent.conf
ファイルの内容を削除します。 このチュートリアルでは、独自のルールを最初から作成します。
source
セクションで情報源を定義します。 この構成をファイルに追加します。
<source>
@type forward
port 24224
</source>
これにより、ソースがforward
として定義されます。これは、TCP上で実行されるFluentdプロトコルであり、ログをFluentdに送信するときにDockerによって使用されます。
ログレコードが届くと、time
、tag
、message
、container_id
など、いくつかの追加のフィールドが関連付けられます。 _tag_
フィールドの情報を使用して、Fluentdがそのデータを送信する場所を決定します。 これはデータルーティングと呼ばれます。
これを設定するには、tag
フィールドの内容と一致するmatch
セクションを定義し、適切にルーティングします。 この構成をファイルに追加します。
<match docker.**>
@type elasticsearch
logstash_format true
host 127.0.0.1
port 9200
flush_interval 5s
</match>
このルールは、docker.
のプレフィックスが付いたすべてのレコードが、ポート9200
の127.0.0.1
で実行されているElasticsearchに送信されることを示しています。 flush_interval
は、Elasticsearchに記録する頻度をFluentdに通知します。
バッファリングとフラッシュの詳細については、バッファプラグインの概要ドキュメントセクションを参照してください。
新しい構成ファイルを保存したら、td-agent
サービスを再起動して、変更が適用されるようにします。
- sudo systemctl restart td-agent
Fluentdが目的に合わせて適切に構成されたので、ElasticsearchをインストールしてFluentdからログをキャプチャします。
ステップ3—Elasticsearchコンテナを起動する
Dockerを使用してElasticsearchのインスタンスを実行します。これは、自分で構成するよりも高速であるためです。 ElasticsearchDockerイメージを使用してコンテナーを作成します。 このイメージを使用するには、Dockerホストのmax_map_count
の値を次のように増やします。
- sudo sysctl -w vm.max_map_count=262144
次に、次のコマンドを実行してElasticsearchイメージをダウンロードし、コンテナーを起動します。
- docker run -d -p 9200:9200 -p 9300:9300 elasticsearch
イメージがダウンロードされ、Elasticsearchコンテナが起動します。 Dockerプロセスをチェックし、コンテナーを探して、コンテナーが正しく実行されていることを確認します。
- docker ps
次のような出力が表示されます。
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76e96943491f elasticsearch "/docker-entrypoint.s" About a minute ago Up 51 seconds 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp gigantic_hawking
コンテナがリストにない場合は、-d
スイッチを使用せずにコンテナを再起動して、コンテナがフォアグラウンドで実行されるようにします。 コマンドdocker run -p 9200:9200 -p 9300:9300 elasticsearch
を実行し、特定のエラーメッセージを探します。 発生する可能性が最も高いエラーは、十分なシステムメモリがないか、Dockerホストのmax_map_count
値が低すぎるという問題です。 このチュートリアルのすべての手順をチェックして、何かを見逃していないことを確認し、再試行してください。
Elasticsearchがコンテナで実行されているので、いくつかのログを生成してFluentdに取り込みましょう。
ステップ4—Dockerコンテナからのログの生成
Dockerを使用すると、標準の出力(STDOUT
)およびエラー(STDERR
)インターフェースを介してログをデータのストリームとして扱うことができます。 Dockerアプリケーションを起動するときは、ネイティブのFluentdログドライバーを使用してログをフラッシュするようにDockerに指示するだけです。 その後、Fluentdサービスはログを受信し、Elasticsearchに送信します。
次のようにDockerコンテナ内でBashコマンドを開始して、これをテストします。
- docker run --log-driver=fluentd ubuntu /bin/echo 'Hello world'
これにより、メッセージHello world
が標準出力に出力されますが、Docker Fluentdドライバーによってキャッチされ、以前に構成したFluentdサービスに配信されます。 約5秒後、レコードはElasticsearchにフラッシュされます。 この間隔は、Fluentd構成ファイルのmatch
セクションで構成しました。
ログをElasticsearchに渡すにはこれで十分ですが、DockerでFluentdドライバーを管理するために使用できるオプションの詳細については、公式ドキュメントを参照してください。
最後に、Elasticsearchがイベントを受信していることを確認しましょう。 curl
を使用して、Elasticsearchにクエリを送信します。
- curl -XGET 'http://localhost:9200/_all/_search?q=*'
出力には、次のようなイベントが含まれます。
{"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"logstash-2016.12.02","_type":"fluentd","_id":"AVQwUi-UHBhoWtOFQKVx","_score":1.0,"_source":{"container_id":"d16af3ad3f0d361a1764e9a63c6de92d8d083dcc502cd904155e217f0297e525","container_name":"/nostalgic_torvalds","source":"stdout","log":"Hello world","@timestamp":"2016-12-02T14:59:26-06:00"}}]}}
設定によっては、かなりの数のイベントがログに記録される場合があります。 単一のイベントは{"took":
で始まり、タイムスタンプで終わる必要があります。 また、ソースコンテナに関連するいくつかの追加情報も含まれます。 この出力が示すように、ElasticsearchはDockerコンテナからデータを受信しています。
結論
Dockerコンテナーからログを収集することは、Fluentdを使用する1つの方法にすぎません。 多くのユーザーがFluentdにアクセスして、リアルタイムのログ検索と長期保存の両方を行うロギングパイプラインを構築しています。 このアーキテクチャは、データストリームをコピーして複数のストレージシステムに出力するFluentdの機能を利用しています。 たとえば、Elasticsearchを使用してリアルタイム検索を行うことはできますが、MongoDBまたはHadoopを使用してバッチ分析と長期保存を行うことができます。
Webアプリケーションは多くのログを生成し、それらは多くの場合任意にフォーマットされ、ローカルファイルシステムに保存されます。 これには2つの理由で問題が発生する可能性があります。 まず、ログをプログラムで解析するのは難しく、多くの正規表現が必要であるため、統計分析、A / Bテストの結果の確認、または実行を通じてユーザーの行動を理解したい人はあまりアクセスできません。不正検出。
次に、テキストログはストレージシステムに一括ロードされるため、ログにリアルタイムでアクセスすることはできません。 さらに悪いことに、サーバーのディスクがバルクロードの間に破損すると、ログが失われたり破損したりします。
Fluentdは、一貫性のあるAPIを備えたさまざまなプログラミング言語用のロガーライブラリを提供することにより、これらの問題の両方を解決します。 各ロガーは、このチュートリアルで見たように、タイムスタンプ、タグ、およびJSON形式のイベントを含むレコードをFluentdに送信します。 Ruby、Node.js、Go、Python、Perl、PHP、Java、C++用のロガーライブラリがあります。 これにより、アプリケーションは「ファイアアンドフォーゲット」できます。 ロガーはデータをFluentdに非同期で送信し、Fluentdはログをバッファリングしてから、バックエンドシステムに送信します。
FluentdとElasticsearchでできる便利なことは他にもたくさんあります。 次のリンクがおもしろいと思うかもしれません。
- Unified Logging Layer で、ロギングレイヤーの動作の詳細を確認できます。
- 基本的なElasticsearch操作で、Elasticsearchの操作方法について詳しく学びます。
- ダッシュボードの追加。ログを視覚化できます。
- Fluentd + Elasticsearch for Kubernetes by Satnam Singh、Kubernetesコミッター。