データベースが落ち着いているので、その間に別のことに着手。
チームの監視システムがmonっつー超レガシーシステム。知っている人もいるかもしれないが、monはperl製のシンプルな監視システム。古くからあるものなんだけど「mon perl」で検索すると「もしかして: man perl」とgoogle様にも何だっけソレ?と言われてしまうかわいそうな奴(「mon monitoring tool」だとちゃんと出てくる)。なのでまあこの際だから俺が葬り去ってやる。導入したSensuのバージョンは0.12.6。GW前くらいから運用しているが今んとこ問題ない。まだ運用期間短いね。



割と長文になっちまったので、目次をば。

  • 0. sensu概要
  • 1. なぜsensu?
  • 2. インストール
  • 3. コンフィグの配置
  • 4. プラグインについて
  • 5. API
  • 6. デバッグ
  • 7. 今後の展望
0. sensu概要

Sensuって何なのって話だが、コレ、ね。An open source monitoring framework.と書かれている名の通り、オールインワンの監視システムではなく、監視の閾値チェックも通知の仕組みもプラガブルになっていて、利用者任せになっている。プラグイン扱いとなっているとはいえ、メール通知やCPU監視などよくありがちなものはコミュニティプラグインとして提供されていて、その資産を使うこともできる。sensu本体もコミュニティプラグインもgithubにホスティングされているので、自作のプラグインを書いた場合はpull requestを送ると取り込んでもらえる場合もある。
sensuのデプロイイメージは↓のようになっている。

sensu_01

Monitering Serverは図で示すコンポーネントで構成され、プロセスはredis, sensu-api, sensu-server, rabbitmq-server, sensu-dashboardを起動する必要がある。図では全コンポーネントを同じ箱の中に配置しているが、別の箱にあっても良い。一旦は同じ箱の中に全部置いときゃいいだろう。


  • redis: クライアントの情報やアラートの履歴が格納されている。
  • Sensu API: REST API。このAPI経由でアラートを止めたりするなどいろいろ操作できる。後述するDashboardやSensu AdminのようなGUIはこのAPI経由で情報を取得している。
  • RabbitMQ: 監視サーバと監視対象ノードとのやりとりはこのRabbitMQを経由したメッセージングで行われる。
  • Sensu Server: RabbitMQ経由で送られてきたクライアントの情報をもとに、アラート通知(メール, IRC, hipchat…etc)を行う。
  • Dashboard: GUIを提供する。APIをつついて情報を取得している。このデフォルトのGUIの他にもSensu Adminなるものがある。俺はSensu Adminを使っている。
監視対象ノード(Node)にはSensu Clientのみが入っていて、起動するプロセスもsensu-clientのみで良い。監視対象ノードは自分自身のローカルに置かれたプラグインを使用して自分で自分の状態を監視し、その結果をRabbitMQに通知する仕組み。

1. なぜsensu?

monは”異常を検知してアラートを飛ばす”という、監視システムとして必要最低限の動きはしてくれているのでそこは良い。monと比べて、という枕詞付きになるが、次の点がmonの不満でありsensuが俺の担当サービスに適していると考えた。
  • Sensuはサーバのロール変化、増減に対応しやすい(monは面倒)
    • チームではサーバ数の増減や、サーバの転用がよく発生する。monのように中央管理型(という言葉はないと思うが)の監視システムだと、サーバが増えたらmonのコンフィグに追記する、サーバの役割が変わったら、もとの設定を削除して新しい設定に書き換える…などとする必要がある。とにかく面倒。mon.cfが長くて見にくい。監視漏れとかもたま発生する。sensuの場合はagent(sensu-client)を起動すれば、サーバの役割に応じた勝手に監視が始まる。ただ、監視対象ノードに確実にsensu-clientをプロビジョニングする仕組み(chef, ansibleなど)があることが前提となる。この仕組みさえあればSensuは非常に楽。
  • APIがある(monはない)
    • 俺のチームのローカルルールではあるが、リリース時は、監視を止める→リリースする→監視再開するなどいう作業をするのだが、これが面倒。リリースジョブにSensuのAPIを叩いて監視を止める/再開するような処理を組み込んでおけば、この作業から解放される。
主に前者のポイントはnagiosと比べてもアドバンテージだと思う。zabbixは知らん。サーバの増減や頻繁な再構築が多発するような環境だとsensuの良さが活きると思ってます。そうでも無い場合はnagiosなど現場の担当者が慣れてるやつで良いと思う。現状に不満が無い場合は変える必要は無い。とりあえず、現状の監視システムに不満がある場合は置き換えの候補になり得ますよ、と。

