OSS紹介 Advent Calendar 2017 - Qiita 22日目の記事です。
最近、監視を Zabbix から Mackerel に切り替えていっています。それと並行して、新規プロジェクトは Amazon ECS でコンテナで運用するようにもしていっています。そこで考えどころなのが、コンテナで動作するプロセスのモニタリングをどうするかです。
たとえば、コンテナで動作する nginx を mackerel-plugin-nginx で監視する場合、普通にやるとこんな感じになるのですが…
- nginx と mackerel-agent を同一タスク (ECS用語) に定義する
- mackerel-agent.conf で
cloud_platform = "none"
の設定をして、コンテナがホストの EC2 とは切り離された状態でホストとして認識されるようにする
すべてのタスクを Mackerel 上のホストとして認識させることになると、いくつか困ることがあります。
- 課金対象が増える
- タスクはデプロイごとに入れ替わ���ので、ホストの入れ替わりイベントが大量に発生する
- 自動退役すればみなくてよいとはいえ…
複数コンテナのメトリクスは、集約した状態で一つの値がみられれば用が足りることが多いため、何らかの形で集約メトリクスを実現したかったのですが、現状の Mackerel では同一時刻に登録したサービスメトリックの値は上書きされてしまいます。
そこで、CloudWatch で集約することを考えました。
CloudWatch では同一時刻に複数回送信した値を、合計、最大、最低、平均などの統計(statistics)を指定して取得することができるため、nginx でいうと RequestCount の合計なら単位時間内の総クエスト数、平均なら1コンテナあたりの平均リクエスト数、のように、目的に合わせて値を読み取れます。
sardine
mackerel-plugin (互換) のコマンドを実行し、得たメトリクスを CloudWatch へ投稿する agent として、sardine を書きました。 Go で実装されたシンプルな agent です。
命名は、mackerel(鯖)より小さいのが群れているので sardine(鰯) ということで。
[plugin.metrics.nginx] command = "mackerel-plugin-nginx --host nginx --port 80 --path /nginx_status" dimensions = ["Service=staging", "Service=staging,Task=app"]
このような、mackerel-agent.conf に類似した設定ファイルで定義をします。各 ECS タスクに同梱して動作させる想定です。
デフォルトでは60秒ごとにプラグインをコマンドとして実行し、たとえば得られた出力が以下だった場合に
nginx.requests.requests 123.0 1512057958
CloudWatch のメトリクスとしては以下の値を投稿します。
- Namespace: nginx/requests
- MetricName: requests
- Value: 123.0
- Timestamp: 2017-12-01T16:05:58Z
これで複数の同一種類のコンテナ、タスクから投稿された値を、大づかみにして把握できます。
この集約されたメトリクスを、Fluentd を用いて (plugin-cloudwatch + plugin-macakrel) Mackerel に値を持っていくことで、Mackerel 上でグラフを並べてみることもできます。
まとめ
- コンテナ、タスク単位で Mackerel にホストを作らず、集約メトリクスを実現するために sardine を作りました
- Mackerel 本体だけで、このような集約メトリクスが実現できると嬉しいです