Amazon Web Services ブログ

Amazon ECS向けAmazon CloudWatch Container Insightsについて

本記事は AWS のシニアソリューションアーキテクトの Sirirat Kongdeeによる寄稿記事です。

Amazon CloudWatch を利用することで、Amazon Elastic Container Service(Amazon ECS)のリソースを監視することができます。Amazon CloudWatchは、CPU やメモリの割り当てについてや、クラスター、サービスレベルでのリソース使用率のメトリクスを提供するサービスです。以前は、サービスとタスクについてカスタムモニタリングを有効にする必要がありましたが、CloudWatch Container Insightsを使用することで、すべての Amazon ECS リソースの監視、トラブルシューティング、アラームの設定を行うことができるようになりました。これはフルマネージド型のサービスであり、Amazon ECSのメトリクスとログを収集、集約、要約することが可能となります。

CloudWatch Container Insightsダッシュボードでは、次のような情報を確認することができます。

  • CPUやメモリの使用率
  • タスク数、サービス数
  • ストレージへの読み込み/書き込み
  • ネットワーク 受信バイト数/送信バイト数
  • クラスター、サービス、タスクが利用するコンテナインスタンスの数
  • その他

これらのメトリクスを直接確認することで、Amazon ECS リソースに対して、より完全に近い形での洞察や制御ができるようになります。

CloudWatch Container Insightsを使用すると、次のことが可能となります。

  • CloudWatch Container Insightsダッシュボードメトリクスにアクセスできます。
  • CloudWatch Logs Insightsとの統合により、コンテナアプリケーションとパフォーマンスログに対して動的にクエリおよび分析ができます。
  • CloudWatch で、パフォーマンスと潜在的な問題を追跡するためのアラーム通知を作成できます。
  • ワンクリックでContainer Insightsを有効にできます。追加の設定やサイドカーを使用してタスクを監視する必要はありません。

CloudWatch Container Insightsは、Amazon Elastic Kubernetes Service(Amazon EKS)もサポートしています。

概要

この記事では、Container Insightsのセットアップの流れと、Container Insightsダッシュボードを紹介します。このダッシュボードで利用できるAmazon ECSメトリクスを実際にお見せします。また、Container Insights パフォーマンスログにクエリを実行して、特定のメトリクスデータを取得する方法を解説します。最後に、自動的に生成されたデフォルトのダッシュボードを順を追って説明し、タスクを適切なサイズに設定してサービスをスケールする方法を説明します。

新しいクラスターでContainer Insightsをデフォルトで有効にする

まず、現在の IAM ユーザーまたはロールで作成されるクラスターについて、デフォルトでContainer Insightsを有効にするように Amazon ECS サービスを設定します。

  1. Amazon ECS コンソールにアクセスします。
  2. ナビゲーションペインで、Account Settingsを選択します。
  3. Container Insightsのデフォルトのオプトインを有効にするには、ページの下部にあるチェックボックスにチェックを入れます。この設定が有効になっていない場合は、後でクラスターを作成するときにContainer Insightsを有効にすることも可能です。

次に、AWS Fargate用のAmazon ECSワークショップの手順に従って ※1、Container Insightsを有効にしたAmazon ECSクラスターを作成します。Webフロントエンドと複数のバックエンドサービスを持つクラスターを作成しています。

完了したら、次の図のように、公開しているApplication Load BalancerのURLを使用してフロントエンドアプリケーションにアクセスします。

次のコマンドの出力結果を使用してアクセスすることもできます。

alb_url=$(aws cloudformation describe-stacks --stack-name container-demo-alb --query 'Stacks[0].Outputs[?OutputKey==`ExternalUrl`].OutputValue' --output text)
echo "Open $alb_url in your browser"

CloudWatch Container Insightsについて

クラスター作成後、Container Insightsが有効になっていること、そしてCloudWatch が Amazon ECSメトリクスを収集していることを確認するためにコンテナタスクを実行してみましょう。

