はじめに
Amazon ECS に、Container Insights というコンテナワークロードに特化したモニタリング機能があります。ECS クラスターで稼働するサービスやタスクを一目で把握する可視化機能や、サービス単位のパフォーマンスメトリクスを確認する機能があります。また、サービス配下のタスク単位では、最新時刻のパフォーマンスを確認する機能があり、タスクに対する負荷の集中が確認しやすくなります。
Container Insights は、簡単に始められるので有効化の方法を確認してみましょう。
Container Insights の有効化
Amazon ECS クラスターの詳細画面を引きます。CloudWatch monitoring に Default と表示されている場合は、Container Insights は無効化となっています。
既存の ECS クラスターの有効化は、マネージメントコンソールでは出来ません。AWS CLI から有効化が可能です。次のコマンドを実行します。
aws ecs update-cluster-settings --cluster test-cluster01 --settings name=containerInsights,value=enabled
Container Insights が有効になりました。有効にしてから、約 5分ほど待機すると、CloudWatch の画面に反映されました。すぐ確認しても表示されないので、多少待ちましょう。
Container Insights を確認
いくつかのシナリオを基に、Container Insights の使い方を見ていきましょう。
クラスターの全体像を確認
CloudWatch のメニューから、Container Insights を選択します。画面内のプルダウンで、Container map を選択します。
Container Insights が有効になっている全クラスタの状態が見えます。特定のクラスタだけ見たい場合は、Filter からクラスタ名を選択します。
ECS の Service と Task が並べて表示されております。より直感的に確認するために、Refresh を押します。
Service に紐づく形で、Task が表示されました。これで、クラスタ内に稼働するサービスと、それに紐づく Task の概要がわかります。また、アイコンの色が緑色ではない場合は、CPU などのリソースの状況が良くない可能性を示しています。黄色の段階では、まだ大丈夫かもしれませんが、確認してみると良いでしょう。
サービス単位のパフォーマンスを確認
Performance monitoring を確認
調査したいサービスを選択
サービス配下で稼働するタスクを全てまとめた形で、CPU やメモリや、稼働すべきタスクの数、現在稼働しているタスクの数が見えます。
Task 単位のパフォーマンスを確認
Performance monitoring の画面には、Task 単位での CPU やメモリの使用率がわかります。現時点での最新の状況しかわらかないため、過去の履歴は見えない点は留意しておきましょう。
Task のログを検索
該当の Task を選択して、アプリケーションのログを検索することが出来ます。選択して、View application logs を押します。
Run query を押す
ログを検索が出来ます。
余談 : Task 単位の過去メトリクス確認
あまり実用的ではないかもしれないですが、Task 単位の過去のメトリクスを確認するための Dashboard が公開されています。これを import することで、Task 単位の CPU や Memory の使用率を確認できます。ただ、表示する Task は動的に更新されるわけではなく、import の時に task id を指定する形になるため、Task の再作成に自動追従することが出来ません。
GitHub : https://github.com/mreferre/container-insights-custom-dashboards
作業用ディレクトリを適当に作成して、GitHub から clone します。
mkdir ~/temp/container-insights-custom-dashboards
cd ~/temp/container-insights-custom-dashboards
git clone https://github.com/mreferre/container-insights-custom-dashboards.git
ディレクトリを移動します。
cd container-insights-custom-dashboards/container-level-metrics
container-level-metrics.json
に手を加えていきます。クラスタ名を指定します。
sed -i 's/CLUSTERNAME/test-cluster01/g' container-level-metrics.json
タスクid、コンテナid を指定します。
sed -i 's/CONTAINERNAMEREPLACEME/hello-ber/g' container-level-metrics.json
sed -i 's/TASKIDREPLACEME/2a0e0d90e4634989ab76ac313b7e9452/g' container-level-metrics.json
region を東京に指定します。
sed -i 's/us-west-2/ap-northeast-1/g' container-level-metrics.json
変更後の json ファイルです。
{
"start": "-PT168H",
"widgets": [
{
"height": 6,
"width": 15,
"y": 0,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/ecs/containerinsights/test-cluster01/performance' | fields @message\n| filter Type=\"Container\" and TaskId=\"2a0e0d90e4634989ab76ac313b7e9452\"\n| filter @logStream like \"FargateTelemetry\"\n| stats max(CpuReserved) as ContainerCpuReserved, max(CpuUtilized) as PeakCpuUtilized, avg(CpuUtilized) as AvgCpuUtilized by ContainerName | sort ContainerName asc",
"region": "ap-northeast-1",
"stacked": false,
"title": "CPU usage by Container",
"view": "table"
}
},
{
"height": 6,
"width": 15,
"y": 6,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/ecs/containerinsights/test-cluster01/performance' | fields @message\n| filter Type=\"Container\" and TaskId=\"2a0e0d90e4634989ab76ac313b7e9452\"\n| filter @logStream like \"FargateTelemetry\"\n| stats max(MemoryReserved) as ContainerMemoryReserved, max(MemoryUtilized) as PeakMemoryUtilized, avg(MemoryUtilized) as AvgMemoryUtilized by ContainerName | sort ContainerName asc",
"region": "ap-northeast-1",
"stacked": false,
"title": "Memory usage by container",
"view": "table"
}
},
{
"height": 6,
"width": 9,
"y": 0,
"x": 15,
"type": "log",
"properties": {
"query": "SOURCE '/aws/ecs/containerinsights/test-cluster01/performance' | fields @message\n| filter Type=\"Container\" and ContainerName=\"hello-ber\" and TaskId=\"2a0e0d90e4634989ab76ac313b7e9452\"\n| filter @logStream like /FargateTelemetry/\n| stats avg(CpuUtilized) as AvgCpuUtilized, max(CpuReserved) as ContainerCpuReserved by bin(30m)\n",
"region": "ap-northeast-1",
"stacked": false,
"title": "CPU usage for selected container",
"view": "timeSeries"
}
},
{
"height": 6,
"width": 9,
"y": 6,
"x": 15,
"type": "log",
"properties": {
"query": "SOURCE '/aws/ecs/containerinsights/test-cluster01/performance' | fields @message\n| filter Type=\"Container\" and ContainerName=\"hello-ber\" and TaskId=\"2a0e0d90e4634989ab76ac313b7e9452\"\n| filter @logStream like /FargateTelemetry/\n| stats ceil(avg(MemoryUtilized)) as AvgMemUtilized, max(MemoryReserved) as ContainerMemoryReserved by bin(30m)\n",
"region": "ap-northeast-1",
"stacked": false,
"title": "Memory usage for selected container",
"view": "timeSeries"
}
},
{
"height": 9,
"width": 24,
"y": 12,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/ecs/containerinsights/test-cluster01/performance' | fields @message\n| filter Type=\"Task\" and TaskId=\"2a0e0d90e4634989ab76ac313b7e9452\"\n| filter @logStream like \"FargateTelemetry\"\n| stats latest(TaskDefinitionFamily) as TaskDefFamily, latest(TaskDefinitionRevision) as Rev, latest(ServiceName) as Service, latest(ClusterName) as Cluster, max(CpuReserved) as TaskCpuReserved, avg(CpuUtilized) as AvgCpuUtilized, concat(ceil(avg(CpuUtilized) * 100 / TaskCpuReserved),\" %\") as AvgCpuUtilizedPerc, max(CpuUtilized) as PeakCpuUtilized, concat(ceil(max(CpuUtilized) * 100 / TaskCpuReserved),\" %\") as PeakCpuUtilizedPerc, max(MemoryReserved) as TaskMemReserved, ceil(avg(MemoryUtilized)) as AvgMemUtilized, concat(ceil(avg(MemoryUtilized) * 100 / TaskMemReserved),\" %\") as AvgMemUtilizedPerc, max(MemoryUtilized) as PeakMemUtilized, concat(ceil(max(MemoryUtilized) * 100 / TaskMemReserved),\" %\") as PeakMemUtilizedPerc",
"region": "ap-northeast-1",
"stacked": false,
"title": "Fargate task details",
"view": "table"
}
}
]
}
AWS CLI でダッシュボードを import します。
aws cloudwatch put-dashboard --dashboard-name container-level-metrics --dashboard-body file://./container-level-metrics.json
決め打ちで 1 つの Task に関する過去の状況が見えます。ただ、Task の再作成などのタイミングで、Task id が変わるので、使いにくいかもしれません
わかったこと
- Container Insights
- Task レベルのパフォーマンスは、現在のメトリクスしか見えない (過去のメトリクスを使った可視化などは難しい)
- Service の単位では、過去のメトリクスを使って可視化が可能
- GitHub に公開されている Dashboard を import することで、Task ID を決め打ちで指定した可視化は可能
- ただ、Task の再作成で Task ID が変わるため、この自動化は難しい
- Lambda などによる自動化を作り込めばいけるかもしれない
- CloudWatch Logs Insights のクエリーの書き方を工夫すれば、もしかしたら余地はあるかもしれない。
参考 URL