えいのうにっき

a-knowの日記です

mkr を使った監視ルールのチェックをインフラ CI フローに組み込んでみた

またも Mackerel ネタ。鯖だけに。(?)

Mackerel には、CLI ツールである mkr GitHub - mackerelio/mkr: Command Line Tool for Mackerel がある。

CLIツールmkrを利用することで、ホストのステータスをまとめて変更するような操作や、手順をスクリプトに組込み自動化することができるようになります。 - CLIツール mkr を使う - Mackerel ヘルプ

今回はこれを使って「監視ルールのコード化」および「監視ルールのチェックを CI フローに組み込む」ことをやってみた。この記事中で用いている mkr のバージョンは 0.11.2

まずは mkr に慣れる

mkr 、存在こそ知ってはいるものの、まだがっつり使ったことはないので、最初は慣れるところから。

何はなくとも、まずはインストール。取り急ぎ開発機(Mac)で mkr を実行できればよいので、homebrew で入れてしまう。

$ brew tap mackerelio/mackerel-agent
$ brew install mkr

そして、何らかの方法で環境変数 MACKEREL_APIKEYAPI キーをセットしておく。API キーは https://mackerel.io/orgs/<organization_name>?tab=apikeys で確認できる。

export MACKEREL_APIKEY=<API key>

うまく設定できているかどうか、いくつかコマンドを叩いて確認してみる。

$ mkr hosts
[
    {
        "id": "2ApBp9M7kbh",
        "name": "a-know-home-web",
        "status": "working",
        "roleFullnames": [
            "a-know-home:web"
        ],
        "isRetired": false,
        "createdAt": "Jan 11, 2016 at 11:05am (JST)",
        "ipAddresses": {
            "eth0": "10.240.0.2"
        }
    }
]
$ mkr fetch --name loadavg5 2ApBp9M7kbh
{
    "2ApBp9M7kbh": {
        "loadavg5": {
            "time": 1468368900,
            "value": 3.38
        }
    }
}

よさそう。

監視ルールをコード管理する

mkrmonitors というサブコマンドがあり、これにさらに pull サブコマンドを指定し実行することで、現在設定されている各種監視ルールを monitors.json というファイルに落とし込むことができる。

$ mkdir mkr
$ mkr monitors pull -F mkr/monitors.json
      info Monitor rules are saved to 'mkr/monitors.json' (20 rules).

あ、この mkr を実行する作業だけど、僕は自分のサーバの構成管理を Chef で行うようにしており、それのリポジトリGitHub - a-know/a-know-home-server: a-know-home chef recipe repository なんだけど、そこのルートで行うことを想定している。

作成された monitors.json の中身を覗いてみる。