新しく収集されたメトリクスを表示するには、CloudWatch コンソールに移動し、Container Insightsを選択します。自動ダッシュボードを表示するには、ECS Resource dimensionを選択します。利用可能な Amazon ECS オプションは、ECS クラスター、ECS サービス、および ECS タスクです。ここではECSクラスターを選択します。

ダッシュボードには、クラスターで使用可能なメトリクスが表示されます。これらのメトリクスには、CPU使用率、メモリ使用率、タスク数、サービス数、およびネットワークの使用量が含まれています。

次のダッシュボードの例では、タスクはFargate上で実行されています。またFargate利用時はAWSVPCネットワークモードを利用する必要があります。初期リリースでは、Container Insights はAWSVPC ネットワーキングモードに対するネットワークメトリクスをサポートしていません。次のグラフでは、これらのメトリクスが省略されていることがわかるでしょう。また、このクラスターでは Fargate タスクのみが実行されるように設定されており、コンテナインスタンス数は0となっています。

ページの下部で、ECS クラスタを選択します。ActionsView performance logsの順に選択します。すると、CloudWatch Logsのデータメトリクスに対してすばやく効果的にクエリできるCloudWatch Logs Insightsが表示されます。CloudWatch Logs Insightsではシンプルで強力なコマンドを備えた専用クエリ言語が利用できます。詳細については、CloudWatch Logs Insights を使用したログデータの分析を参照してください。

Container Insightsには、Run queryを選択して実行することができるデフォルトのクエリが用意されています。このクエリは、CloudWatch がクラスターから収集するすべてのメトリクスを分単位でレポートします。 各データ項目を展開して、個々のメトリクスをさらに調べることができます。

CloudWatch Container Insightsを使用すると、統合ビューからECSクラスターをモニタリングし、運用上の問題をすばやく特定して対応できます。

ユースケースについて

このセクションでは、CloudWatchおよびContainer Insightsを使用してクラスターを管理する方法について説明します。クラスターへのトラフィックを生成することから始めましょう。フロントエンドURLに対して、毎秒1回のWebリクエストを行います。

alb_url=$(aws cloudformation describe-stacks --stack-name container-demo-alb --query 'Stacks[0].Outputs[?OutputKey==`ExternalUrl`].OutputValue' --output text)
while true; do curl -so /dev/null $alb_url ; sleep 1 ; done &

CloudWatch Container Insightsダッシュボードで、ECSサービスを選択し、対象のクラスターを選択します。次のダッシュボードのスクリーンショットが示すように、CPUとメモリの使用率は最小限であり、フロントエンドサービスはこの負荷を処理できていることがわかります。

次に、ApacheBench を使用してクラスターへの高トラフィックをシミュレートします。次の ApacheBench コマンドは、9 つの同時要求 (-c 9) を 60 秒 (-t 60) 生成し、Lengthの差異 (-l) を無視します。これを毎秒繰り返しループします。

while true; do ab -l -c 9 -t 60 ${alb_url}/ ; sleep 1; done

メモリ使用率は低いままですが、タスクのCPU使用率は大幅に増加します。

次のスクリーンショットに示すように、ダッシュボードの時間範囲を調整して、過去30分間の各タスクのCPUおよびメモリの平均使用率を確認します。

30 分を超える個々のリソース使用率の平均を表示するには、ダッシュボードの一番下までスクロールします。

任意のタスクを選択し、ActionsView performance logsの順に選択します。すると、ECS クラスターのCloudWatch Logs Insightsが表示されます。クエリボックスに次のクエリを入力し、Run queryを選択し、実行します。

stats avg(CpuUtilized), avg(MemoryUtilized) by bin (30m) as period, TaskDefinitionFamily, TaskDefinitionRevision 
| filter Type = "Task" | sort period desc, TaskDefinitionFamily

クエリの結果を見てみると、フロントエンドサービスの平均 の使用CPU は 229.2273 ユニットで、使用メモリは 71 メガバイトでした。現在のフロントエンドのタスク定義は、512 MiB のメモリと 256 ユニットの CPU を使用するよう定義しています。つまり、フロントエンドサービスは、予約されているほとんどすべての CPU リソースを使用していていることになります。

