dstat+td-agent+ElasticSearch+Graphite+Grafana on Amazon Linux

公開日: : 最終更新日:2014/09/03 AWS, サーバ , , , , , ,

タイトルが異様に長いけど、業務でタイトルのようなパフォーマンス監視環境を作った。
難易度はそんなに高くないが、色々とインストールして設定しなくてはならないので、手順をまとめてみた。

環境としては、EC2のサーバでWebとかApplicationとか動かしていて、RDSでMySQLを稼働させていることを想定。

また、RDSはCloudWatchで監視されていることも合わせて想定している。

ちなみに、今回は環境作成はEC2のインスタンスで、Amazon LinuxのAMIを選択し、起動した状態からの開始を想定している。

MySQLのインストールと起動

yumでインストール。

$ sudo yum install mysql mysql-server MySQL-python

MySQLのインストールが完了したらMySQLの設定をする。
まずは自動起動を設定し、MySQLデーモンを起動する。

$ sudo chkconfig mysqld on
$ sudo service mysqld start

次に初期設定。
ウィザード形式で色々聞かれるので、適当に。

$ sudo /usr/bin/mysql_secure_installation

初期設定が完了したら、graphite用のユーザを作成する。

$ mysql -u root -p -e "GRANT ALL PRIVILEGES ON graphite.* TO '<ユーザ>'@'localhost' IDENTIFIED BY '<パスワード>';"
$ mysql -u root -p -e "CREATE DATABASE graphite;"
$ mysql -u root -p -e "flush privileges;"

まとめられるけど、わかりやすくするために別コマンドで実行しています・・・

graphiteのインストール

epelリポジトリにパッケージがあるので、それを利用する。

$ sudo yum --enablerepo=epel install graphite-web graphite-web-selinux python-carbon

graphiteの設定を行う。
「<User>」と「<Pass>」はMySQLで作成したユーザとパスワード。

$ cat <<EOL | sudo tee -a /etc/graphite-web/local_settings.py
TIME_ZONE = 'Asia/Tokyo'
DATABASES = {
  'default': {
    'NAME': 'graphite',
    'ENGINE': 'django.db.backends.mysql',
    'USER': '<User>',
    'PASSWORD': '<Pass>',
    'HOST': 'localhost',
    'PORT': '3306',
  }
}
EOL

Carbonストレージサービスの設定と起動

今回はyumでインストールしているので/var/lib/carbon/以下が監視データの保存先となる

$ sudo vi /etc/carbon/storage-schemas.conf

一通り設定を確認したら、以下のdstat用の設定を一番上にでも追加しておく(1分間隔データを1年分保持)

[dstat]
pattern = ^dstat\.
retentions = 60s:365d

設定が完了したら、デーモンの起動設定をして、デーモンを起動する。

$ sudo service carbon-cache start
$ sudo chkconfig carbon-cache on

ElasticSearchのインストール

graphanaはkibana派生なので、今のところdashboardの設定保存等にElasticSearchを使うので、ElasticSearchをインストールする。

$ sudo rpm -ivh https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.2.1.noarch.rpm

上記ではVer1.2.1をインストールしているが、バージョンはその時の状況にあわせてHPで確認しておくこと。
ElasticSearchもデーモンの起動設定をして、起動しておく。

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

graphite初期設定

graphiteで必要なものは一通りインストールできたので、graphiteの設定を行う。
といっても、、、

$ sudo /usr/lib/python2.6/site-packages/graphite/manage.py syncdb

と実行するだけで、MySQLにテーブル作ってくれたりする。

grafanaのインストール

パッケージが見つからなかったので、gitで。

$ cd /opt && sudo git clone https://github.com/grafana/grafana.git

特にコンパイルとか必要ないので、設定を行う。

$ sudo cp -fp ./grafana/src/config.sample.js ./grafana/src/config.js

設定ファイルは「config.js」で設定する。
このあたりはkibana派生なのでほぼ同じ。

$ sudo vi ./grafana/src/config.js

データソースの設定内にあるgraphiteのURL及び、elastic searchのURLを環境に合わせて適当に変更する。

url: "http://xxx.xxx.xxx.xxx/gt/",
elasticsearch: "http://xxx.xxx.xxx.xxx/es",

Apacheの設定と起動(graphite-web)

uWSGI+Nginxでも良いけどuWSGIの起動スクリプト作るのが面倒くさい…
yumでgraphiteを入れるとApache HTTPDの設定も付いてくる。
なので、後で変えるだろうけど、今回はgraphiteはそのままApache HTTPD+mod_wsgiで起動することとした。

$ sudo vi /etc/httpd/conf/httpd.conf

以下の2つのディレクティブを環境に合わせて変更する

