追記 (2020/06/15) Container Insights は GA しています!
2020/06/14 現在はベータ版として提供されていますが
この記述は誤りで Container Insights は 2019 年 11 月には既に GA されておりますので, ここで訂正させて頂きます.
確認不足で誤った情報を記述してしまい大変申し訳ございませんでした.
tl;dr
以前に以下のような記事を書きました.
この記事では, Fargate で動いているバッチ処理タスクの CPU 使用率やメモリ使用量のリソース情報を ECS タスクメタデータエンドポイントから取得し, バッチ処理タスクが終了したらリソース情報を集計してバッチ処理タスクのログに差し込む仕組みを紹介させて頂いています.
記事を書いてからもうすぐ一年が経過しようとしているところで, この仕組みのコードを夜な夜なコツコツと整理して gem 化したので紹介させて頂きます.
kobanzame
作ったもの
Kobanzame = コバンザメ.
サイドカー的にバッチ処理が実行されるコンテナにくっついてリソースの情報を取得する様が, 大きなクジラにくっついてそのおこぼれ等を餌にしているコバンザメのようだったので命名しました.
仕組み
仕組み自体は以下のようなイメージです.
ECS タスクにサイドカーコンテナとして Kobanzame コンテナを追加します. Kobanzame コンテナは Batch Worker コンテナが動き続けている限り, タスクメタデータエンドポイントにアクセス (デフォルトで 1 秒毎) して Batch Worker コンテナの CPU 使用率とメモリ使用量を収集します.
Batch Worker コンテナが終了 (正常, 異常問わず) すると, CPU 使用率とメモリ使用量を集計して Batch Worker のログが出力されている CloudWatch Logs の Log Stream の最終行に差し込みます. (下図の通り.)
集計された情報は, 以下のようにテキストまたは JSON フォーマットで送信することが可能です.
# テキストフォーマット REPORT TaskID: xxxxxxxx Duration: 10ms, Memory Used: 133.4MiB(ave)/200.621MiB(max), CPU Usage: 62.567%(ave)/90.3%(max) # JSON フォーマット { "report": { "duration": { "duration": 10, "unit": "ms" }, "memory_used": { "average": 133.4, "max": 200.621, "unit": "MiB" }, "cpu_usage": { "average": 62.567, "max": 90.3, "unit": "%" } }, "task_id": "xxxxxxxx", "docker_name": "foo" }
また, 前回は実装していなかったのですが, CPU 使用率とメモリ使用量を CloudWatch メトリクスにカスタムメトリクスとして記録するようにしています.
なんちゃってプラグインアーキテクチャ
現時点では, 集計情報は Batch Worker の Log Stream に差し込み, メトリクスは CloudWatch メトリクスのみに記録するようになっていますが, なんちゃってプラグインアーキテクチャになっている為, 必要に応じて, Slack や Datadog 等に送信することも可能です.
以下は雑に Slack チャンネルに通知した様子です.
使い方
設定ファイル
kobanzame は JSON で設定ファイルを書きます. 以下は設定例です.
{ "container": { "name": "batch-worker", "check_interval": 1, "report_format": "json" }, "metrics": { "name": "cloudwatch", "namespace": "Custom/Kobanzame" }, "outputs": [ { "name": "cloudwatch_logs", "log_group_name": "kobanzame-sample-dev-batch-worker", "log_stream_prefix": "batch-worker", "log_stream_name": "batch-worker-resource-statistics" } ] }
以下に設定内容について簡単に解説させて頂きます.
container
セクションには, 対象コンテナ名を指定します (「仕組み」にて掲載している図の Batch Worker
を指しています).
Key | Required | Value Example | description |
---|---|---|---|
name | Yes | batch-worker | 対象コンテナ名を指定します |
check_interval | Yes | 1 | リソース情報取得する間隔を指定します |
report_format | Yes | json | 集計情報を出力するフォーマットを指定します. JSON 以外に Text や CSV も指定可能です |
metrics
セクションには, リソース情報を送信する CloudWatch のネームスペースを指定します (現在は CloudWatch のみに対応しています).
Key | Required | Value Example | description |
---|---|---|---|
name | Yes | cloudwatch | 取得したメトリクスを送信します (現在は CloudWatch のみ対応) |
namespace | Yes | Custom/Kobanzame | CloudWatch メトリクスのネームスペースを指定します |
outputs
セクションには, リソースの集計情報の送信先を指定します.
Key | Required | Value Example | description |
---|---|---|---|
name | Yes | cloudwatch_logs | 集計した情報を CloudWatch Logs に送信します |
log_group_name | Yes | kobanzame-sample-dev-batch-worker | 送信する Log Group 名を指定します |
log_stream_prefix | No | batch-worker | 送信する Log Stream 名を指定します |
log_stream_name | No | batch-worker-resource-statistics | 送信する Log Stream 名を指定します |
log_stream_prefix
を指定した場合には, Batch Worker が出力する Log Stream のプレフィックスを指定すると, Lambda ファンクションの実行結果のようにログが出力されています. また log_stream_name
を指定した場合には, 集計結果のみが指定した Log Stream に集積されます.
尚, 設定ファイル名自体は任意で OK です.
実行
設定ファイルを setting.json というファイル名で作成した場合, 以下のように kobanzame を実行します.
$ kobanzame --config=setting.json
その他のオプションは以下の通りです.
$ kobanzame --config=setting.json Usage: kobanzame [options] -c, --config PATH config file path (default: kobanzame.json) -d, --daemonize enable daemonize (default: false) -p, --pid-file PATH pid file path (default: kobanzame.pid) -l, --log-file PATH log file path (default: STDOUT) -D, --debug start with debug mode (default: false)
Example
kobanzame を実装するにあたって利用した各種ファイル (Fargate 等を構築する Terraform コードや Run Task をラップしたシェルスクリプト等) をリポジトリの example
フォルダに置きました.
参考
今回, kobanzame を実装するにあたって, 以下の OSS ツールを参考 (利用) させて頂きました.
serverengine はその名の通り, Ruby でサーバーを実装するにあたって必要な PID ファイルの作成やログファイルの出力, 安全にプロセスを停止する為の仕組みが提供されていて, あの fluentd でも利用されているライブラリです. serverengine については, udzura さんの以下のブログ記事も参考にさせて頂きました.
kobanzame には緩い感じのプラグイン機構が備わっていて, 集計結果の出力先やメトリクスの送信先をコア部分に影響が無いように追加することが可能です. このなんちゃってプラグイン機構のヒントと実装は sonots さんの alerty を参考にさせて頂きました.
serverengine も fluentd も alerty も以前から存じ上げていましたが, 改めて kobanzame を実装するにあったて, ソースコードを読みましたが, 理解出来ているかは置いといて大変勉強になりました. 有難うございました.
それ, Container Insights で良いんじゃないのか
おっしゃるとおり
ちゃんと使えていないのですが, コンテナのリソースを収集して CloudWatch メトリクスで確認出来る Container Insights が東京リージョンでも利用出来ます. 2020/06/14 現在はベータ版として提供されていますが, ECS のクラスタ毎, サービス毎, タスク毎にコンテナのメトリクスを確認出来ますし, 当然 kobanzame
では取得出来ないメトリクスも確認出来るので, ちゃんとコンテナを監視したい場合には Container Insights を利用することをオススメしたいと思います.
じゃあ, なぜ, 俺は kobanzame を作ったのか
こちら にも書いたように, 以下のような目的がありました. 当時は Container Insights は GA されていなかったりして, Fargate で動いているコンテナのリソース状況を 手軽
に把握する術を模索していました. (Datadog や Mackrel 等のツールも検討しましたが, これらのツールどのようにコンテナのリソースを収集しているかを調べるうちに自分で実装していたという感じです.)
- バッチ処理でどのくらいの CPU やメモリリソースが使われているのかざっくりと把握したい
- 今後のコンテナリソースサイズを検討する際の参考にしたい
そして, バッチ処理のログ出力に Lambda ファンクションのログ出力のようなリソース使用状況を出力したかったことも理由です. 実際にログに出力して, そのログを Elasticsearch に転送して可視化したりして, バッチ処理の改善に役立てることが出来ていると思います.
以上
ECS タスクメタデータエンドポイントを使ったコンテナのリソースモニタリングツール kobanzame を紹介させて頂きました. 多くの人に使って頂きたいというわけではありませんが, 同じような悩みを持たれている方の課題解決に少しでもお役に立てれば幸いです.