GCP Stackdriver 公式パートナーBlueMedora社のMonitoring Agentの紹介と導入方法


@koshi_life です。

最近、GCE上でRails、MongoDBの環境でサービス提供しているプロダクトに対し、Stackdriver Monitoring を用いて、インフラリソースの見える化、異常検知を行えるよう監視基盤を整えるようなことをしました。

見える化のため各種メトリクスを送信するAgentを導入していくわけなのですが、
MongoDBを含め Tomcat, PostgreSQL, Elasticsearchなどのサードパーティ製アプリケーション向けにGCPから提供されていたAgentは2019年2月末でサポート終了1となっており、BlueMedora社のサービス(BindPlane)に移行してね、という公式案内の元、MongoDB版のAgentの設定を行いました。

BindPlane情報が世にあまり出ておらずハマったのでこちらに備忘します。
この記事が誰かの救いになったら幸いです。

準備1. GCP側の設定

BindPlane側のエージェントがGCPプロジェクトのStackdriverの情報を把握し、メトリクスを書き込み可能な「サービスアカウント」と「必要なAPI」を有効化します。 (参考 公式ガイド)

  • サービスアカウントの作成 (参考)
    • ロールは「モニタリング管理者 (Monitoring Admin)」2
    • JSONキーを作成
  • CloudResourceManager のAPIを有効化

準備2. BindPlaneにサインアップ

BindPlaneのアカウントを作成します。

チュートリアル的な案内に沿って進めます。
3ステップでした。

  • STEP 1. 送信先 Destination の設定
  • STEP 2. データ収集サーバ Collector の設定
  • STEP 3. 取得元 Source の設定

STEP 1. 送信先 Destination の設定

この設定は、準備1で作成したサービスアカウントのJSONキーのJSONを貼り付けて完了です。

STEP 2. データ収集サーバ Collector の設定

取得元へアクセス可能なデータ収集サーバを設定します。

私の環境では同一GCPプロジェクト内にいたGCE(Ubuntu)を Collector に設定。
Linuxを選択しました。3

表示されたコマンドをコピーします。

該当のインスタンスにログインし、コピーしたコマンドを実行しデータ収集エージェントインストールします。

インストール完了後、ブラウザのBindPlane画面に戻ると、リロードすることなく進捗状況が以下のように反映され、右下のチャットエリアにいる Kyleさん が「設定は最後の一個だぜ!」って応援してくれます。4

STEP 3. 取得元 Source の設定

最後に取得元情報を設定していきます。
登録されているインテーグレーションから選択します。

ちなみに2019年5月現在168のインテグレーションに対応しているようです。
インテーグレーション一覧

ここではMongoDBを選択します。
設定方法は各インテグレーションごとにドキュメントがあるので参考に。

以下のような入力項目に Source 情報を登録し、テスト接続を経て登録します。

BindPlaneでの全ての設定が完了したので、Kyle が褒めてくれます。

設定反映確認. Stackdriverでメトリクスを確認して完了

設定の反映確認をします。

Stackdriver上で確認

MongoDBへのリクエスト数が確認できました。

BindPlane上でも確認可能

BindPlane上でも概要レベルでは確認ができるようです。

おわりに

BindPlane側のUXがとてもキメ細やかに設計されているおかげで、Mongoのユーザ認証ロール設定でハマった以外は比較的スムーズに導入することができました。

今後、取得元リソースが増えたしても簡単に設定を追加できそうです。

以下にハマったポイントを参考トラブルシューティングとしてまとめておきます。

参考:トラブルシューティング

Step1. Destination 設定時 遭遇したエラー

最初がCloudResourceManagerAPIの有効化が必要なエラー。
次のエラー画像がRoleの権限 monitoring.metricDescriptors.delete が足りないエラー。

Step3. Source 設定時 遭遇したエラー

Mongodの情報を登録する際に以下エラーでハマった。

Unable to run dbStats command on databases with server address list [mongodb-cluster-0:27017]. (Check if a primary mongod is down.)

Mongodが死んでいる?とエラー表示からIPの登録が間違っているとミスリードしハマった、
実際には指定したユーザの権限が足りなかっただけであった。mongod側のログを見るとよい。

Mongoユーザの権限を一時的に root を付与したらテスト接続を通過でき設定ができた。

mongo> db.grantRolesToUser("stackdriver", [ { role: "root", db: "admin" } ])

その後、root権限はセキュリティ的に渡したくなかったので、mongodのログを見ながらBindPlaneの画面からテスト接続を繰り返し、
できるだけ最小限になるよう読込権限のみのロールを導いた。(今の所、メトリクス取得に問題は出ていない。)5

参考:Sourceに設定可能なmongoユーザの読み込み権限のみのロール

mongo> db.createRole({
    "role": "getStackdriverInfo",
    "privileges": [{
            "resource": {
                "db": "admin",
                "collection": ""
            },
            "actions": [
                "viewUser"
            ]
        },
        {
            "resource": {
                "db": "admin",
                "collection": "system.roles"
            },
            "actions": [
                "collStats"
            ]
        },
        {
            "resource": {
                "db": "admin",
                "collection": "system.users"
            },
            "actions": [
                "collStats"
            ]
        },
        {
            "resource": {
                "db": "admin",
                "collection": "system.version"
            },
            "actions": [
                "collStats"
            ]
        },
        {
            "resource": {
                "db": "admin",
                "collection": "system.keys"
            },
            "actions": [
                "collStats"
            ]
        },
        {
            "resource": {
                "db": "config",
                "collection": "system.sessions"
            },
            "actions": [
                "collStats"
            ]
        },
        {
            "resource": {
                "db": "local",
                "collection": "system.rollback.id"
            },
            "actions": [
                "collStats"
            ]
        },
        {
            "resource": {
                "db": "local",
                "collection": "system.replset"
            },
            "actions": [
                "collStats"
            ]
        }
    ],
    "roles": [
        "clusterMonitor",
        "readAnyDatabase"
    ]
})
mongo> db.createUser({user: "stackdriver", pwd: "password", roles: ["getStackdriverInfo"] })

  1. (感想)2019年5月現在サードパーティ製のアプリケーションの中でGCPが継続サポートしているのは Apache,スタンドアロン JVM, Memcached, MySQL, Nginx, Redis, StatsDです。切り離した技術、残した技術からGCP側のビジネス戦略に思いを馳せました。 

  2. 強すぎるロールMonitoring Adminは与えたいのでMonitoring Editorのロールを設定した。今の所問題は起きていない。ちなみに「Monitoring Metric Writer」はテスト接続で弾かれた。 

  3. ちなみにLinuxボタンではなく、別ボタンのGCPボタンを押した時に生成されるコマンドはインスタンス生成をCUI対話形式でやってくれるコマンドが生成されました。 

  4. 随所に離脱しないようUXの作りがキメ細かく工夫されており、離脱させないサービス作りの観点でも勉強になりました。 

  5. Guide では the admin database with read-only credentialsって記載があり、adminに対するreadロールだけで最初試したがテスト接続が通らないので注意。