カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまにRuby on Railsなども。

Fluentd + Elasticsearch + Kibanaで遊んでみた(その1) 〜環境構築から簡単な動作確認まで〜

※2017/4/11追記: 新しいバージョンのFluentd 2.3 + Elasticsearch 5.3 + Kibana 5.3での環境構築記事を書きました。
totech.hateblo.jp

今年の冬休みは前々から気になっていた、ログ可視化ツールとして名高い3点セット、Fluentd + Elasticsearch + Kibana で遊んでみることにした。
ググればいたるところに構築手順はあるものの、バージョン違いなどで苦労した箇所もあったので、現時点の最新版を一から構築したときのメモを残す。

入れるバージョンは全て現時点での最新版である以下の通り。

  • Fluentd (td-agent 2.3.0) : ログ収集ミドルウェアで、今回はログファイルをElasticsearchへ転送する用途のみに使う
  • Elasticsearch 2.1.1 : 全文検索システムで、データベースを内部に持ち、簡単な集計もできる
  • Kibana 4.3.1: Elasticsearchに問合せを発行し、結果をきれいなグラフで可視化する

構成としては、MacにVirtualBoxで仮想マシンのCent OS 7を入れて、そこにFluentd + Elasticsearch + Kibanaをインストールすることにする。

仮想マシンでサーバ構築

この際なので、VirtualBoxとVagrantも公式サイトからMac版最新版のpkgを入手して最新化した結果、バージョンは以下に。

  • VirtualBox: 5.0.12 r104815
  • Vagrant: 1.8.1

VagrantのboxでCent OS 7を探したところ、以下が使えそう。
https://atlas.hashicorp.com/centos/boxes/7
libvirt版とvirtualbox版が選べるので、当然後者のvirtualboxを指定する。

$ vagrant box add centos/7
$ vagrant box list

centos/7  (virtualbox, 1509.01) ★追加された

仮想マシン用のディレクトリ(今回は”dev-centos7”とする)を切って、そこで追加したBoxのマシンを初期化する。

$ mkdir dev-centos7
$ cd dev-centos7
$ vagrant init centos/7

起動とログインに成功することも確認。

$ vagrant up
$ vagrant ssh

サーバはこれでOK。
以降の作業は基本的にはこの仮想マシン内のvagrantユーザで行う。

Fluentd (td-agent 2.3.0) インストール

まずはログ収集ミドルウェアのFluentdを入れる。Fluentdは公式文書の手順を参考にして、最新版のtd-agent 2.3.0をインストールした。
http://docs.fluentd.org/articles/install-by-rpm

ところで、td-agentとは「the stable distribution of Fluentd, called td-agent」という意味で、安定版のFluentdのことをいうらしい。

インストールはOSごとにスクリプトが用意されており、Redhat系のOSの場合は以下のコマンド一発で入る。簡単!

$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh

Fluentdはtd-agentという名前のserviceとして使えるようになっているので、起動停止させてみる。
★起動

$ sudo service td-agent start
Starting td-agent (via systemctl):                         [  OK  ]

★起動確認

$ sudo service td-agent status
td-agent is running

★プロセス確認(親子関係の2つのプロセスが確認できる)

$ ps -ef | grep td-agent | grep -v grep
td-agent 17550     1  0 11:18 ?        00:00:00 /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --use-v1-config --group td-agent --daemon /var/run/td-agent/td-agent.pid
td-agent 17553 17550  0 11:18 ?        00:00:00 /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --use-v1-config --group td-agent --daemon /var/run/td-agent/td-agent.pid

★停止

$ sudo service td-agent stop
Stopping td-agent (via systemctl):                         [  OK  ]

★停止確認

$ sudo service td-agent status
td-agent is not running

起動・停止は問題なさそう。

あとは、後でElasticsearchにデータを転送できるようにするために、連携用のfluent-plugin-elasticsearchプラグインをインストールしておく。
プラグインはfluent-gemコマンドでインストールできる。

$ sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elasticsearch
★fluent-plugin-elasticsearch (1.3.0) が入った

Fluentdを使ってみる

設定ファイルを編集する。
/etc/td-agent/td-agent.confに以下の内容を追記。

/etc/td-agent/td-agent.conf

<source>
  type forward
  port 24224
</source>

<match *.*>
  type stdout
</match>

