KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

モニタリングルーター Sensu


こんにちは。下田です。寒くなると鍋が食べたくなりますよね。そこで鍋をしたんですが、白菜が余ったので次の日も鍋するために肉やその他の野菜を買って一人鍋をしました。すると、白菜以外の肉や野菜が余ってしまい次の日に白菜を買ってまた一人鍋をしました。気づいたら鍋の永久機関が完成してしまい、完全に鍋ループから抜け出せなくなりました。誰か助けてください。

はい。では、今回は、 Sensu というモニタリングシステムを紹介したいと思います。モニタリングシステムと言いましたが、どちらかと言うとモニタリングルーターと言ったほうがいいかもしれません。何故かというと、UIがデフォルトでは付いてない、通知するシステムも自分で決めてインストールしなきゃいけません。 Sensu がやるのは、あるグループに決まったチェックを定期的に依頼して、その結果を保存するだけです。構成や設定の仕方も ELK に似ていて簡単です。
以下が、 Sensu の構成です。
shimoda02
全てのソフトウェア郡は横にスケールすることが出来ます。モニタリングシステムが重すぎて使えねぇといったことも無さそうですね。 Redis に監視対象からのチェック結果を保存しています。 Sensu と 監視対象のやり取りは全て RabbitMQ 経由になりますので、監視対象側に設定しなきゃいけない情報は、自分の名前とアドレス、所属グループ、 RabbitMQ の接続情報だけとなります。ちなみに Dashboard アプリの名前が uchiwa なのですが、画像がなかったのでそれに近い画像を拝借しています。

では、 CentOS7 に erlang, rabbitmq, redis, sensu を入れていこうと思います。 erlang は、 rabbitmq が使うのでインストールします。

# erlang
sudo yum install epel-release
sudo yum install erlang

# rabbitmq
sudo rpm --import https://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo rpm -Uvh https://www.rabbitmq.com/releases/rabbitmq-server/v3.5.7/rabbitmq-server-3.5.7-1.noarch.rpm
sudo systemctl enable rabbitmq-server
sudo systemctl start rabbitmq-server
sudo rabbitmqctl add_vhost /sensu
sudo rabbitmqctl add_user sensu secret
sudo rabbitmqctl set_permissions -p /sensu sensu ".*" ".*" ".*"

# redis
sudo yum install redis
sudo systemctl enable redis
sudo systemctl start redis

# sensu
echo '[sensu]
name=sensu
baseurl=http://repositories.sensuapp.org/yum/$basearch/
gpgcheck=0
enabled=1' | sudo tee /etc/yum.repos.d/sensu.repo

sudo yum install sensu

まずは、これで、必要なソフトウェアのインストールは終わりです。あとは、 /etc/sensu にある設定ファイルを弄っていきます。
一つ目は、 /etc/sensu/config.json で、sensu サーバー のみ rabbitmq, redis の接続先情報を記載します。監視対象側は、 rabbitmq だけ記載します。今回は API も同じサーバーに載せます。

{
  "rabbitmq": {
    "host": "localhost",
    "vhost": "/sensu",
    "user": "sensu",
    "password": "secret"
  },
  "redis": {
    "host": "localhost"
  },
  "api": {
    "host": "localhost",
    "port": 4567
  }
}

二つ目は、監視項目の定義です。今回は、ディスク、メモリ、負荷の3つを監視項目としたいと思います。 /etc/sensu/conf.d/check_basic.json というファイルを用意します。ここで設定した項目が RabbitMQ に乗ってマルチキャストされます。同じグループに所属する監視対象に通知が行き、実行され同じように結果が RabbitMQ に乗ってサーバーへ戻ってきます。ここで使うプラグインは、既に Sensu の plugin リポジトリにあるものを使っていますが、自分で組むことも可能です。 Sensu に伝える手段として終了コードを用いるのでどの言語でも実装可能です。ちなみに、 0=>OK, 1=>WARNING, 2=>CRITICAL, 3=>UNKNOWN となります。実はこの仕様は、 Nagios と同じなので、Nagios のプラグインが使えます。(完全互換かどうかは実装次第ですが)