フロントエンドサービスの、CPUをベースにしたパフォーマンスを改善する1つの方法に、タスクサイズの変更があります。まず、新しいCPU/メモリ値を使った新しいタスク定義のリビジョンを作成します。次に、新しいリビジョンを使用するようにフロントエンドサービスを更新します。

Step 1: タスク定義の新しいリビジョンを作成する

  1. ECSのコンソール画面にて, Task Definitionsを選択する。
  2. ecsdemo-frontendの横のチェックボックスにチェックを入れて、Create new revisionボタンを押下します。
  3. Create new revision of Task Definition 画面のContainer Definitionsの項目で、ecsdemo-frontendを選択します。
  4. Memory Limits (MiB)で、Soft limitを選択し、1024と値を入力します。
  5. ENVIRONMENTの直下にあるCPU units512と値を入力します。
  6. Update ボタンを押下します。
  7. Create new revision of Task Definition 画面のTask size項目にて、0.5 vCPUを選択します。これは512 CPU unitと同義です。
  8. Memoryには1GBを選択します。
  9. Createボタンを押下します。

Step 2: 新しいタスク定義でフロントエンドサービスを更新します。

  1. Clusters画面にて、対象となるクラスターを選択します。
  2. Servicesタブでecsdemo-frontendの横のチェックボックスをオンにし、Updateボタンを押下します。
  3. Task Definition項目で、Step 1で作成したタスク定義のリビジョンを選択します。
  4. Skip to reviewを選択し、最後にUpdate Serviceを選択して更新します。

ECS は、この新しいリビジョンのタスク定義で新しいタスクを起動し、古いタスクを削除します。

ダッシュボードを見ればわかるように、平均CPU使用率は高いままです。つまり現在の負荷では、依然としてほとんどすべての CPU リソースを使用していているということです。ただ明るい話題としては、タスクサイズの変更の結果、フロントエンドサービスのロードバランサーは、5 分間で元々25kのリクエストを処理していたのが、57k のリクエストまで処理できるようになっています。

ApacheBenchのベンチマーク結果も同じ兆候を示しています。クライアントの観点から見ると、フロントエンドサービスは元々のリクエストの 2 倍以上を処理できています。タスクで使用可能な CPU を増やすことで、フロントエンドサービスに対する負荷を処理する能力が向上しています。ただ、フロントエンドサービスは 3 つのタスクで構成されており、CPU 使用率は依然高いままであることを忘れないでください。

CPU メトリクスに基づいてフロントエンドサービスのパフォーマンスを引き続き改善するには、タスクサイズをさらに大きくするか、またはサービスをスケールアウトすると良いでしょう。現在の負荷では、RequestCountPerTargetの値は約 8k/5分です。フロントエンドサービスを更新し、タスクがオートスケーリング するように設定し、RequestCountPerTarget をターゲットあたり 1000 のリクエストに近づけようとします。

次のコマンドを実行して、フロントエンドサービスを更新し、最大 25 のタスクと最低 3 つのタスクでService Auto Scalingをセットアップします。スケーリングポリシーについては、RequestCountPerTarget のターゲット値が 1000 のターゲット追跡スケーリングポリシーを使用します。

cd ~/environment/container-demo
export clustername=$(aws cloudformation describe-stacks --stack-name container-demo --query 'Stacks[0].Outputs[?OutputKey==`ClusterName`].OutputValue' --output text)
export alb_arn=$(aws cloudformation describe-stack-resources --stack-name container-demo-alb | jq -r '.[][] | select(.ResourceType=="AWS::ElasticLoadBalancingV2::LoadBalancer").PhysicalResourceId')
export target_group_arn=$(aws cloudformation describe-stack-resources --stack-name container-demo-alb | jq -r '.[][] | select(.ResourceType=="AWS::ElasticLoadBalancingV2::TargetGroup").PhysicalResourceId')
export target_group_label=$(echo $target_group_arn |grep -o 'targetgroup.*')
export alb_label=$(echo $alb_arn |grep -o 'conta-Publi.*')
export resource_label="app/$alb_label/$target_group_label"

