Help us understand the problem. What is going on with this article?

Elasticsearch+Kibanaでサーバメトリクスの可視化をする

はじめに

サーバの運用監視といえばMackerelだったり、DataDogなりのSaasを使って綺麗に可視化したいものです。
が、仕事だと外部サービス使わせてもらえないので、ElasticsearchとKibanaを使ってオンプレでも可視化する方法を調べました。
Elasticsearch+Kibana+Fluentd+dstatは既に色々記事があるのですが、古めの記事が多く、そのままやってもうまく動かなかったため、2018/10時点で動作した方法をまとめます。

完成イメージとしてはこんな感じです

環境

  • サーバ
    • AWSインスタンス×2 (監視サーバと監視対象)
    • Amazon Linux 2 AMI
    • t2.medium
  • 各サービスのバージョン
    • 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
docker-compose.yml
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

確認

Elasticsearch確認.
$ 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で取り込んで、標準出力に出して確認してみましょう

fluent.conf
<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で処理しやすくする

fluent.conf(変更後)
<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です。
画像
上のようになっていれば

  1. Index patternにdstat-*を入れて、Next Step
  2. Time Filter field nameに@timestampを選択してCreate Index Patternをします

ヴィジュアライズ作成

それでは基本的な時系列グラフをつくってみます。
例としてネットワークのrecv,sendを時系列グラフにしてみます.
下へアクセスします
http://<監視サーバのホスト名>:5601/app/kibana#/visualize?_g=()

  1. Create a visualizationをクリックし
  2. Areaを選択します
  3. dstat-*を選択すると、グラフ画面が表示されます.

画像

次にグラフの設定をしてきましょう
1. まずはX軸を設定しますBucketsのX-Axisを選択しAggregationでDate Histogramを選択します(Field, Intervalはデフォでいいです)
2. Y-Axis Count 左の三角ボタンを押して、AggregationでAverage, Fieldをdstat.net_total.recvに変更します
3. さらにAdd metricsボタンを押して、Y-Axis, AggregationでAverage, Fieldをdstat.net_total.sendで追加します

この状態で上の青い再生ボタン(Apply Changesボタン)を押すと下のような画面になるはずです
画像

おkであれば上のSaveタブで保存しておきましょう
画像

こんな感じで、いろいろグラフが作れます.
Visualizeをいろいろ作って、Dashboard画面でまとめて見ることも可能です(冒頭のスクショのような

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away