{
  "checks": {
    "disk": {
      "command": "check-disk-usage.rb -w 80 -c 95",
      "interval": 600,
      "subscribers": [
        "basic"
      ]
    },
    "load": {
      "command": "check-load.rb",
      "interval": 600,
      "subscribers": [
        "basic"
      ]
    },
    "memory": {
      "command": "check-memory.rb -w 75 -c 90",
      "interval": 600,
      "subscribers": [
        "basic"
      ]
    }
  }
}

何となく見るだけで分かりますね。定期的にチェックしてしきい値を超えると WARNING, CRITICAL になる感じです。この command というところに書いてる ruby らしきファイルは、 Sensu plugin なので、クライアント側(監視対象)に予めインストールする必要があります。(後述)

三つ目は、アラートの設定です。 /etc/sensu/conf.d/default_handler.json というファイルを用意します。エラーが出てたらメールを送信したいと思います。最近の流行りだと、 IRC, slack, hipchat, pagerduty, jira なんかに通知設定をする方が多いようです。

{
  "handlers": {
    "default": {
      "type": "set",
      "handlers": ["cat", "mail"]
    },
    "cat": {
      "type": "pipe",
      "command": "cat"
    },
    "mail": {
      "type": "pipe",
      "command": "handler-mailer.rb",
      "severities": ["warning", "critical", "unknown"]
    }
  }
}

四つ目は、メール送信サーバーや送信先を設定します。 /etc/sensu/conf.d/mailer.json というファイルを用意します。

{
 "mailer": {
   "mail_from": "sensu@example.com",
   "mail_to": "mon@example.com ",
   "smtp_address": "localhost",
   "smtp_port": "25",
   "smtp_domain": "example.com "
 }
}

メール送信は、 Sensu plugin なので、sensu-install コマンドを使ってインストールします。

sudo sensu-install -p mailer:0.1.1

五つ目は、クライアントの設定です。 Sensu は、サーバーにもなれますし、クライアントにもなれます。まずは、/etc/sensu/conf.d/client.json というファイルを用意します。

{
  "client": {
    "name": "sensu-server",
    "address": "localhost",
    "subscriptions": [
      "basic"
    ]
  }
}

このクライアントは、 basic というグループに入っています。よって、先ほど basic に設定した監視項目のディスク、メモリ、負荷のチェックがクライアント側で実行されますので、そのプラグイン郡をインストールします。ちなみに c++ などが入っていないとコケてしまうので、予めインストールしておきましょう。

sudo sensu-install -p disk-checks:1.1.2
sudo sensu-install -p load-checks:0.0.4
sudo sensu-install -p memory-checks:0.0.7

これで、設定は完了です。流石にサーバー側の設定は多いですが、クライアント側の設定は、本当に少なかったですね。あとは、 /etc/sensu のオーナーを sensu に変更と、サーバーとクライアントを起動して、Boot 時の設定を入れれば終わりです。

sudo chown -R sensu:sensu /etc/sensu

# sensuserver
sudo chkconfig sensu-server on
sudo chkconfig sensu-api on
sudo systemctl start sensu-server
sudo systemctl start sensu-api

# sensu client
sudo chkconfig sensu-client on
sudo systemctl start sensu-client

試しに、ディスクが over 20% なら warning っていうテストを行った時に来た通知はこんな感じになります。

Subject:
ALERT - localhost/disk: WARNING

Body:
CheckDisk WARNING: / 33.71% bytes usage (32 GiB/96 GiB)

Admin GUI: http://localhost:8080/
Host: localhost
Timestamp: 2015-12-20 01:55:59 +0900
Address:  localhost
Check Name:  disk
Command:  check-disk-usage.rb -w 20 -c 95
Status:  WARNING
Occurrences:  1

いかがでしょうか。これでサーバーが増えたとしても、 サーバー側の設定は何も変更すること無く、監視対象を増やすことが出来ます。また、全てがスケールするので、大規模なサービスでの利用も耐えられるような設計となっています。自分はまだ7台くらいしか管理してないので、monolithic な構成ですが。。。 Sensu の良い所は、スモールスタートの監視や、大きくなったとしてもスケールするしカスタマイズ出来る、さらには、 Nagios plugin の恩恵も得られるところだと思いますので、興味があれば使ってみてください。

【関連記事】
Splunkに株価を取り込んでみた ft. Fujikawa
Introduction to Antlr!
Introduction to Antlr! Pt.2
JavaPoetで簡単コード生成!
Introduction to Antlr! Pt.3