Fluentdのリッスンポート24224に送られたログはstdout、つまりFluentdの標準ログに流されるという設定にする。
Fluentdへの入力は、fluent-catというコマンドが用意されているので、それで確認できる。引数にはタグを適当に指定する。match側にはタグを正規表現で指定できるので、今回設定した"*.*"にマッチするように、”debug.test”とする。

$ echo '{"message":"Hello,World."}' | /opt/td-agent/embedded/bin/fluent-cat debug.test
$ tail /var/log/td-agent/td-agent.log
2016-01-02 11:18:33 -0500 [info]: listening fluent socket on 0.0.0.0:24224
2016-01-02 11:29:46 -0500 debug.test: {"message":"Hello,World."}

debug.testというタグでmessageが受信できていることが確認できた!Fluentdの動きは問題なさそう。

Elasticsearch 2.1.1 インストール

次に全文検索システムのElasticsearchをインストールする。
ElasticsearchはJavaが必要なので、ない場合は先にこちらを入れておく。今回はOpen JDK 1.8.0をyumで入れる。
※rootで実行

# yum install java-1.8.0-openjdk-headless
# java -version
openjdk version "1.8.0_65"
OpenJDK Runtime Environment (build 1.8.0_65-b17)
OpenJDK 64-Bit Server VM (build 25.65-b01, mixed mode)

Elasticsearchのインストーラを以下の公式サイトからダウンロードする。
https://www.elastic.co/downloads/elasticsearch

インストール手順も公式文書に書いてある通り。
aptやyumベースで入れられるようになっているので、yumの手順に従う。
https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-repositories.html#_yum

Elasticsearchのrpmをインポートする。

$ sudo rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch

Elasticsearchのリポジトリを追加する。
/etc/yum.repos.dディレクトリにelasticsearch.repoファイルを以下の内容で作成する。

/etc/yum.repos.d/elasticsearch.repo

[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=http://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1

yumでElasticsearchをインストールする。

$ sudo yum install elasticsearch

自動起動も有効化しておく。

$ sudo systemctl enable elasticsearch.service
ln -s '/usr/lib/systemd/system/elasticsearch.service' '/etc/systemd/system/multi-user.target.wants/elasticsearch.service'

Elasticsearchがインストールできたので、起動停止方法を確認しておく。yumで入れているので、普通にserviceコマンドで起動・停止できる。
★起動

$ sudo service elasticsearch start
Starting elasticsearch (via systemctl):                    [  OK  ]

★起動確認

$ sudo service elasticsearch status
elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled)
   Active: active (running) since Sat 2016-01-02 10:25:49 EST; 3s ago
     Docs: http://www.elastic.co
  Process: 16645 ExecStartPre=/usr/share/elasticsearch/bin/elasticsearch-systemd-pre-exec (code=exited, status=0/SUCCESS)
 Main PID: 16646 (java)
   CGroup: /system.slice/elasticsearch.service
           └─16646 /bin/java -Xms256m -Xmx1g -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcM..$

Jan 02 10:25:49 dev systemd[1]: Starting Elasticsearch...
Jan 02 10:25:49 dev systemd[1]: Started Elasticsearch.

Active: active (running)になっている。
★停止

$ sudo service elasticsearch stop
Stopping elasticsearch (via systemctl):                    [  OK  ]

★停止確認

$ sudo service elasticsearch status
elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled)
   Active: inactive (dead) since Sat 2016-01-02 10:25:58 EST; 1s ago
     Docs: http://www.elastic.co
  Process: 16646 ExecStart=/usr/share/elasticsearch/bin/elasticsearch -Des.pidfile=${PID_DIR}/elasticsearch.pid -Des.default.path.home=${ES_HOME} -Des.default.path.logs=${LOG_DIR} -Des.default.path.data=${DATA_DIR} -Des.default.path.conf=${CONF_DIR} (code=exited, status=143)
  Process: 16645 ExecStartPre=/usr/share/elasticsearch/bin/elasticsearch-systemd-pre-exec (code=exited, status=0/SUCCESS)
 Main PID: 16646 (code=exited, status=143)

Jan 02 10:25:49 dev systemd[1]: Starting Elasticsearch...
Jan 02 10:25:49 dev systemd[1]: Started Elasticsearch.
Jan 02 10:25:58 dev systemd[1]: Stopping Elasticsearch...