2. インストール

公式ドキュメントにある通りchefでのインストールが楽。公式ドキュメントを参照するのが良いだろう。イギリス語を読みたくない場合は、日本人のブログにも種々の手順が掲載されているのでそちらを参考にすると良い。
俺は自分のマシンから監視サーバ、監視対象ノードともにknife soloで構築した。慣れてる手段でOK。

3. コンフィグ

インストール後にケアすべきコンフィグの一式は次の通り。例をgistに貼付けてあるので参考にどうぞ。設定ファイルの中身の各項目の説明はこちらのエントリがわかりやすい →「Sensuの監視の設定」。なお、下記において「★」マークをつけたポイントは個人的な考慮ポイント。
  • サーバ側
    • /etc/sensu/config.json
      • 鯖自身の情報: config.json
      • RabbitMQ, Redis, APIのIPやポート等を設定する。sensu-dashboardを使う場合はその設定も。
    • /etc/sensu/conf.d/check.json
      • 監視項目: check.json
      • ファイル名をcheck.jsonとしているが、ファイル名自体は.jsonであればなんでも良い。checks要素は必ず存在する必要がある。そして、その下の階層のsnmpd_proc/ntpd_proc/sshd_procは一意である必要がある。
      • ★refresh: 例だと、180(sec)にしてあるが、これを設定しておくと一度アラートが鳴ったら、180秒間隔でアラートを鳴らし続けてくれる。この設定が無いと、一度アラートが鳴ったら、Resolveするまで鳴ってくれない。解決するまでアラートを鳴らし続けたい場合は設定しておくべき。
    • /etc/sensu/conf.d/handler.json
      • ハンドラの指定: handler_mailer.json
      • これもファイル名は何でも良くて、handlers要素は必ず存在する必要がある。んで、同じくその配下は一意である必要がある。
    • /etc/sensu/handler/*
    • /etc/default/sensu
      • sensuのログレベルなど: sensu
      • ★EMBEDDED_RUBY:これはtrueでいいと思う(デフォルトはfalse)。chefでsensuをインストールすると/opt/sensu配下にRubyおよびsensuが使うgemなどがインストールされる。trueの設定はこの/opt/sensu配下のRubyやgemを使うという意味。trueにしない理由は特にないと思うのでtrueでいいと思うよ。
      • ★LOG_LEVEL:デフォルトはinfo。割とログが頻繁に出るので運用始まったらerrorとかでいいんじゃないかな?
  • 監視対象ノード側
    • /etc/sensu/config.json
      • RabbitMQの場所: config.json
      • 監視対象ノード側で設定するのはRabbitMQの場所だけで良い。
    • /etc/sensu/conf.d/client.json
      • 自分自身の情報: client.json
      • 自分自身のホスト名とIP、そしてsubscriptionsを書く。
      • ★keepalive: keepaliveを設定しておくと、sensu-clientが落ちたときにアラート通知をしてくれる。この例は、60秒間sensu-clientが死んでたらcriticalとして扱ってくれる。この設定は入れといた方がいいんじゃないかな。なお、このときに使われるハンドラは「default」の模様。サーバ側のhandler_mailer.json参照。つまり、handlers/mailer.rbが呼ばれて、「sensu-client落ちてるよ!」とメール通知が行われる。
      • ★refresh: 先ほど書いた通り、sensu-clientダウンのアラート通知が行われたあと、ここで指定した秒数が経過するともう一度アラートを通知してくれる。
    • /etc/sensu/plugins/*
      • プラグイン。サーバ側のcheck.jsonで指定してあるプラグインをここに置いておく。上記check.jsonの例だと、check-procs.rbを置いておく必要がある。リンクで示した通り、これもコミュニティプラグインに梱包されている。
    • /etc/default/sensu
      • sensuのログレベルなど。概ねサーバ側と同じで良い。EMBEDDED_RUBYやLOG_LEVELはサーバ側と同じくケアした方がいいと思うよ。
なお、俺の環境の/etc/sensuディレクトリ配下は次のようになっている。

まず、サーバ側。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/etc/sensu
├── conf.d
│   ├── check_cpu.json
│   ├── check_disk.json
│   ├── check_http.json
│   ├── check_mem.json
│   ├── check_mysql_state.json
│   ├── check_ntp.json
│   ├── check_port.json
│   ├── check_proc.json
│   ├── check_raid.json
│   ├── check_swap.json
│   ├── client.json
│   ├── handler_default.json
│   ├── handler_mailer_crit.json
│   ├── handler_mailer_warn.json
│   ├── mailer_crit.json
│   └── mailer_warn.json
├── config.json
├── extensions
├── handlers
│   ├── mailer_crit.rb
│   └── mailer_warn.rb
├── mutators
├── plugins
└── ssl
├── cert.pem
`-- key.pem

次、クライアント側。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/etc/sensu
|-- conf.d
| `-- client.json
|-- config.json
|-- extensions
|-- handlers
|-- mutators
|-- plugins
| |-- check-cpu.rb
| |-- check-disk.rb
| |-- check-http-json.rb
| |-- check-http.rb
| |-- check-load.rb
| |-- check-ntp.rb
| |-- check-ports.rb
| |-- check-procs.rb
| |-- check-raid.sh
| |-- check-swap.sh
| |-- mysql-connections.rb
| |-- mysql-innodb-lock.rb
| `-- mysql-replication-status.rb
`-- ssl
|-- cert.pem
`-- key.pem

チームのローカルルール的なものに適応させる工夫としては、handlers/mailer.rbではなく、handlers/mailer_crit.rbとhandlers/mailer_warn.rbに分けている点。warningとcriticalでアラートメールの飛ばし先が違うんだわ。

4. プラグインについて

コミュニティプラグインがあるということはたびたび述べた。ざっと見た感じだが、”とりあえず作った”という印象が若干ある。plugins/security/check-ports.rbがwarningで固定だった(criticalとwarningを出し分けたいんだけど…)とか、plugins/mysql/mysql-connections.rbが普通にバグってたり…etc。これらについてはリンクで示したPull Requestを送ってマージしてもらったのでとりあえずOKだが、ちょっと触っただけでも結構いろいろと見つかったので、使う場合ちゃんと実験した方が良い。
プラグインの仕様についてはnagiosと同じで、プラグインのexitコードを0: OK, 1: WARNING, 2: CRITICAL, 3: UNKNOWNで返せば良いので、自作は簡単にできる。なのでnagiosの資産を流用することもできる。

5. API

RESTなAPIがある。

http://sensuapp.org/docs/0.12/api

下記に監視を止める例を挙げる。ドキュメントにあるとおり、httpを投げてやれば良い。
例えば下記のようなコマンドを投げると、web01のsnmpd_procの監視がoffになる。ここで、web01はclient.jsonの「”client”: {“name”: “web01″」で示したものに、snmpd_procはcheck.jsonの「”checks”: {“snmpd_proc”」で示したものに対応している。

1
curl -i -X POST -H "Content-Type: application/json" -d "{\"path\":\"silence/web01/snmpd_proc\",\"content\":{\"timestamp\":\"`date +%s`\", \"description\":\"RELEASE `date`\", \"owner\":\"jenkins\"}}" "http://xxx.xxx.xxx.xxx:4567/stashes"

Jenkinsのリリースジョブに上記コマンドと同じ動きをするものを仕込んであるのだが、つい先日実施したリリースではSensu Adminは次のようになった。

sensu_02

誰(jenkinsが)がどういった理由(リリースで)でいつ監視を止めたのかがわかる。また、API仕様や上記GUIを見ればわかるが、Expireをセットすることもできる。監視を再開するときはGUIからActionのdeleteをクリックしてやるか、止めたときと同じくcurlなどでDELETEメソッドを投げてやれば良い。

6. デバッグ

上手く動かんときはログ見るべし。ログは/var/log/sensu配下に出る↓あたりを。
  • /var/log/sensu/sensu-client.log
  • /var/log/sensu/sensu-server.log
ログレベルの設定については上述したけど、デバッグにはinfoレベルで十分かな、という所感。また、RabbitMQにはGUIもあるので、メッセージがちゃんとやりとりされているか見ることもできる。

sensu_03

7. 今後の展望
  • 監視の監視
    • 他のブログでも言われているが、Sensu APIが落ちることがある。sensu-server再起動時にたまに落ちますね。自然死は今のところ発生していないので、とりあえずsensu-server再起動時にsensu-apiも再起動するようにしてあげるのがいいのかな、と。
    • また、sensu-serverそのものやRabbitMQが死んだときにどうするか?
  • 冗長化
    • ↑と繋がるが、単純に箱を二つ用意して、最悪、プライマリが死んだらクライアント側のclient.jsonを配り直せばいいかな?
  • 何台までイケるか?
    • 現状、監視対象ノードは100台弱あるんだが、とりあえずこんくらいは全然イケることがわかった。
  • メトリクス系
    • graphiteとかに情報を送ってメトリクスを取ることもできる。こっちの検証もしたいね。
おわり

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Set your Twitter account name in your settings to use the TwitterBar Section.