えいのうにっき

a-knowの日記です

Mackerel "kazeburo" plugin を通じてサーバーモニタリングのキモを探る 〜スクリプトプラグイン編〜

去る 10月5日に、Mackerel DAY というイベントが開催された。サーバー監視サービス・Mackerel のリリース3周年を祝っての大型イベントで、豪華登壇陣をゲストに迎え、お昼過ぎから懇親会まで、非常に濃密な時間だった。僕もスタッフとして参加し、また登壇もさせていただいた(僕の登壇スライドはこちら)。

豪華登壇陣、と書いたが、本当に豪華で、非常に多種多様な観点でのお話を聴くことができ、中の人としても・いちユーザーとしても、大変貴重な時間だった。そんななか、ガツンと脳天に響いたセッションが、メルカリ社の SRE チーム所属・プリンシパルエンジニアの id:kazeburo@kazeburo )さんの発表だった。

speakerdeck.com

内容としては、メルカリ社における 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 の公式プラグインにも 同様の働きをするものがある。

github.com

check-resolver

--host で与えた名前の名前解決所要時間をチェックするためのカスタムスクリプトH2O でも著名な kazuho さんの Net::DNS::Lite を利用して作成されている。

github.com

前提として、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 やそのための各種ロガーとやりとりを低リソースで実現できるログ転送エージェント。

github.com

fluent-agent-hydra はモニタリング用のAPIを備えており、 /system にアクセスすると Go 内部(GC やメモリアロケーション、起動しているゴルーチンの数)に関する稼働状況が、それ以外のロケーション( / )にアクセスすると fluent-agent-hydra の稼働状況(追尾しているファイルのポジション、転送したメッセージの数やバイト数など)を確認できる。

check-hydra-pos ではこれを利用し、追尾しているファイルのポジションが正常に更新されているかどうかをチェックする。これを通じて、fluent-agent-hydra がきちんと動作しているかどうかを監視するわけだ。

check-inode

inode とは、ファイルシステム上でのファイルやディレクトリを管理するためのデータのこと。上限が決まっていて、これが枯渇するとファイルの作成ができなくなる。

Mackerel の公式プラグイン集にも mackerel-plugin-inode があるが、kazeburo さんのスクリプトでは、

  • 絶対値での指定によるチェックではなく割合での閾値指定が可能なこと
    • OS やそのサーバの役割などでサイズが異なる場合がある
  • 全てのファイルシステムに対するチェックを実施しやすくしている

と 、公式プラグインの弱点を補っている。一方で、公式プラグイン・mackerel-plugin-inode はチェックプラグインではなくメトリックプラグインなので、以下の画像のように、時系列による inode の変化をモニタリングしたい場合には有用なため、これと組み合わせて使用するのも良いかと思われる。

f:id:a-know:20171009210732p:plain

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 という最大試行回数を指定できるオプションができたのだが、それよりも前にコードで解決されていた。すごい。

mackerel.io

interval-checker

これも delay-checker と同じような、チェック監視のためのユーティリティスクリプトinterval-checker --interval 300 -- check-tcp -p 80 のように用いる。。-- 以降で指定したコマンドを、 --interval で指定した間隔で実行しチェックする。Mackerel のチェックプラグインは、デフォルトでは毎分の実行なのだが、指定した間隔になるまでは前回のチェック結果を返すようになっている。

これについても、今の Mackerel のチェック監視には check_interval オプションが追加されている。

mackerel.io

mackerel-plugin-gaurun-usage

Perl で書かれたメトリックプラグイン(チェック監視ではなく、Mackerel によるグラフ描画可能なメトリックを取得・送信するプラグイン)。そして Gaurun とは、メルカリ社の開発したスマホアプリ向けのプッシュ通知サーバ。mackerel-plugin-gaurun-usage は、その稼働状況をモニタリングするためのもの。

Gaurun そのものとそのモニタリングについては、本家の ハイパフォーマンスGaurun〜メルカリの大規模プッシュ配信を支えるミドルウェア〜 - Mercari Engineering Blog が詳しい。

tech.mercari.com

mackerel-plugin-linux-lite

Perl で書かれたメトリックプラグイン。さまざまなハードウェアスペックのサーバ群に対し、一貫した監視閾値を設定することを目的としたメトリックの収集・送信をするためのプラグインスクリプト。具体的には以下のような項目を可視化できる。

  • available memory
    • /proc/meminfoMemFree + Cached + Inactive の値
  • 100% を上限とした CPU usage
    • コア数が異なるサーバが混在していても、共有の監視設定が可能に
  • CPU コアあたりのロードアベレージ
  • プロセス数
    • all
    • running

これはスーパー便利だと思う。とりあえずでも入れておくことで、有事の際にその傾向を把握することにも役立ちそう。僕もさっそく、自分のサーバに導入した。

f:id:a-know:20171009211008p:plain

mackerel-plugin-ntpq

これも Perl で書かれたメトリックプラグイン

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 の調整をおこなう際に可視化されていると便利』とのこと。これも僕も導入してみた。

f:id:a-know:20171009211113p:plain

mackerel-plugin-php-version

Perl で書かれたメトリックプラグイン。名前のとおり、そのサーバの PHP のバージョンを数値化・グラフ化し可視化するというちょっと変わった・おもしろいプラグイン

例えば、PHP がインストールされているサーバ全てに PHP といったロール(Mackerel における ロール )を設定しておくことで、このメトリックをロールグラフ(Mackerel の機能。同一ロールに属するホスト全てのグラフをひとつのグラフに集約することができる)で確認できる。これにより、古いバージョンのものがインストールされているサーバがあれば、そのサーバのグラフだけ特異な線を描くことになるので、視覚的に把握することが容易にできる(もちろん、これに対して閾値設定をしておくことでアラート発報、ということもできる)。

mackerel-plugin-postfix

Perl で書かれたメトリックプラグインPostfix の queue(msgs in queue)を可視化する。公式プラグインにも mackerel-plugin-mailqというものがあり、これは Postfix だけでなく、Eximqmail にも対応している。

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 を提供してくれている
  • 監視の結果に疑問が入り込む余地を(できるだけ)なくす
    • Net::DNS::Lite の仕様を理解した上での check-resolver や check-dns-rr のような。。

......といったような、メルカリ社の SRE である kazeburo さんの視点、視座の一部を、感じ取ることができたような気がした(妄想含む)。僕は Perl は殆ど読み書きしたことはないのだけど、それでも5分10分眺めているとだいたいわかってくるので(それも Mackerel のプラグインスクリプトの良いところだと思う)、「これは!」というものがあればぜひ一度、実際のコードも確認してみてほしいなと思う。

次回は(いつになるかはわからないけど)https://github.com/kazeburo/ で管理されている Go で書かれた Mackerel プラグインも確認していく。

2017-10-21 追記

メルカリさん以外の登壇内容もすごくよかったので、そちらについても別エントリとしてまとめた。一見の価値アリ。

blog.a-know.me

その他、今回参考にしたもの



follow us in feedly