Nginx・Fluentd・ElasticSearch・Kibanaの環境を構築してみる

Fluentd、ElasticSearch、Kibanaを初めて試してみたときのメモです。
Nginxのアクセスログをtailして、Fluentdで収集しElasticSearchに保存、Kibanaでログの検索や分析を行うような構成にしました。

概要
1. Fluentdのインストール
2. ElasticSearchのインストール
3. Nginxのインストール
4. Fluentdの設定
5. Kibanaのインストール

ローカル環境(Vagrant)で作成しました。Vagrantfileは下記になります。

作業環境
OS: Windows7 Home Premium 64bit
VirtualBox: 5.0.2
Vagrant: 1.7.4

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

   config.vm.box = "centos67"
   config.vm.box_url = "https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box"

   config.vm.define "node1" do |node1|
     node1.vm.hostname = "node1"
     node1.vm.network "private_network", ip:"192.168.33.40"
     node1.vm.provider "virtualbox" do |vb|
        vb.customize ["modifyvm", :id ,"--memory", "1024"]
     end
   end

   config.vm.define "node2" do |node2|
     node2.vm.hostname = "node2"
     node2.vm.network "private_network", ip:"192.168.33.41"
     node2.vm.provider "virtualbox" do |vb|
        vb.customize ["modifyvm", :id ,"--memory", "1024"]
     end
   end

end

node1はFluentd(Aggregator)、ElasticSearch、kibana
node2はFluentd(Forwarder)、Nginx
をインストールします。

1. Fluentdのインストール [対象:node1・node2]
Fluentd | Open Source Data Collector | Unified Logging Layer

td-agent2のインストールします。td-agent1とは違うので注意してください。
Treasure Agent(td-agent)の1と2の今後 - Qiita
の記事にも書かれていますが、
td-agent1はRuby 1.9.3、td-agent2はRuby 2.1.3を同梱していますが、
Ruby 1.9.3は2015年2月にサポートが終了しています。

新しくFluentdを使いたい場合は、td-agent2をインストールした方が良いでしょう。

$ curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sudo sh
$ td-agent --version
td-agent 0.12.12

自動起動の設定をします。

$ sudo chkconfig td-agent on
$ sudo chkconfig --list td-agent

2. ElasticSearchのインストール [対象:node1]

  • Javaをインストール

ElasticSearchはJavaで動くので、先にインストールします。

$ sudo yum install java-1.7.0-openjdk
  • elasticsearchをインストール

Elasticsearch: RESTful, Distributed Search & Analytics | Elastic

1.5.2をインストールします。1.5.2未満のバージョンは脆弱性があるので注意。
Elasticsearch 1.5.2 および 1.4.5リリース(日本語訳) - @johtaniの日記 2nd

$ sudo rpm --import https://packages.elasticsearch.org/GPG-KEY-elasticsearch
$ sudo vi /etc/yum.repos.d/elasticsearch.repo

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

$ sudo yum install elasticsearch

自動起動の設定をします。

$ sudo chkconfig --add elasticsearch
$ sudo chkconfig elasticsearch on
$ sudo chkconfig --list elasticsearch
$ sudo service elasticsearch start

curlで動作確認します。

$ curl -XGET http://127.0.0.1:9200
{
  "status" : 200,
  "name" : "Crown",
  "cluster_name" : "elasticsearch",
  "version" : { 
  "number" : "1.5.2",
  "build_hash" : "62ff9868b4c8a0c45860bebb259e21980778ab1c",
  "build_timestamp" : "2015-04-27T09:21:06Z",
  "build_snapshot" : false,
  "lucene_version" : "4.10.4"  
  },
  "tagline" : "You Know, for Search"
}

elasticsearchのログファイルは、/var/log/elasticsearch/elasticsearch.logにあります。
動作をしていない場合などに見ると良いでしょう。

FluentdとElasticsearchの連携に必要なプラグインです。

$ sudo td-agent-gem install fluent-plugin-elasticsearch

3. Nginxのインストール [対象:node2]

インストールして、自動起動の設定をします。

$ sudo yum install nginx
$ nginx -v
nginx version: nginx/1.0.15
$ sudo service nginx start
$ sudo chkconfig nginx on
$ chkconfig --list nginx

http://[node2のIPアドレス]/でアクセスして、Nginxのデフォルトページが表示されるか確認します。

4. Fluentdの設定 [対象:node1・node2]