Listen 8080
ServerName xxx.xxx.xxx.xxx:8080

graphite-webのHTTPDの設定は以下のように。
ServerNameは環境に合わせて適当に設定すること。

$ cat <<EOL | sudo tee /etc/httpd/conf.d/graphite-web.conf
<VirtualHost *:8080>
     Header set Access-Control-Allow-Origin "*"
     Header set Access-Control-Allow-Methods "GET, OPTIONS"
     Header set Access-Control-Allow-Headers "origin, authorization, accept"

     ServerName xxx.xxxxxxx.com

     DocumentRoot "/usr/share/graphite/webapp"
     ErrorLog /var/log/httpd/graphite-web-error.log
     CustomLog /var/log/httpd/graphite-web-access.log common
     Alias /media/ "/usr/lib/python2.6/site-packages/django/contrib/admin/media/"

     WSGIScriptAlias / /usr/share/graphite/graphite-web.wsgi
     WSGIImportScript /usr/share/graphite/graphite-web.wsgi process-group=%{GLOBAL} application-group=%{GLOBAL}

     <Location "/content/">
         SetHandler None
     </Location>
     <Location "/media/">
         SetHandler None
     </Location>

     <Directory /usr/share/graphite/>
         Options All
         AllowOverride All
         Require all granted
     </Directory>
 </VirtualHost>

設定ができたら、HTTPDデーモンの起動設定をして、デーモンを起動する。

$ sudo chkconfig httpd on
$ sudo service httpd restart

Nginxのインストールと設定と起動

graphiteはApache HTTPDにしたけど、無駄にフロント側(grafana)だけはNginxにしてみたw

$ sudo yum install nginx

インストールが終了したら基本設定。

$ cat <<EOL | sudo tee /etc/nginx/nginx.conf
daemon on;
user  root;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
error_log  /var/log/nginx/error.log  warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

上記は、ほぼデフォルトに設定しているが、環境に合わせて変更すること!

次に、監視用のgrafanaのNginxでの設定を行う。
設定ファイル名と、server_nameは環境に合わせて適当に。

