Elasticsearch+Kibanaでサーバメトリクスの可視化をする
October 10, 2018
はじめに
サーバの運用監視といえばMackerelだったり、DataDogなりのSaasを使って綺麗に可視化したいものです。 が、仕事だと外部サービス使わせてもらえないので、ElasticsearchとKibanaを使ってオンプレでも可視化する方法を調べました。 Elasticsearch+Kibana+Fluentd+dstatは既に色々記事があるのですが、古めの記事が多く、そのままやってもうまく動かなかったため、2018/10時点で動作した方法をまとめます。
完成イメージとしてはこんな感じです
環境
- サーバ
- AWSインスタンス×2 (監視サーバと監視対象)
- Amazon Linux 2 AMI
- t2.medium
- AWSインスタンス×2 (監視サーバと監視対象)
- 各サービスのバージョン
- Docker - 18.06.1-ce
- docker-compose - 1.22.0
- Fluentd - v1.0 (td-agent3)
- Elasticsearch - 6.4.1
- Kibana - 6.4.1
監視サーバの構築
まず監視サーバの構築を行います
Docker, docker-composeインストール
ElasticsearchとKibanaはdocker-composeで動かすためDockerを入れます
// インストール
$ sudo yum install docker-ce
// デーモン起動
$ sudo service docker start
// 一般ユーザーでも使えるようにdockerグループに所属させる
$ sudo usermod -a -G docker ec2-user
// 一度ログアウトしてから再度ログインすれば反映される
$ sudo service docker restart
$ exit
// 確認
$ docker version
Client:
Version: 18.06.1-ce
API version: 1.38
Go version: go1.10.3
Git commit: e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
Built: Wed Sep 5 18:57:40 2018
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.06.1-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: e68fc7a/18.06.1-ce
Built: Wed Sep 5 18:59:05 2018
OS/Arch: linux/amd64
Experimental: false
// docker-composeのインストール
// https://github.com/docker/compose/blob/master/CHANGELOG.md 最新を確認してインストール
$ sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
// 確認
$ docker-compose version
docker-compose version 1.22.0, build f46880fe
docker-py version: 3.4.1
CPython version: 3.6.6
OpenSSL version: OpenSSL 1.1.0f 25 May 2017
Elasticsearch+Kibanaのインストール
適当なディレクトリを作って、docker-compose.ymlとesdataというフォルダを掘ります
$ tree
.
|-- docker-compose.yml
`-- esdata
// また事前にElasticsearch用に以下を設定しておく
// メモリマップの上限値を上げておく
$ sudo sysctl -w vm.max_map_count=262144
// ulimitの上限あげ
$ sudo su
## ulimit -n 65536
## exit
version: '3.7'
services:
elasticsearch:
## https://hub.docker.com/_/elasticsearch/
image: docker.elastic.co/elasticsearch/elasticsearch:6.4.1
volumes:
- ./esdata:/usr/share/elasticsearch/data
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
nofile:
soft: 65536
hard: 65536
ports:
- 9200:9200
- 9300:9300
networks:
- esnet
kibana:
## https://hub.docker.com/_/kibana/
image: docker.elastic.co/kibana/kibana:6.4.1
ports:
- 5601:5601
environment:
ELASTICSEARCH_URL: "http://elasticsearch:9200"
links:
- elasticsearch
networks:
- esnet
networks:
esnet:
$ ls
docker-compose.yml esdata
$ docker-compose up -d
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------------
elastickibana_elasticsearch_1 /usr/local/bin/docker-entr ... Up 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp
elastickibana_kibana_1 /usr/local/bin/kibana-docker Up 0.0.0.0:5601->5601/tcp
確認
$ curl <監視サーバのホスト名>:9200
{
"name" : "oTmpxcX",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "f0L7EvzcTZeJA9OPsSVCUg",
"version" : {
"number" : "6.4.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "e36acdb",
"build_date" : "2018-09-13T22:18:07.696808Z",
"build_snapshot" : false,
"lucene_version" : "7.4.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
Kibana確認 ブラウザでhttp://<監視サーバのホスト名>:5601へアクセス こんな感じの画面が見れれば一旦おk
監視サーバでの作業は一旦ここまでになります. 次に監視対象サーバでメトリクスの出力とfluentdの設定を行います。
監視対象サーバの構築
監視対象サーバではdstatを使ってサーバメトリクスを取得し、それをfluentdでElasticsearchに送ります
dstatの準備
$ sudo yum install dstat
$ dstat -cdlnmpr 3
----total-cpu-usage---- -dsk/total- ---load-avg--- -net/total- ------memory-usage----- ---procs--- --io/total-
usr sys idl wai hiq siq| read writ| 1m 5m 15m | recv send| used buff cach free|run blk new| read writ
6 1 93 0 0 0| 99k 1460k| 0 0.05 0.17| 0 0 |1417M 2088k 1382M 1145M| 0 0 10|5.82 18.6
0 0 100 0 0 0| 0 0 | 0 0.05 0.17|1657B 2323B|1417M 2088k 1382M 1145M| 0 0 0| 0 0
1 0 99 0 0 0| 0 181k| 0 0.05 0.17|2236B 3058B|1418M 2088k 1382M 1143M| 0 0 0.7| 0 38.7
3秒ごとにCPU, ディスク, ロードアベレージ, ネットワーク, メモリ, プロセス, IOのメトリクスを出すオプションにしています。 オプションはdstat -h
で確認して必要な情報あればそれを出すようにしましょう
fluentdインストール
サービスとしてはtd-agentという名前です
公式ページを参考に
$ curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent3.sh | sh
// td-agent, td-agent-gemコマンドが使えるようになり, サービスも登録される
$ sudo systemctl status td-agent
● td-agent.service - td-agent: Fluentd based data collector for Treasure Data
Loaded: loaded (/usr/lib/systemd/system/td-agent.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: https://docs.treasuredata.com/articles/td-agent
プラグインのインストール
次のプラグインをインストールする
プラグイン名 | 説明 |
---|---|
fluent-plugin-dstat | dstatをfluentdのsourceにできる |
fluent-plugin-elasticsearch | fluendからelasticsearchにデータを送れる |
fluent-plugin-filter_typecast | 型変換を行う(※後述) |
fluent-plugin-filter-object-flatten | ネストしたデータ構造を展開して、処理しやすくするのに使う |
// td-agent-gemコマンドでインストールする
$ sudo td-agent-gem install fluent-plugin-dstat fluent-plugin-elasticsearch fluent-plugin-filter_typecast fluent-plugin-filter-object-flatten
設定確認
とりあえずdstatをfluentdで取り込んで、標準出力に出して確認してみましょう
<source>
@type dstat
tag dstat
option -cnm
delay 3
</source>
<match dstat>
@type stdout
</match>
$ td-agent -c fluent.conf
...
2018-10-09 15:40:05.237184928 +0000 dstat: {"hostname":"ip-172-31-26-80.ap-northeast-1.compute.internal","dstat":{"total_cpu_usage":{"usr":"0.203","sys":"0.120","idl":"99.644","wai":"0.031","hiq":"0.0","siq":"0.001"},"net/total":{"recv":"0.0","send":"0.0"},"memory_usage":{"used":"199806976.0","buff":"2138112.0","cach":"463761408.0","free":"3471278080.0"}}}
2018-10-09 15:40:05.237376395 +0000 dstat: {"hostname":"ip-172-31-26-80.ap-northeast-1.compute.internal","dstat":{"total_cpu_usage":{"usr":"0.0","sys":"0.166","idl":"99.834","wai":"0.0","hiq":"0.0","siq":"0.0"},"net/total":{"recv":"126.667","send":"105.333"},"memory_usage":{"used":"198103040.0","buff":"2138112.0","cach":"463761408.0","free":"3472982016.0"}}}
出力を見ると問題が2つあります。1つはデータの型がすべて文字列になっていることです。fluentdでは基本的に値は文字列で出すらしい。 Elasticsearch+Kibanaに突っ込んで可視化する際, 時系列グラフにできるのはNumericな型のみなので、型変換が必要
また、キーに/
などの処理しづらい文字が入っていたり、ネストされており、このままじゃ扱いづらいので、これらもflatten_mapで処理しやすくする
<source>
@type dstat
tag dstat
option -cnm
delay 3
</source>
<filter **>
@type object_flatten
tr [" /", "__"]
</filter>
<filter **>
@type typecast
types dstat.total_cpu_usage.usr:float,dstat.total_cpu_usage.sys:float,dstat.total_cpu_usage.idl:float,dstat.total_cpu_usage.wai:float,dstat.total_cpu_usage.hiq:float,dstat.total_cpu_usage.siq:float,dstat.net_total.recv:float,dstat.net_total.send:float,dstat.memory_usage.used:float,dstat.memory_usage.buff:float,dstat.memory_usage.cach:float,dstat.memory_usage.free:float
</filter>
<match dstat>
@type stdout
</match>
2018-10-09 16:00:03.369963227 +0000 dstat: {"hostname":"ip-172-31-26-80.ap-northeast-1.compute.internal"}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.total_cpu_usage.usr":0.209}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.total_cpu_usage.sys":0.107}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.total_cpu_usage.idl":99.657}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.total_cpu_usage.wai":0.027}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.total_cpu_usage.hiq":0.0}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.total_cpu_usage.siq":0.001}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.net_total.recv":0.0}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.net_total.send":0.0}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.memory_usage.used":200888320.0}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.memory_usage.buff":2138112.0}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.memory_usage.cach":464175104.0}
2018-10-09 16:00:03.369963227 +0000 dstat: {"dstat.memory_usage.free":3469783040.0}
ちゃんと型変換されて、ネストも解消されている.
Elasticsearchへ送る
fluent.confを編集して、Elasticsearchへ送るようにする
- <match dstat>
- @type stdout
- </match>
+ <match dstat>
+ @type elasticsearch
+ host <監視サーバのホスト名>
+ port 9200
+ index_name dstat
+ logstash_format true
+ logstash_prefix dstat
+ type_name dstat
+ flush_interval 5
+ </match>
これで起動して問題なければ、デーモン化にしておきましょう
$ cd /etc/td-agent
// バックアップ
$ mv td-agent.conf td-agent.conf.bak
// ↑で作ったfluent.confを持ってくる
$ sudo mv ~/fluent/fluent.conf td-agent.conf
// サービス起動
$ sudo systemctl start td-agent
$ $ sudo systemctl status td-agent
● td-agent.service - td-agent: Fluentd based data collector for Treasure Data
Loaded: loaded (/usr/lib/systemd/system/td-agent.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2018-10-09 16:11:27 UTC; 37s ago
Kibanaの設定
最後にKibanaで可視化をしていきます。 上のfluentdでうまく送れていたら、新たなインデックスができているはずです.
インデックスパターンの作成
まずはインデックスパターンを作成します
http://<監視サーバのホスト名>:5601/app/kibana#/management/kibana/index?_g=()
にアクセスしてみましょう
下のようにdstat-YYYY.MM.DD
の候補があればおkです。
上のようになっていれば
- Index patternに
dstat-*
を入れて、Next Step - Time Filter field nameに
@timestamp
を選択してCreate Index Patternをします
ヴィジュアライズ作成
それでは基本的な時系列グラフをつくってみます。 例としてネットワークのrecv,sendを時系列グラフにしてみます. 下へアクセスします http://<監視サーバのホスト名>:5601/app/kibana#/visualize?_g=()
- Create a visualizationをクリックし
- Areaを選択します
- dstat-*を選択すると、グラフ画面が表示されます.
次にグラフの設定をしてきましょう
- まずはX軸を設定しますBucketsのX-Axisを選択しAggregationで
Date Histogram
を選択します(Field, Intervalはデフォでいいです) - Y-Axis Count 左の三角ボタンを押して、Aggregationで
Average
, Fieldをdstat.net_total.recv
に変更します - さらにAdd metricsボタンを押して、Y-Axis, Aggregationで
Average
, Fieldをdstat.net_total.send
で追加します
この状態で上の青い再生ボタン(Apply Changesボタン)を押すと下のような画面になるはずです
おkであれば上のSaveタブで保存しておきましょう
こんな感じで、いろいろグラフが作れます. Visualizeをいろいろ作って、Dashboard画面でまとめて見ることも可能です(冒頭のスクショのような