Jan 02 10:25:58 dev systemd[1]: Stopped Elasticsearch.

Active: inactive (dead)になった。

Elasticsearchを使ってみる

ElasticsearchはREST形式のAPIでいろいろな操作を行うものらしい。
なので、まずElasticsearchを起動し、GETに応答することを確認する。デフォルトでは9200番ポートで起動するので、おもむろにcurlを打ってみる。

$ curl -XGET http://localhost:9200
{
  "name" : "Richard Parker",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.1.1",
    "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71",
    "build_timestamp" : "2015-12-15T13:05:55Z",
    "build_snapshot" : false,
    "lucene_version" : "5.3.1"
  },
  "tagline" : "You Know, for Search"
}

応答が返ってきた!正常に起動しているよう。

続いて簡単なデータを登録してみる。
Elasticsearchではインデックスというデータ構造にデータを登録するようなので、まずsample_indexという名前のインデックスを作成する。

$ curl -XPOST http://localhost:9200/sample_index
{"acknowledged":true}

test_indexにテストデータを登録する。
Elasticsearchは、/インデックス名/タイプ名/ID のURLパターンでにアクセスし、PUT形式のリクエストで登録できる。
※以下は-dをつけているので、1行目だけでなく、全てが実行するコマンドであることに注意。

$ curl -XPUT http://vmdev:9200/sample_index/sample_log/1 -d '
{
  "timestamp": "01/May/2015:05:10:22 +0000",
  "value": "hoge",
  "number": "200"
}
'

以下のメッセージが出力される。どうやら成功しているよう。

{"_index":"sample_index","_type":"sample_log","_id":"1","_version":1,"_shards":{"total":2,"successful":1,"failed":0},"created":true}

_searchを付与すると検索できるよう。検索条件はリクエスト内で指定できるようだが、今回は何も指定せずに検索する。

$ curl -XGET http://localhost:9200/sample_index/_search -d '
{
  "query": {
    "match_all": {}
  }
}
'

実行結果は以下。正しくとれているよう。

{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"sample_index","_type":"sample_log","_id":"1","_score":1.0,"_source":
{
  "timestamp": "01/May/2015:05:10:22 +0000",
  "value": "hoge",
  "number": "200"
}

Elasticsearch管理プラグインのkopf (最新の2.1.1)をインストール

いろいろ見ていると、kopfというElasticssearchの管理GUIを提供してくれるプラグインがあるらしいので、使ってみる。
https://github.com/lmenezes/elasticsearch-kopf

ElasticsearchのプラグインもFluentdと同じように、専用コマンドでインストールできる。

$ sudo /usr/share/elasticsearch/bin/plugin install lmenezes/elasticsearch-kopf
(略)
Installed kopf into /usr/share/elasticsearch/plugins/kopf

kopfのインターフェースには以下のURLでアクセスできるらしい。
http://host:9200/_plugin/kopf

ここで、ホスト機のMac側でhostsに仮想マシンのIPアドレスをvmdevというホスト名で解決できるように設定して以下のURLにアクセスしてみたが、画面がつながらなかった。どうやら、Elasticsearch側のネットワークの設定が必要なよう。
http://vmdev:9200/_plugin/kopf

Elasticsearchの設定ファイルは以下にあったので、これを編集する。
/etc/elasticsearch/elasticsearch.yml

$ sudo vi /etc/elasticsearch/elasticsearch.yml

network.hostという項目がコメントアウトされているので、これを仮想マシンのIPアドレスを明示的に指定して有効化する。

network.host: 192.168.33.10

Elasticsearchを再起動する。

$ sudo service elasticsearch restart

再度、Macからkopfにアクセス。
http://vmdev:9200/_plugin/kopf

f:id:osn_th:20160106213840p:plain
上記のような作ったindexがWebブラウザで確認できるコンソールが表示された。ここで、indexの設定確認やREST発行ができる。
また、この変更でゲストOS(仮想マシン側)のコンソールからlocalhostではElasticsearchに接続できなくなったので、localhostからも直接IPアドレス指定でアクセスする必要がある。

$ curl -XGET http://localhost:9200
curl: (7) Failed connect to localhost:9200; Connection refused

$ curl -XGET http://192.168.33.10:9200
{
  "name" : "Electro",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.1.1",
    "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71",
    "build_timestamp" : "2015-12-15T13:05:55Z",
    "build_snapshot" : false,
    "lucene_version" : "5.3.1"
  },
  "tagline" : "You Know, for Search"
}

