オンプレでMackerelとNeptune.ioの連携を試す



# はじめに

[Neptune.io](https://www.neptune.io/)というスタートアップのクラウドサービスが、運用エンジニアにとって魅力的な言葉が踊っていて試してみたかった。

> Don't wake up your engineers to fix alerts. Use Neptune to fix them automatically

「問題改善のために起こされることはありません。Neptuneが自動的に修復します」

仕事納めの今日、検証する時間があったので[Mackerel](https://mackerel.io/)との連携を試してみました。


# 作るもの

オンプレって言いながらVagrantです。すみません。
今回は2台のノードを使って、

1. ノード1が疎通NGになったら
2. mackerelにNGを検知させてNeptune.ioにWebhookを送信し
3. Neptuneのエージェント経由でアクションを行い
2. ノード2がノード1の持っているエイリアスアドレス(VIP)を引き継ぐ

という動作をさせてみます。


# 試験的実装

はじめにお断り：
本当に動作試験しただけなので、この実装を真似ないようにしてくださいね。
以下はいつもの口調で・・・・

## Neptune.ioアカウント作成

動作確認なのでFreeアカウントでよいかと。

## Neptune.ioエージェントインストール

『Integrations』の『Infrastracture Integration』より、
『ON PREMISE SERVERS』を選択する。

![スクリーンショット 2015-12-29 11.57.22.png](https://qiita-image-store.s3.amazonaws.com/0/82212/405b4651-64e4-d689-d692-b5a79ca3c617.png "スクリーンショット 2015-12-29 11.57.22.png")

インストール用bashコマンドが表示されるので、対象サーバーにてそのままコピペで打とう。今回は2台のサーバーで実行。

```bash
NAGENT_USER="neptuneioagent"  NEPTUNEIO_KEY="xxxx" bash -c "$(curl -sS -L https://raw.githubusercontent.com/neptuneio/nagent/prod/src/install_nagent.sh)" 
```

2台のサーバーが登録された。

![スクリーンショット 2015-12-29 11.59.25.png](https://qiita-image-store.s3.amazonaws.com/0/82212/b5d84ce1-2bea-020f-ecc8-e54f6001c424.png "スクリーンショット 2015-12-29 11.59.25.png")

この`neptuneioagent`ユーザーによって障害対応のアクションが自動実行されるようになる。
アグレッシブすぎるのでおすすめはしないが、対象サーバーにはこんなsudoersを作っておこう。（本当は必要なコマンドだけ解放するのが良い）

```/etc/sudoers.d/11_neptuneio
Defaults:neptuneioagent !requiretty
neptuneioagent ALL=(ALL) NOPASSWD:ALL
```

プロセス再起動とかを実施させたければ、ulimitsとかも気をつける必要がある。


## Rule設定

それでは、障害発生時のルールを作っていく。

Rules→Webhooksを選択、『Create Rule』画面に遷移する。
Triggerに「Webhook」を選択。
Whitelisted IPを選択して[mackerelのソースIPアドレス](http://help-ja.mackerel.io/entry/faq)を設定する。（と言いたいところだが、ネットワーク指定に対応していないのでやむなく無視した）

そして、EXECUTE_SCRIPTアクションを設定する。
『Select hosts』欄にアクションを実行するホストを指定する。今回はノード2を指定した。

![スクリーンショット 2015-12-29 12.09.10.png](https://qiita-image-store.s3.amazonaws.com/0/82212/0453175c-eddb-828d-48fb-bc1651efe2e4.png "スクリーンショット 2015-12-29 12.09.10.png")

Runbook欄に復旧アクションを行うbashスクリプトを記載しよう。
今回はIPアドレスを付けるスクリプトを作ってみた。（あまり一般的な例じゃないなぁｗ）

```bash
# Write your script here 
/bin/ping -c 3 192.168.200.201
if [ $? -ne 0 ]; then
  /sbin/ip address add 192.168.200.201/32 dev eth1
fi
```


## mackerel側設定

先ほどのRule設定が終わると、このようにWebhook用Trigger URLが発行される。
このcurlの中のURLをコピーしよう。

![スクリーンショット 2015-12-29 16.10.44.png](https://qiita-image-store.s3.amazonaws.com/0/82212/c86c7123-0b62-c9ad-58cb-420e3b649ce5.png "スクリーンショット 2015-12-29 16.10.44.png")

mackerel側にアラート設定を入れる。
Webhook通知によって、Neptune.ioにアラートを通知する。
URLに関してはcurlに書かれているものをコピーすれば良い。

![スクリーンショット 2015-12-29 16.09.47.png](https://qiita-image-store.s3.amazonaws.com/0/82212/171671e0-01a5-7309-287b-f31a1b451e78.png "スクリーンショット 2015-12-29 16.09.47.png")


このままだと何のサーバーが落ちてもWebhookが送られてしまうので、mackerel側にてうまくグループを整理する必要がある。そこについては割愛する。

## 実験

ノード1を落としてみる。

```bash
[node1] $ shutdown -h 0
```

しばらく経つとmackerelによってConnectionErrorが通知される。
その結果、Webhookが突つかれたことが確認できる。

![スクリーンショット 2015-12-29 12.35.23.png](https://qiita-image-store.s3.amazonaws.com/0/82212/eb592c1f-2fe8-6d5d-1b40-fa3df83eea9a.png "スクリーンショット 2015-12-29 12.35.23.png")


ノード2を見てみよう。実行されていることが確認できる。

![スクリーンショット 2015-12-29 12.42.32.png](https://qiita-image-store.s3.amazonaws.com/0/82212/0269f157-9b59-e9d2-3b07-b09da138d2d2.png "スクリーンショット 2015-12-29 12.42.32.png")

戻すときはどうするんだ？
って疑問が湧いてきたけれど、切り戻しなんてのは手作業でもいいか。

# 感想

Neptune.ioは非常に高機能でモダンで、運用管理者にとってわくわくできるサービスですね。
一方で、現在のmackerelの監視通知設計とは合わない印象が強かったです。
というのも、

* Neptune.ioは「 **1アラート : 1 Webhook URL** 」を期待している
* mackerelはサービスあるいはOrganization(≒全システム)に **共通で通知先Webhookを設定** する

といった理由で、複雑な通知設計を考える必要があるからです。

また、アラートの内容を変数として取得することが、JSONデータの構造の違い([mackerel](http://help-ja.mackerel.io/entry/howto/alerts/webhook), [Neptune.io](http://docs.neptune.io/docs/webhook-triggers))によって現状ではできません。
　※ Neptune.ioでは、MetaDataという構造体で渡す必要がある
そのため、サービス状況による条件分岐を考慮した処理を実装することは出来ません。

これらの問題はmackerelに限った話ではなく、多くのクラウド系サービスに言えることですね。
NagiosやZabbixを自前で用意している環境ではもう少し柔軟にできるでしょう。


試行錯誤してみようと思います。