$ cat <<EOL | sudo tee /etc/nginx/conf.d/xxxx.xxxxxxx.conf
server {
  listen      80;
  server_name xxxx.xxxxxxx.com;

  auth_basic "Input User and Password.";
  auth_basic_user_file "/etc/nginx/conf.d/.htpasswd";

  location / {
    root  /opt/grafana/src/;
    index index.html;
  }

  location /es/ {
    proxy_pass http://127.0.0.1:9200/;
  }

  location /gt/ {
    proxy_pass_header Authorization;
    proxy_pass http://127.0.0.1:8080/;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }

  location ~ /\.ht {
    deny  all;
  }
}
EOL

ちなみに上記は見ればわかるが、ベーシック認証をかけてある。
認証ファイルは適当に作成して、保存したパスに書き換えるように!
設定が終わったらNginxも起動しておく。

$ sudo chkconfig nginx on
$ sudo service nginx restart

graphinaの稼働確認

さて、ここまでで一通り必要なもののインストールは全て完了し、基本的な設定も全ておわっているはず。
一旦Webページを確認してみる。
スクリーンショット 2014-06-12 12.13.33
上記のように表示されていればOK!
表示されてなければ、それぞれのログやらを確認してみる。
ちなみに、表示されないほとんどの理由はPermission周りなので、そのあたりも確認してみること!

ここまでいったら、あとは監視される側に諸々仕込んでいく。

td-agentのインストール

監視対象となるサーバにはtd-agentを仕込んでおく。

EC2のサーバを想定しているので、Redhat用のスクリプトを実行してtd-agentをインストールする。

$ curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sudo sh

インストールが完了したら必要なPluginをインストールする。
graphite用のpluginはgitからソース取得してインストール。

$ sudo yum install libcurl-devel.x86_64 ruby-devel.noarch
$ sudo yum install gcc.noarch gcc-c++.noarch
$ sudo yum install dstat
$ mkdir ~/work && cd ~/work/
$ git clone https://github.com/hotchpotch/fluent-plugin-graphite.git
$ cd fluent-plugin-graphite/ && /usr/lib64/fluent/ruby/bin/rake
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install pkg/fluent-plugin-graphite-0.2.1.gem
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-map fluent-plugin-dstat

pluginのインストールが完了したら、td-agentの設定をする。

$ cat <<EOL | sudo tee -a /etc/td-agent/td-agent.conf
 <source>
   type dstat
   tag dstat
   option -lcnm
   delay 5
 </source>

 <match dstat>
   type copy
   <store>
     type map
     tag  "map.dstat.loadavg-short"
     time time
     record {"key" => record["hostname"]+".loadavg-short", "gauge" => record["dstat"]["load avg"]["1m"].to_f*100 }
   </store>
   <store>
     type map
     tag  "map.dstat.cpu-usr"
     time time
     record {"key" => record["hostname"]+".cpu-usr", "gauge" => record["dstat"]["total cpu usage"]["usr"] }
   </store>
   <store>
     type map
     tag  "map.dstat.cpu-sys"
     time time
     record {"key" => record["hostname"]+".cpu-sys", "gauge" => record["dstat"]["total cpu usage"]["sys"] }
   </store>
   <store>
     type map
     tag  "map.dstat.cpu-hiq"
     time time
     record {"key" => record["hostname"]+".cpu-hiq", "gauge" => record["dstat"]["total cpu usage"]["hiq"] }
   </store>
   <store>
     type map
     tag  "map.dstat.cpu-siq"
     time time
     record {"key" => record["hostname"]+".cpu-siq", "gauge" => record["dstat"]["total cpu usage"]["siq"] }
   </store>
   <store>
     type map
     tag  "map.dstat.net-recv"
     time time
     record {"key" => record["hostname"]+".net-recv", "gauge" => record["dstat"]["net/total"]["recv"] }
   </store>
   <store>
     type map
     tag  "map.dstat.net-send"
     time time
     record {"key" => record["hostname"]+".net-send", "gauge" => record["dstat"]["net/total"]["send"] }
   </store>
   <store>
     type map
     tag  "map.dstat.mem-used"
     time time
     record {"key" => record["hostname"]+".mem-used", "gauge" => record["dstat"]["memory usage"]["used"] }
   </store>
   <store>
     type map
     tag  "map.dstat.mem-buff"
     time time
     record {"key" => record["hostname"]+".mem-buff", "gauge" => record["dstat"]["memory usage"]["buff"] }
   </store>
   <store>
     type map
     tag  "map.dstat.mem-cach"
     time time
     record {"key" => record["hostname"]+".mem-cach", "gauge" => record["dstat"]["memory usage"]["cach"] }
   </store>
   <store>
     type map
     tag  "map.dstat.mem-free"
     time time
     record {"key" => record["hostname"]+".mem-free", "gauge" => record["dstat"]["memory usage"]["free"] }
   </store>
 </match>

<match map.dstat.*>
  type            graphite
  host            xxx.xxx.xxx.xxx
  port            2003
  key_prefix      dstat
  flush_interval  5s
</match>
EOL

上記のhostはcarbonへの接続になるので、環境に合わせて監視サーバのIPに変えること!

設定が完了したら、デーモンの起動設定を行い、デーモンを起動する。

$ sudo service td-agent configtest
$ sudo service td-agent start

ここまで設定すれば、パフォーマンス状況がどんどんと蓄積されていく。

監視サーバにもtd-agentを準備

CloudWatchからのデータの読み込みに今回は、監視用のサーバをそのまま利用する。

ということで、監視サーバにもtd-agentをインストールする。

インストール手順は前記と同様に。

$ curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sudo sh

インストールが完了したら必要なPluginをインストールする。

$ sudo /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-cloudwatch --no-ri --no-rdoc
$ sudo /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-graphite --no-ri --no-rdoc

pluginのインストールが完了したらtd-agentの設定を行う。

ファイル名は適当に。

$ sudo mkdir /etd/td-agent/conf.d
 cat <<EOL | sudo tee /etc/td-agent/td-agent.conf
 include conf.d/aws-rds.database.conf
 EOL

上でインクルードしたファイルの中身はこんな感じで。

$ cat <<EOL | sudo tee /etc/td-agent/conf.d/aws-rds.database.conf
 <source>
   type        cloudwatch
   tag         cloudwatch.rds.database
   aws_key_id  <アクセスキー>
   aws_sec_key <シークレットキー>
   cw_endpoint <span style="text-decoration: underline;">monitoring.ap-northeast-1.amazonaws.com</span>
   namespace   AWS/RDS
   metric_name BinLogDiskUsage,CPUUtilization,DatabaseConnections,DiskQueueDepth,FreeStorageSpace,FreeableMemory,NetworkReceiveThroughput,NetworkTransmitThroughput,ReadIOPS,ReadLatency,ReadThroughput,SwapUsage,WriteIOPS,WriteLatency,WriteThroughput
   dimensions_name DBInstanceIdentifier
   dimensions_value <RDSインスタンスID>
   period      180
   interval    180
 </source>

 <match cloudwatch.rds.database.**>
   type copy
   <store>
     type file
     path /var/log/td-agent/cloudwatch.database
   </store>
   <store>
     type      graphite
     host      localhost
     port      2003
     tag_for   prefix
     name_keys BinLogDiskUsage,CPUUtilization,DatabaseConnections,DiskQueueDepth,FreeStorageSpace,FreeableMemory,NetworkReceiveThroughput,NetworkTransmitThroughput,ReadIOPS,ReadLatency,ReadThroughput,SwapUsage,WriteIOPS,WriteLatency,WriteThroughput
   </store>
 </match>
 EOL

ちなみに、hostは監視サーバとCloudWatchからのデータ読み込みに同じサーバを想定しているので、localhostを設定している。

環境に合わせて適時変えること!

また、cw_endpointで設定しているEndPointやmetric_nameとname_keysで指定しているMetricについてはここで確認して環境にあわせて設定すること。

更に、上記の場合はRDSの単一インスタンスを対象としているが、他にも対象がある場合は同じような設定を追加していく。

監視対象毎に上記のようなファイルを作って、メインの設定ファイル「td-agent.conf」でIncludeするようにするのが分かり易いか…

設定が完了したらtd-agentを起動!

$ sudo service td-agent configtest
$ sudo service td-agent start

最終確認

あとは、grafanaの設定をポチポチと設定していく。

grafanaの設定手順はGUIで簡単なので省略。

ちなみに、こんな感じで今回は作成してみた。

EC2インスタンスで立ち上がっているWebとかAPサーバのdstatをプロットさせた場合はこんな感じ。

スクリーンショット 2014-06-12 14.45.06

設定のポイントはいくつかあるが、LoadAverageはScaleで0.01倍に。

次にCloudWatchからデータを持ってきているRDSのDBについてはこんな感じ。

スクリーンショット 2014-06-12 14.51.16

また、RDSではなく、CloudWatchのElastiCacheのパフォーマンス状況をプロットさせた場合はこんな感じ。

スクリーンショット 2014-06-12 14.56.16

まとめ

適当に関連しそうな情報をまとめて、比較的簡単にDashboardとして作ることが出来た。

インストールするべきものが沢山あるが、パッケージが用意されているものがほとんどなので、苦労もほとんど無い。

あと、気がついている人も沢山いると思うが、上記手順内では「fluent-plugin-graphite」だけ2つの実装の違うpluginを利用している。

同じ名前なので、どちらを使った場合であっても問題はないが、今回は例として両方を使ってみた。

実運用では同じものを使ったほうが良いのは当たり前なので、揃えて導入することをオススメするが、設定内容にはそれぞれ違いがあるので、選んだほうのドキュメントなりを読んで正しい設定にすることは言わないでもわかると思う・・・

あと、手順ですっ飛ばしているけど、SecurityGroupの設定は正しく設定すること!

今回の手順通りに作成した場合は、HTTP(80)だけ無条件公開で、あとはLocalnetからの制限を入れて、carbon(2003)とかのポートを開けてあげれば良い。

Adレクタングル[忍者ADMAX]

関連記事

aws_logo._V400518270_

AWSでRoute 53をPrivate DNSとしてVPC内で使ってみた

Amazon Web Services(AWS)のRoute 53がVPC内でのPrivate Ho

記事を読む

nginx_logo

ngx_pagespeed対応版nginxパッケージの作成(RHEL系)

インストールされているミドルウェアやアプリケーションはパッケージ化されていると、管理上において非常に

記事を読む

RabbitMQ.sh-600x600

EC2上のRabbitMQをMulti-AZで冗長化

うーん。。。ハマった。 多分、もっとErlangのこと把握できていればよかったのだろうけど。

記事を読む

nginx_logo

NginxでのOCSP Stapling対応設定

意外にハマったのでメモ。 OCSPとは OCSP(Online Certificate Stat

記事を読む

nginx_logo

NginxでのSSL設定(もうちょっと詳しく)

単に、 とするだけではなくて…というエントリ。 ちなみにRHEL系を想定して書いている。 ngin

記事を読む

コメントを残す

Adレクタングル[忍者ADMAX]

RabbitMQ.sh-600x600
EC2上のRabbitMQをMulti-AZで冗長化

うーん。。。ハマった。 多分、もっとErlangのこと把握できていれ

aws_logo._V400518270_
AWSでRoute 53をPrivate DNSとしてVPC内で使ってみた

Amazon Web Services(AWS)のRoute 53がV

nginx_logo
NginxでのSSL設定(もうちょっと詳しく)

単に、 とするだけではなくて…というエントリ。 ちなみにRHEL系を

→もっと見る

  • Author:
    hiro
    Work:
    インフラエンジニア
    Brief History:
    新卒後、ソフトハウスにて受託開発を中心に開発エンジニアを始める。
    数年前から現在はITインフラが専門。
PAGE TOP ↑