aws application-autoscaling register-scalable-target \
    --service-namespace ecs \
    --scalable-dimension ecs:service:DesiredCount \
    --resource-id service/${clustername}/ecsdemo-frontend \
    --min-capacity 3 \
    --max-capacity 25
 
envsubst <config.json.template >/tmp/config.json
 
aws application-autoscaling put-scaling-policy --cli-input-json file:///tmp/config.json

これで、フロントエンドサービスのスケーリングが開始されます。CloudWatch Container Insightsは、スケーリングの各ステップのタスク数を表示します。

フロントエンドサービスのロードバランサーのリクエストメトリックスを見ると、クラスターがさらに多くのリクエストを処理できていることがわかるでしょう。約153k リクエストまたは ターゲット単位で約6.1k リクエストを、5 分間で処理しています。Auto Scaling ポリシーのタスクの最大数を 25 に設定しなかった場合、閾値がターゲットあたり 1000 リクエストであるため、フロントエンドサービスはさらにスケールアウトされます。

ApacheBenchからも同じ兆候を示しています。フロントエンドサービスはより多くのリクエストを処理でき、リクエストあたりの時間ははるかに短くなります。

CloudWatch Logs Insight のクエリ結果を見ると、CPU の平均使用率は以前に設定された 512 CPU ユニットのうち 158 CPU ユニットの使用であり、比較的低くなっています。

Container Insightsのこれらのメトリクスを使用すると、クラスターをきめ細かく調整することができることがわかるかと思います。リソース不足のタスクを見つけた方法と同様の技術を使用して、オーバーサイズのタスクを見つけ、構成を小さくすることで、今度はコストを削減することができるでしょう。

フロントエンドサービスのスケールインを確認したい場合は、[Ctrl] + [C] を 2 回押してab ループをキャンセルし、負荷を停止します。curl loop の場合は、fg と入力してプロセスをフォアグラウンドに移動し、[Ctrl] + [C] を押します。数分以内に、フロントエンドサービスのスケールインが始まります。

結論

以前は、このようなことを実現するためには、カスタムメトリクスを実装する必要がありました。現在は、Amazon ECS 向け CloudWatch Container Insightsを利用することで、アプリケーションのモニタリングおよび管理に集中できるため、運用上の問題に迅速に対応できるようになります。この機能の、追加されたCPU およびメモリのメトリクスを活用することで、Amazon ECS クラスター、サービス、およびタスクに対してより鋭い洞察を行うことが可能です。また、CloudWatch Log Insights を使用することで、適切なサイジング、アラーム、スケーリングがおこなえ、またパフォーマンスログへのクエリ実行で、より多くの情報に基づいた分析をおこなうことが可能となります。

この記事では、これらの新しい CloudWatchのコンテナのメトリクスを紹介しました。デフォルトで自動生成されるダッシュボードについて解説し、CloudWatch Container Insights コンソールを使用して適切なサイズのタスクとサービスのスケーリングを行う方法を説明しました。また、CloudWatch Logs Insights が提供するパフォーマンスログイベントについて深掘りして確認しました。クエリ言語を使用して特定のメトリクスの値を調査し、適切なサイジング目的での最良な値を選択する方法を示しました。

CloudWatch Container Insightsは、Amazon ECS、AWS Fargate、Amazon EKS、および Kubernetes 向けに一般公開されています。詳細については、Container Insightsの使用に関するドキュメントを参照してください。この機能のフィードバックを送信したり、この機能の更新をメールで受け取るには、containerinsightsfeedback@amazon.comにメールでお問い合わせください。

翻訳はソリューションアーキテクト濵が担当しました。原文はこちらです。

※1 2019/11/11時点で、本Workshop内のセキュリティグループに誤りがあり、サービス間通信が行えません。container-demo-ContainerSecurityGroupというセキュリティグループに、同じセキュリティグループ(container-demo-ContainerSecurityGroup)からのカスタムTCP 3000ポートのインバウンド通信を許可していただくと動作いたします。