Kibana 4.3.1セットアップ

Kibana 4.3.1は以下の公式サイトからダウンロードできる。
https://www.elastic.co/downloads/kibana

KibanaはスタンドアロンなWebサーバがバンドルされていて、付属の起動スクリプトを実行するだけでWebインタフェースが立ち上がる構成になっている。ちなみに、Kibana 3以前はApacheなどのWebサーバを自前で用意してやる必要があったようだが、Kibana 4からはその必要がなくなったよう。

Kibanaを公式サイトからダウンロードし、適当なディレクトリに展開・配置する。

$ wget https://download.elastic.co/kibana/kibana/kibana-4.3.1-linux-x64.tar.gz
$ tar xvfz kibana-4.3.1-linux-x64.tar.gz
$ ln -s kibana-4.3.1-linux-x64 kibana
$ cd kibana

Kibanaを起動する。binディレクトリに”kibana”というそのままな実行可能ファイルがあるので、それを実行する。

$ ./bin/kibana
  log   [19:32:43.615] [info][status][plugin:kibana] Status changed from uninitialized to green - Ready
  log   [19:32:43.655] [info][status][plugin:elasticsearch] Status changed from uninitialized to yellow - Waiting for Elasticsearch
  log   [19:32:43.671] [info][status][plugin:kbn_vislib_vis_types] Status changed from uninitialized to green - Ready
  log   [19:32:43.676] [info][status][plugin:markdown_vis] Status changed from uninitialized to green - Ready
  log   [19:32:43.679] [info][status][plugin:metric_vis] Status changed from uninitialized to green - Ready
  log   [19:32:43.686] [info][status][plugin:spyModes] Status changed from uninitialized to green - Ready
  log   [19:32:43.691] [info][status][plugin:statusPage] Status changed from uninitialized to green - Ready
  log   [19:32:43.695] [info][status][plugin:table_vis] Status changed from uninitialized to green - Ready
  log   [19:32:43.713] [info][listening] Server running at http://0.0.0.0:5601
  log   [19:32:48.747] [info][status][plugin:elasticsearch] Status changed from yellow to yellow - No existing Kibana index found
  log   [19:32:51.678] [info][status][plugin:elasticsearch] Status changed from yellow to green - Kibana index ready

以下のURLにブラウザでアクセスする。
http://vmdev:5601
f:id:osn_th:20160106213843p:plain
Kibanaの画面が正しく表示された!

KibanaはElasticsearchの接続先の情報を登録しておく必要があるが、デフォルトだとlocalhostが前提となっている。しかし、先ほどIPアドレス指定でないとアクセスできないようにElasticsearch側の設定を変更しているため、このままではKibanaからElasticsearchにアクセスできない。そのため、Kibanaのconfigを変更し、IPアドレス指定でElasticsearchにアクセスするようにする。

$ vi config/kibana.yml

hostをvmdevに変更のため、以下のように変更

elasticsearch.url: "http://vmdev:9200"

Kibanaで可視化を試してみる。
可視化にあたっては、以下の記事がそのまま参考になったので、ここではリンクの紹介のみとする。
http://qiita.com/harukasan/items/3737a1cc0bed2facc14e

まとめ

いまさらながらFluentd + Elasticsearch + Kibanaの環境構築と簡単な疎通確認レベルで各ツールを動かしてみた。
いずれのツールも簡単にとても簡単に構築できたし、ツール自体がとてもシンプルに設計されているので、Web上のさまざまな記事を参考にして一通り疎通させることができた。
なお、構築にあたってかなりの部分を以下の書籍を参考にしたが、やや最新版とは異なる箇所もあった(特にElasticsearchやKibana)。

ただ、基本的な考え方はほとんど変わらず、セットアップの手順や設定ファイルの書き方がやや異なる程度なので、その辺りはWeb上の参考情報や公式文書を見ながら試行錯誤して、それほど嵌まることなくここまでこれた。

次は、具体的なデータを使って、ElasticsearchからKibanaへのデータ連携から可視化までの一気通貫の流れを記事にまとめたい。
以上!


続きの記事です。