{
    "monitors": [
        {
            "id": "2ApwsSsV1Wu",
            "type": "connectivity"
        },
        {
            "id": "2ApCqwqbDeb",
            "name": "Filesystem %",
            "type": "host",
            "metric": "disk%",
            "operator": ">",
            "warning": 80,
            "critical": 90,
            "duration": 3,
            "scopes": [
                "a-know-home: web"
            ],
            "notificationInterval": 30
        },(以下略)
}

いいかんじ。このファイルがまさに、『いままで Mackerel の Web コンソールでポチポチと設定してきた監視ルール設定たち』である。 monitors diff コマンドで、Mackerel 側に設定されているルールと手元の json ファイルの内容との差異を確認することもできる。

$ mkr monitors diff -F mkr/monitors.json
Summary: 0 modify, 0 append, 0 remove

今後は mkr monitors push コマンド(json ファイルの内容に基づき監視ルールを反映させる)を通してのみ監視ルールの設定をするようにすれば、このファイルが常に正となる。なので、そうすることに決めた。いま決めた!(宣言)

監視ルールの差分チェックを CI に組み込む

高らかに宣言したところで、このチェックを CI のフローに組み込んでみる。上述のリポジトリでは既に

  • chef (knife solo)
  • serverspec
  • Google Compute Engine preemptible instance
  • CircleCI

といったツールを活用したインフラ CI を実施しているので、そのテストのステップに『 mkr monitors diff の結果、実際の設定と json の内容とが一致していることをチェックする』プロセスを追加するだけでいい。はず。つまり、 mkr monitors diff で差分が出た場合は先ほどの宣言が守られていないということで、CI が失敗するようにする、というわけだ。

まずは、CI が行われる CircleCI コンテナ内でも mkr が使えるようにしなくてはいけない。具体的には、

の2つ。CircleCI における環境変数の設定は このあたり を見てもらえればと思う。

mkr のインストールは、circle.yml にこんなかんじ↓に書いてみた(今回の作業に関係のない yml ファイル内の記述は省略)。

dependencies:
  pre:
    - |
      curl -fsSL https://mackerel.io/assets/files/scripts/setup-apt.sh | sh
      sudo apt-get install mkr

そして、 mkr monitors difftest ステップの serverspec の前にでも追加しておく。

test:
  override:
    mkr monitors diff -e -F mkr/monitors.json && bundle exec rake spec:ci:web

mkr monitors diff--exit-code, -e オプションを指定することで、差分があったときに終了コード 1 を返してくれる。

ここまでできたらいざ、CI 。

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

おけ!

ためしに、Mackerel の Web UI で適当な監視ルールを追加してみた上で(さきほどの『宣言』をわざと破ってみた上で)CI を実行してみる。

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

↑のように、『CPU %』という監視ルールを手動で追加してみた上で CI を通してみるとー。

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

ちゃんと失敗してくれた(差分に関する情報付きで)!

まとめ

以上までの作業を行ったコミットをまとめた、実際の Pull Request は↓こちら。

github.com

一回の CI で全然違うテスト(serverspec と mkr monitors diff )が走るのはちょっともにょるかもしれないけど、今回は個人ユースでもあるし、これで十分なかんじ。

また、ここではインフラ用のリポジトリ(の CI)で一緒にやっちゃったけど、そのリポジトリで管理している内容とは殆ど関係ないものなので、仮にインフラのコード化をまだできていなかったり、CI できていなかったりしても、Mackerel の監視ルールのチェックだけでもやっちゃってもいいかんじ。むしろ、これをインフラのコード化を進めていくきっかけにしちゃうぐらいのつもりでもいいんじゃないかな。

実際の業務で運用する際には、もう少し柔軟に(場合によっては Web UI からのルールの設定・変更も許す...とか?)ルール決めをするのがよさそう。

mkr 、もう少し遊べそうな気がするので、また気が向いたら遊んでみることにする!

追記(2016-07-14)

「今後は mkr monitors push コマンド(json ファイルの内容に基づき監視ルールを反映させる)を通してのみ監視ルールの設定をするようにすれば、このファイルが常に正となる。なので、そうすることに決めた。」 と上で書いたけれど、少し不足があったので追記。

Web UI で作った監視ルールを pull で持ってきた場合、そのいずれのルールにも id が付与されているものが得られる( id は Mackerel 側で自動で振られる)んだけど、

{
    "monitors": [
        {
            "id": "2ApwsSsV1Wu",
            "type": "connectivity"
        },
        {
            "id": "2ApCqwqbDeb",
            "name": "Filesystem %",
            "type": "host",
            "metric": "disk%",
            "operator": ">",
            "warning": 80,
            "critical": 90,
            "duration": 3,
            "scopes": [
                "a-know-home: web"
            ],
            "notificationInterval": 30
        },(以下略)
}

Web UI での変更を行わず、 push でのみルールを追加する場合は、当然 id は振ることができない。

ここらへん、元々考慮されていて、詳しくは CLIツール mkr を使う - Mackerel ヘルプ に書いてある。

push時の監視ルールの同一性判定ロジック

pullする際はMackerelが付与したidが必ず含まれます。 pushする場合はidが含まれないルールも許容するために以下のロジックで監視ルールの同一判定を行います。

  • idを含む .. idで同一判定
  • idを含まずnameを含む .. nameで同一判定
    • 同じnameを持つ監視ルールが存在した場合、idでのみ同一判定を行います。
    • そのため全ての監視ルールにidが含まれる必要があります。
    • またWarningメッセージを出力します。
  • idもnameも含まないルールがある場合はエラーとなります。

また、 監視ルールをGitHubで管理しよう - Mackerel ヘルプ でもちゃんと書いてあった。

mkr による監視ルールの管理

mkr による監視ルールの管理方法には、WebUIとコードの両方で変更を行うか、 それともコードのみで変更するかどうかで大きく次の2パターンがあります。

(中略)

mkr monitors では monitor rule の特定にidもしくはnameを利用します。 idは監視ルールを新規登録した時にMackerel側で付与するものです。 nameはユーザーが命名します。

前者ではidベースで管理しますので、管理するjsonファイルにもidを含める必要があります。 後者はnameベースで管理しますので、jsonにidを含める必要がありません。 ただしnameが重複していないことが必要です。

もしjsonやMackerel側でnameが重複していた場合、mkrはidベースで監視ルールを 特定しようとします。 nameが重複しているにもかかわらず、jsonの各監視ルールに idが存在しない場合はmkrは不正なjsonと判定します。

つまり、手元の json ファイルを編集し push することでのみ監視ルールの管理をしていく場合は、json ファイル内の各ルールに id 要素は必要ない、ということ。id があるものとないものが混在していても問題ないようす。あと、 name だけでもルールの同一性を判別できるので、id を持ってくるためだけに pull をする必要もない。

ここらへん、監視ルールをGitHubで管理しよう - Mackerel ヘルプ にとても詳しく書かれているので、監視ルールのコード管理とその運用フローを真面目に考える場合は、ぜひご一読あれ。

参考 URL

関連するかも

blog.a-know.me

blog.a-know.me



follow us in feedly