td-agentの設定ファイルは、/etc/td-agent/td-agent.confにあります。
設定ファイルは、system、source、match、includeの4つのディレクティブを用いて記述します。

systemディレクティブ Fluentdのコア部分の動作を決める
sourceディレクティブ ログの入力元を決める
matchディレクティブ ログの出力先を決める
includeディレクティブ 外部から設定を取り込む

さっそくnode2のtd-agent.confを、下記のように編集してください。

<source>
    type tail
    path /var/log/nginx/access.log
    format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forward>[^\"]*)")?$/
    time_format %d/%b/%Y:%H:%M:%S %z
    pos_file /var/log/td-agent/nginx-access.log.pos
    tag nginx.access
</source>

<match **>
   type stdout 
</match>

編集したら、td-agentを再起動してください。

$ sudo service td-agent restart

td-agentのログファイルを見てみます。

$ sudo tail -f /var/log/td-agent/td-agent.log 
2015-10-22 09:09:33 +0000 fluent.error: {"message":"Permission denied @ rb_sysopen - /var/log/nginx/access.log"}
2015-10-22 09:09:34 +0000 [error]: Permission denied @ rb_sysopen - /var/log/nginx/access.log
2015-10-22 09:09:34 +0000 [error]: suppressed same stacktrace
2015-10-22 09:09:34 +0000 fluent.error: {"message":"Permission denied @ rb_sysopen - /var/log/nginx/access.log"}
2015-10-22 09:09:35 +0000 [error]: Permission denied @ rb_sysopen - /var/log/nginx/access.log
2015-10-22 09:09:35 +0000 [error]: suppressed same stacktrace
2015-10-22 09:09:35 +0000 fluent.error: {"message":"Permission denied @ rb_sysopen - /var/log/nginx/access.log"}
2015-10-22 09:09:36 +0000 [error]: Permission denied @ rb_sysopen - /var/log/nginx/access.log
2015-10-22 09:09:36 +0000 [error]: suppressed same stacktrace

上記のエラーの原因は、td-agentデーモンがNginxのアクセスログを読み込める権限がないからです。

以下のように変更しましょう。

$ sudo chown td-agent:td-agent /var/log/nginx/access.log
$ sudo chmod g+x /var/log/nginx/access.log

もう一度、td-agentのログファイルを見てみます。

$ curl -XGET http://192.168.33.41
$ sudo tail -f /var/log/td-agent/td-agent.log 
2015-10-22 09:24:28 +0000 nginx.access: {"remote":"192.168.33.41","host":"-","user":"-","method":"GET","path":"/","code":"200","size":"3698","referer":"-","agent":"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2","forward":"-"}

Nginxのアクセスログを出力していることが確認できます。

次にnode1、node2のtd-agent.confを下記のように編集してから、td-agentを再起動してください。
・node1

###
## Output descriptions:
##

# Treasure Data ([http://www.treasure-data.com/ http://www.treasure-data.com/]) provides cloud based data
# analytics platform, which easily stores and processes data from td-agent.
# FREE plan is also provided.
# @see [http://docs.fluentd.org/articles/http-to-td http://docs.fluentd.org/articles/http-to-td]
# This section matches events whose tag is td.DATABASE.TABLE

<source>
  type forward
  port 24224
</source>

<match nginx.access>
   type elasticsearch
   host 127.0.0.1
   port 9200
   type_name nginx_access_log

   logstash_format true
   logstash_prefix nginx_access_log
   logstash_dateformat %Y%m

   buffer_type memory
   buffer_chunk_limit 1m
   buffer_queue_limit 128
   flush_interval 1s
   retry_limit 16
   retry_wait 1s
</match>

・node2

### 
## Output descriptions: 
## 

# Treasure Data ([http://www.treasure-data.com/ http://www.treasure-data.com/]) provides cloud based data 
# analytics platform, which easily stores and processes data from td-agent. 
# FREE plan is also provided. 
# @see [http://docs.fluentd.org/articles/http-to-td http://docs.fluentd.org/articles/http-to-td] 
# This section matches events whose tag is td.DATABASE.TABLE

<source>
 type tail
 path /var/log/nginx/access.log
 format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<forward>[^\"]*)")?$/
 time_format %d/%b/%Y:%H:%M:%S %z
 pos_file /var/log/td-agent/nginx-access.log.pos
 tag nginx.access
</source>

<match **>
  type forward
  <server>
    host 192.168.33.40
    port 24224
  </server>
  flush_interval 1s
</match>

