えいのうにっき

a-knowの日記です

Mackerel の自動退役の仕組みを紐解いてみる

この記事は、Mackerel アドベントカレンダー(全部CRE)の25日目の記事です。最終日です!メリークリスマス!

最終日。つまりこれで最後。今年のアドベントカレンダーは終わり。ということで今回は、サーバーをMackerelの監視対象から外して"終わり"にする"退役"操作のなかでも、「自動退役機能」にクローズアップしてみたいと思います。...... "終わり" と "退役" を掛けてみたんですが......イマイチか......。

Mackerelにおける "退役" とは

これについては、すでに公式にもヘルプページが存在していて、ぜひ一度読んでみていただけたらと思うのですが、

mackerel.io

これは、不要なサーバーを指定して手動で退役させる場合についての記述です。今回のこのエントリのテーマはそれではなく、例えばオートスケール環境下にあるサーバーの監視については、この退役操作を自動でおこなってほしいわけなんですが、そのような機能も Mackerel には備わっており、それを指して「自動退役」と呼んでるものがあり、それがテーマです。

mackerel.io

ここでは、以下の各パターンにおいてどのようにして自動退役という仕組みが実現されているかを紐解いてみたいと思います。

  • Linux系サーバーにおける自動退役
    • systemd の場合
    • init スクリプトの場合
  • Windows系サーバーにおける自動退役
  • AWSインテグレーションにおける自動退役

Linux系サーバーにおける自動退役

systemd の場合

主に、CentOS 7 や RHEL 7、Amazon Linux 2 以降の場合はこちらかと思われます。systemd により起動されるサービスは、serviceファイルにより定義され、それは mackerel-agent においても同様です。

エージェントのインストールによりセットアップされる service ファイルは、mackerel-agent の GitHub リポジトリでも確認することができます。

mackerel-agent/mackerel-agent.service at master · mackerelio/mackerel-agent · GitHub

注目すべきは以下の行!

ExecStopPost=/bin/sh -c '[ "$AUTO_RETIREMENT" == "" ] || [ "$AUTO_RETIREMENT" == "0" ] && true || /usr/bin/mackerel-agent retire -force --root $ROOT $OTHER_OPTS'

ExecStopPost は、そのサービスが停止されたあとに実行してほしいコマンドを指定するためのものです。/usr/bin/mackerel-agent retire -force 、なるほどなるほど。retire サブコマンドについては、以下のヘルプページにも記載されています。

mackerel.io

謎が解けましたね。簡単!

initスクリプトの場合

こちらの場合も上記と同様、mackerel-agent の init スクリプトの内容を GitHub で確認することができます。

mackerel-agent/mackerel-agent.initd at master · mackerelio/mackerel-agent · GitHub

自動退役に関わりそうなのは、以下のようなあたりでしょうか。

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        retval=$?
        [ "$AUTO_RETIREMENT" != "" ] && [ "$AUTO_RETIREMENT" != "0" ] && retire
        exit $retval
        ;;
retire() {
    echo -n $"Retiring the Host:"
    $BIN retire -force ${APIBASE:+--apibase=$APIBASE} ${APIKEY:+--apikey=$APIKEY} --root=$ROOT $OTHER_OPTS >>$LOGFILE 2>&1
    retval=$?
    if [ $retval -ne 0 ]; then
        failure
        echo
        return $retval
    fi
    success
    echo
}

考え方は基本的に systemd のときと同じですね!initスクリプトの stop に依らないような停止のされ方をされると、自動退役もされない、ということになります。

Windows系サーバーにおける自動退役

実はこちらは、比較的最近サポートされた機能です。

mackerel.io

この対応のための Pull Request はこちら。安心のmattnじるし。(ありがとうございます!)

github.com

全般的に、Windowsサービスとしてバイナリを起動するために必要なパッケージ・svc( golang.org/x/sys/windows/svc )を使って実装されています。へー、知らなかった。。

上記 Pull Request を File Changed で見て頂くとわかりやすいですが、基本的な考え方は Windows であってもいっしょ。自動退役設定が有効な状態でサービスがシャットダウンされたら、退役処理である retire が実行されるようになっています。

AWSインテグレーションにおける自動退役

こちらも、比較的最近サポートされた機能です。今の所EC2のみのサポートです。

mackerel.io

こちら↓の「自動退役を有効にする」をオンにすることで、インテグレーション連携ホストに対する自動退役が有効になります。

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

この機能はこれまでの仕組みとは全くことなるアプローチになります。なぜならば、AWSインテグレーションなので、エージェントのインストールを前提とすることができないためです。

AWSインテグレーションのコードは公開されていないのですが、この機能の仕様としては「AWSインテグレーションによるメトリック取得時に、EC2 インスタンスの status が terminated であればそれに対応する Mackerel ホストを退役させる」というものになります。

ここまで書いてきたとおり、mackerel-agent による自動退役は、エージェントのプロセスの死に方によっては退役処理が走らない場合があります。そうした場合には、課金対象とはならないまでもゴミホストが残ってしまうので、地味に厄介な問題でした。AWSインテグレーション自動退役機能は、それに対するセーフティーネット的な機能にもなります。

まとめ

Mackerel の自動退役の仕組みをパターンごとにご紹介しました。「謎な便利機能」として活用されていることも多い気がするんですが、紐解いてみると意外とシンプルであることがわかりますね。

と、いうことで、12月に入ってからというもの、同じくCREの id:missasan と走り続けてきたMackerel アドベントカレンダー(全部CRE)も、これにて無事終了となります。毎日更新を楽しみにしていただいたみなさま(いるのかな......?)、本当にありがとうございました。

2019年も Mackerel をどうぞよろしくお願いいたします。メリークリスマス!良いお年を!!