去る 10月5日に、Mackerel DAY というイベントが開催された。サーバー監視サービス・Mackerel のリリース3周年を祝っての大型イベントで、豪華登壇陣をゲストに迎え、お昼過ぎから懇親会まで、非常に濃密な時間だった。僕もスタッフとして参加し、また登壇もさせていただいた(僕の登壇スライドはこちら)。
豪華登壇陣、と書いたが、本当に豪華で、非常に多種多様な観点でのお話を聴くことができ、中の人としても・いちユーザーとしても、大変貴重な時間だった。そんななか、ガツンと脳天に響いたセッションが、メルカリ社の SRE チーム所属・プリンシパルエンジニアの id:kazeburo ( @kazeburo )さんの発表だった。
内容としては、メルカリ社における Mackerel のサービス/ロール設計のお話と、独自に作成しておられるカスタムスクリプト/プラグインの紹介というもの。
文字通り、Mackerel をフル活用されているからこその内容を目の前にして、とにかくすごいと思った。僕は居ても立ってもいられなくって、公開されているカスタムスクリプト・プラグインをひとつずつ見てみることにした。公開されているものには大別して「LL言語(Perl)で書かれているもの」( http://github.com/kazeburo/custom-mackerel-plugins )と「Go言語で書かれているもの」( https://github.com/kazeburo/ )とがあって、今回のこの記事はそのうちの前者について。
ちなみに言語の使い分けについてはこちらのスライドに書かれていて、「コマンドの呼び出しと結果の処理だけで実現できるもの」「HTTPリクエストと JSON 処理があるもの」については LL 言語で書く、という方針のようす(AWS API の利用や DB への接続などをおこなう必要のあるものは Go 言語で、とのこと)。
Mackerel のプラグインは終了コード、もしくは標準出力結果をパースする仕様なので、言語を選ばず書ける(それこそ shellscript でも)のがよいところ。
以下は、ひとつずつ見ていきながら気づいたこととかのメモ。
github.com/kazeburo/custom-mackerel-plugins を紐解く
check-conntrack-free
iptables によるパケット追跡数の上限は /proc/sys/net/netfilter/nf_conntrack_max
にて定められており(※このファイルのロケーションは OS のバージョンなどによって異なることがある)、この値を超過するとパケットが破棄されてしまう。
現在の追跡パケット数は /proc/sys/net/netfilter/nf_conntrack_count
に記録されている(※同上)。このカスタムスクリプトは、追跡可能残りパケット数をチェック監視するためのもの。閾値はオプションで w=98765 c=43210
のように与える。
Mackerel の公式プラグインにも mackerel-plugin-conntrack というものがあり、これを用いることで可視化・監視が可能。
check-crt-expiration
SSL証明書の expiration をチェックする。internet-facing なものであれば Mackerel の外形監視でもチェック可能なので、そうではないものについてはこれが活用できる。Mackerel の公式プラグインにも 同様の働きをするものがある。
check-resolver
--host
で与えた名前の名前解決所要時間をチェックするためのカスタムスクリプト。H2O でも著名な kazuho さんの Net::DNS::Lite を利用して作成されている。
前提として、Net::DNS::Lite は server が指定されていない場合には /etc/resolv.conf を読んでネームサーバの解決をおこなう仕様になっており( https://blog.nomadscafe.jp/2012/06/netdnslite-resolvconf---netdnslite-009.html )、このスクリプトでもその仕様を利用している。
check-dns-rr
これも check-resolver 同様、Net::DNS::Lite を活用している。--host
に与えた名前に対して紐付く(DNSラウンドロビンの結果に含まれる)IP アドレスの数のチェックを実施できる。
check-hydra-pos
ログ集約ソフトウェアとして利用されるケースの多い fluentd だが、一定以上のログ流量がある場合だと fluentd のパフォーマンスがネックになる場合がある。fluent-agent-hydra は、fluentd やそのための各種ロガーとやりとりを低リソースで実現できるログ転送エージェント。
fluent-agent-hydra はモニタリング用のAPIを備えており、 /system
にアクセスすると Go 内部(GC やメモリアロケーション、起動しているゴルーチンの数)に関する稼働状況が、それ以外のロケーション( /
)にアクセスすると fluent-agent-hydra の稼働状況(追尾しているファイルのポジション、転送したメッセージの数やバイト数など)を確認できる。
check-hydra-pos ではこれを利用し、追尾しているファイルのポジションが正常に更新されているかどうかをチェックする。これを通じて、fluent-agent-hydra がきちんと動作しているかどうかを監視するわけだ。
check-inode
inode とは、ファイルシステム上でのファイルやディレクトリを管理するためのデータのこと。上限が決まっていて、これが枯渇するとファイルの作成ができなくなる。
Mackerel の公式プラグイン集にも mackerel-plugin-inode があるが、kazeburo さんのスクリプトでは、
と 、公式プラグインの弱点を補っている。一方で、公式プラグイン・mackerel-plugin-inode はチェックプラグインではなくメトリックプラグインなので、以下の画像のように、時系列による inode の変化をモニタリングしたい場合には有用なため、これと組み合わせて使用するのも良いかと思われる。
check-iptables
当日の発表でもあったが、日本版メルカリはさくらインターネットの DC 内専用サーバでホストされている。さくらの専用サーバには全てに global ip address が振られるらしく、それが不要なサーバでは iptables が diable になっている必要があるのだが、それをチェックするためのスクリプト。
check-myip
これは、ちょっと意図がよくわからなかった。プロキシサーバとの疎通チェックをおこなうためのスクリプト?
/path/to/checke-myip host port
のように引数を2つ以上指定しないと使えないようになっているのだけど、コード的には host
の方しか使われてない気がする?
check-uptime
uptime をチェック監視するためのもの。不意の・意図しない再起動を検出するなどを目的として使用。今では Mackerel 公式のプラグインでも同名のものが用意されているが、これが無かった時代にはこのスクリプトを用いて監視をされていた、とのこと。
delay-checker
delay-checker -c 3 -- check-tcp -p 80
のように用いる。--
以降で指定したコマンドを実行した結果が、 -c
で指定した回数以降失敗したらアラートを上げられるようにする......、、といった、チェック監視のためのユーティリティスクリプト。今では Mackerel のチェック監視にも max_check_attempts
という最大試行回数を指定できるオプションができたのだが、それよりも前にコードで解決されていた。すごい。
interval-checker
これも delay-checker と同じような、チェック監視のためのユーティリティスクリプト。interval-checker --interval 300 -- check-tcp -p 80
のように用いる。。--
以降で指定したコマンドを、 --interval
で指定した間隔で実行しチェックする。Mackerel のチェックプラグインは、デフォルトでは毎分の実行なのだが、指定した間隔になるまでは前回のチェック結果を返すようになっている。
これについても、今の Mackerel のチェック監視には check_interval
オプションが追加されている。
mackerel-plugin-gaurun-usage
Perl で書かれたメトリックプラグイン(チェック監視ではなく、Mackerel によるグラフ描画可能なメトリックを取得・送信するプラグイン)。そして Gaurun とは、メルカリ社の開発したスマホアプリ向けのプッシュ通知サーバ。mackerel-plugin-gaurun-usage は、その稼働状況をモニタリングするためのもの。
Gaurun そのものとそのモニタリングについては、本家の ハイパフォーマンスGaurun〜メルカリの大規模プッシュ配信を支えるミドルウェア〜 - Mercari Engineering Blog が詳しい。
mackerel-plugin-linux-lite
Perl で書かれたメトリックプラグイン。さまざまなハードウェアスペックのサーバ群に対し、一貫した監視閾値を設定することを目的としたメトリックの収集・送信をするためのプラグインスクリプト。具体的には以下のような項目を可視化できる。
- available memory
/proc/meminfo
のMemFree
+Cached
+Inactive
の値
- 100% を上限とした CPU usage
- コア数が異なるサーバが混在していても、共有の監視設定が可能に
- CPU コアあたりのロードアベレージ
- プロセス数
- all
- running
これはスーパー便利だと思う。とりあえずでも入れておくことで、有事の際にその傾向を把握することにも役立ちそう。僕もさっそく、自分のサーバに導入した。
mackerel-plugin-ntpq
Mackerel の公式チェックプラグインにも check-ntpoffset というものがあり、これを用いることで時刻のズレについては検知可能だが、あくまでチェック監視なので、「どのようにズレていったか」といったことを可視化・時系列で把握することはできない。mackerel-plugin-ntpq は、chronyc
コマンド、もしくは ntpq
コマンドの実行結果をパースし、 offset(絶対値)とリモート(NTPサーバ)との Sync 状況を数値化している。
$ chronyc -n sources 210 Number of sources = 4 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^+ 122.215.240.51 2 10 377 292 -102us[ -127us] +/- 35ms ^* 106.185.31.36 2 10 377 187 +262us[ +237us] +/- 34ms ^+ 122.215.240.52 2 10 377 452 -160us[ -185us] +/- 33ms ^- 198.60.22.240 2 10 377 288 -867us[ -892us] +/- 90ms
$ /home/a-know/mackerel-plugin-ntpq ntpq.synced.remote 1 1507520339 ntpq.offset.seconds 0.237 1507520339
synced
については、ちゃんと同期しているサーバがあるかどうかのチェックに使える。kazeburo さん曰く、『ntp.conf の調整をおこなう際に可視化されていると便利』とのこと。これも僕も導入してみた。
mackerel-plugin-php-version
Perl で書かれたメトリックプラグイン。名前のとおり、そのサーバの PHP のバージョンを数値化・グラフ化し可視化するというちょっと変わった・おもしろいプラグイン。
例えば、PHP がインストールされているサーバ全てに PHP
といったロール(Mackerel における ロール
)を設定しておくことで、このメトリックをロールグラフ(Mackerel の機能。同一ロールに属するホスト全てのグラフをひとつのグラフに集約することができる)で確認できる。これにより、古いバージョンのものがインストールされているサーバがあれば、そのサーバのグラフだけ特異な線を描くことになるので、視覚的に把握することが容易にできる(もちろん、これに対して閾値設定をしておくことでアラート発報、ということもできる)。
mackerel-plugin-postfix
Perl で書かれたメトリックプラグイン。Postfix の queue(msgs in queue)を可視化する。公式プラグインにも mackerel-plugin-mailqというものがあり、これは Postfix だけでなく、Exim や qmail にも対応している。
periodic-checker
これもまた、Perl で書かれたチェック監視ユーティリティ。$ periodic-checker --range 00:00-06:00,06:30-24:00 -- check-tcp -p 80
のように使う。......この usage だけでどんな機能を持つものかピンと来ると思うのだけど、--range
で指定した特定の時間帯のみ、--
以降で指定したチェック監視コマンドを実行する、というもの。
例えばデイリーでのバッチ処理(それも重い)などがある時間帯だけはチェック監視をおこなわせないようにする、といった使い方になる。periodic-checker を使わずにこうした監視を実現しようとすると、Mackerel のホストステータスを API 経由でコントロールするくらいしかないわけで、これは超絶便利すぎるでしょ......。。
感想
以上が GitHub - kazeburo/custom-mackerel-plugins: my custom mackerel plugins で管理されているスクリプトプラグインの全て。
こうして見てみると、当時の Mackerel には無かった機能もコードにより実現されていることも少なくないことがよくわかる。まさに『コードを書くことで問題を解決する』という世界観。そしてそれはプログラミングの根幹にある「楽しさ」に通じるものがある、というのは、僕自身の実体験からも言えることだと思っている。
今回これらのカスタムスクリプトの確認を通じて、
- とにかくコードを書いて実現する
- 「経験」を「経験」のままにせず、コードに表す
- 取得可能なメトリックは全て取得し、時系列でモニタリング可能にする
- 優れたソフトウェアはその多くが、モニタリングのための API を提供してくれている
- 監視の結果に疑問が入り込む余地を(できるだけ)なくす
......といったような、メルカリ社の SRE である kazeburo さんの視点、視座の一部を、感じ取ることができたような気がした(妄想含む)。僕は Perl は殆ど読み書きしたことはないのだけど、それでも5分10分眺めているとだいたいわかってくるので(それも Mackerel のプラグインスクリプトの良いところだと思う)、「これは!」というものがあればぜひ一度、実際のコードも確認してみてほしいなと思う。
次回は(いつになるかはわからないけど)https://github.com/kazeburo/ で管理されている Go で書かれた Mackerel プラグインも確認していく。
2017-10-21 追記
メルカリさん以外の登壇内容もすごくよかったので、そちらについても別エントリとしてまとめた。一見の価値アリ。