この設定で以下のことができるようになります。

(1) (node2のFluentdが)Nginxのアクセスログをnode1のFluentdに転送する
(2) (node1のFluentdが)受け取ったログをElasticSearchに保存する

実際にElasticSearchにデータが保存されているか確認します(先にjqをインストールします)。

$ sudo yum install jq
$ curl -XGET http://localhost:9200/nginx_access_log-201510/_search -d '
{
  "query": {
  "match_all": {}
  }
}' | jq .   
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                                   
                                 Dload  Upload   Total   Spent    Left  Speed                                                     
101  4034  100  4034    0    28   202k   1439 --:--:-- --:--:-- --:--:--  558k                                                    
{                                                                                                                                 
  "hits": {                                                                                                                       
    "hits": [                                                                                                                     
      {                                                                                                                           
        "_source": {                                                                                                              
          "@timestamp": "2015-10-22T03:23:18+00:00",                                                                              
          "forward": "-",                                                                                                         
          "agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36",
                                                                                                                                  
          "remote": "192.168.33.1",                                                                                               
          "host": "-",                                                                                                            
          "user": "-",                                                                                                            
          "method": "GET",                                                                                                        
          "path": "/",                                                                                                            
          "code": "304",                                                                                                          
          "size": "0",                                                                                                            
          "referer": "-"                                                                                                          
        },                                                                                                                        
        "_score": 1,                                                                                                              
        "_id": "AVCNkn50wKctAXIQgGZi",                                                                                            
        "_type": "nginx_access_log",                                                                                              
        "_index": "nginx_access_log-201510"                                                                                       
      },                                                                                                                          
      {                                                                                                                           
        "_source": {                                                                                                              
          "@timestamp": "2015-10-22T03:23:18+00:00",                                                                              
          "forward": "-",                                                                                                         
          "agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36",
                                                                                                                                  
          "remote": "192.168.33.1",                                                                                               
          "host": "-",                                                                                                            
          "user": "-",                                                                                                            
          "method": "GET",                                                                                                        
          "path": "/poweredby.png",                                                                                               
          "code": "304",                                                                                                          
          "size": "0",                                                                                                            
          "referer": "http://192.168.33.41/"                                                                                      
        },                                                                                                                        
        "_score": 1,                                                                                                              
        "_id": "AVCNkn50wKctAXIQgGZn",                                                                                            
        "_type": "nginx_access_log",                                                                                              
        "_index": "nginx_access_log-201510"

(一部抜粋)
ElasticSearchに保存できていることが確認できました。

5. Kibanaのインストール [対象:node1]
Kibana: Explore, Visualize, Discover Data | Elastic

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

$ sudo yum install wget
$ wget https://download.elastic.co/kibana/kibana/kibana-4.1.1-linux-x64.tar.gz
$ tar xvfz kibana-4.1.1-linux-x64.tar.gz
$ sudo mkdir /opt/kibana
$ sudo tar xvfz kibana-4.1.1-linux-x64.tar.gz -C /opt/kibana --strip-components 1

kibana4にはHTTPサーバーの機能があります。以下のコマンドで起動できます。

$ /opt/kibana/bin/kibana

http://[node1のIPアドレス]:5601/ でアクセスしてみて、表示されるか確認します。

kibanaは主に4つの操作に分かれています。

Discover - 必要なデータを検索、発見する
Visualize - データの可視化を行う
Dashboard - 可視化したグラフをダッシュボードにまとめる
Settings - インデックスの設定を行う

最初にSettingsでインデックスを設定します。設定の仕方は画像を参考にしてください。

f:id:eno0514:20151104022948p:plain
f:id:eno0514:20151104023004p:plain

今のままだとkibanaを手動で起動させないといけないので、自動起動の設定をします。
起動スクリプトhttps://github.com/Xaway/script/blob/master/init_kibanaを参考にしました。

$ git clone https://github.com/Xaway/script.git
$ sudo chmod g+x script/init_kibana
$ sudo mv script/init_kibana /etc/init.d/kibana
$ sudo chkconfig --add kibana
$ sudo chkconfig kibana on
$ sudo chkconfig --list kibana
$ sudo service kibana start

以上になります。

参考:
【CentOS】Fluentd / Elasticsearch / Kibana環境構築【Nginx】 | FiS Project
Fluentd、ElasticSearch、Kibana4によるログ分析環境の構築 | hrendoh's memo
Kibana 4 BETAファーストインプレッション - Qiita