Amazon ECSのAmazon CloudWatch Container Insightsでオブザーバビリティ強化されたので、AWS X-Rayとともに検証してみた

はじめに

re: Invent2024期間中に「Amazon ECSのAmazon CloudWatch Container Insightsでオブザーバビリティが強化」するアップデートがありました。

Amazon ECS タスク・サービスレベルのモニタリング可能になるという 激アツ アップデートだったのですが、AWS X-Rayとの連携強化もされたとのことでした。
そんなことを聞いたら、「AWS X-Ray含めて触ってみたいじゃん!!」と、思っていたところ...
ちょうど良いサンプルを見つけたので実際に展開して、強化されたオブザバビリティを体験してみようと思います!

アップデートについて

Amazon CloudWatch Container Insights が Amazon ECS のオブザーバビリティを強化

もともと、Amazon EKSでは2023年に登場していた機能が今年ついに、Amazon ECS(EC2/Fargate)でも利用可能になりました!

主なアップデート内容は下記の通りです。

  • Amazon ECS タスク・コンテナレベルの詳細なリソースモニタリング
  • コンテナからドリルアップおよびドリルダウンし、個々のコンテナの問題を直接特定可能になった(AWS X-RayやCloudWatch Logsとの連携強化)
  • 複数アカウントにわたるクラスター監視

が可能となりました。

設定方法も簡単で、「クラスター / AWSアカウント」レベルに対し、ボタン一つでの設定が可能となっています。また、既存クラスターへの設定更新も可能です。

設定方法は下記でも触れていきます。

実際に検証した内容

構成

こちらのGitHubのサンプル(example-for-aws-xray-in-amazon-ecs)をもとに、AWS X-Rayを含んだ、Amazon ECS - Fargateの分散アプリケーションを利用します。

READMEに記載の通りですが、それぞれのコンテナの役割は下記の通りです。

  • フロントエンド(nginx、html)
    BFFにリクエストを送り、その結果を表示するシンプルなhtmlファイルを返す。

  • BFF(Express、Node.js)
    バックエンド#1、#2に順次リクエストを送り、その結果をJSON形式で返す。

  • Backend #1 (Flask, Python)
    現在の日付情報をJSON形式で応答し、ログ(最終アクセス時刻)をDynamoDBに書き込む。

  • Backend #2 (Django, Python)
    現在の時刻情報をJSON形式で応答し、ログ(最終アクセス時刻)をDynamoDBに書き込みます。

また、トレースデータは、AWS X-Ray SDKとAmazon ECSタスク上のAWS X-Ray Daemonを使用して、BFF、Backend #1、Backend #2を介して取得され、関連付けられます。

今回の作業環境

CloudShellを利用しました。バージョンは下記の通りです。

  • 作業環境: CloudShell
  • SAM CLI: 1.126.0

サンプルを展開する

まずはCloudShell上でサンプルアプリ一式を取得します。

デプロイのための設定ファイルを編集します。

下記の通りになっていますので、特にこだわりがなければデフォルトで良いです。
今回はCloudShell上からAssumeRoleはせず、現在のIAMユーザの権限でデプロイをしたいので、下記の通り1行コメントアウトします。

私は今回下記でデプロイしました。
必要に応じて、APP_ID/ENV_IDも修正してください。作成されるリソース名にこれらの名前がつきます。

envファイルが完成したら、
下記コマンドを実行して、SAMからAWSリソースを展開します。

コマンド実行後CloudFomrationやらFargate用のアプリデプロイが走るため、15~20分くらい実行を待ちます。
下記の通り、表示されれば実行成功です。

Successfully created/updated stack - --svc-frontend-stack in ap-northeast-1
Script [install.sh] completed

今回はこちらをさらに2つほど、カスタマイズしていきます。

追加設定1: 強化されたAmazon CloudWatch Container Insights の有効化

Amazon CloudWatch Container Insights が Amazon ECS のオブザーバビリティを強化

こちらのアップデートについて設定をしてきます。
今回は「ECSクラスター」に設定をします。

「 ECSクラスター」 - 「編集」
から、モニタリングの項目を更新します。

オブザーバビリティが強化された Container Insights

を有効にして保存します。

これだけで、今まではECS クラスター・サービスまでしか取得できなかったリソースメトリクスが拡張され、ECS タスク・コンテナレベルのリソースメトリクスも取得可能となります!!
簡単ですね〜。

追加設定2: Synthetics Canaryを設定する

外形監視用途でSynthetics Canaryも設定します。

展開された、CloudFormationスタックから下記を見つけます。

APP_ID-ENV_ID-svc-base-stack

このスタックの「出力」からフロントエンドALBのDNS名を確認します。

DNS名をCanaryに設定し外形監視を設定しておきます。また、アラームも設定しておきます。

Amazon CloudWatch - Application Signals - Synthetics Canaries
から、「Canaryを作成」を押下します。

設計図を使用する - ハートビートのモニタリング
を選択し、

  • 名前:「任意の名前」
  • アプリケーションまたはエンドポイント URL:「先ほどのALBのDNS名」

を設定します。

URLの実行失敗に対するアラームも設定しておきます。

以上で、一通り環境設定は完了です。

AWS X-Rayの動作検証

動作検証その1: DynamoDBの書き込み遅延を発生させてみる

バックエンドのDB処理にレイテンシが発生しているケースを見てみます。

下記gifのように、Webページの応答処理が遅延するケースを見てみます。
実際にもよくありがちなケースで、サーバ負荷が高かったり、DB処理が詰まっていたりという原因が主に考えられます。

事前準備

DynamoDBへの書き込み自体を遅延させたかったのですが、今回は手っ取り早くsleep処理を挟んで時間がかかるようにします。

こちらへ、Backend#2の書き込み処理に時間がかかる細工をします。
32~33行目の通り

を追加します。これで処理時間が+5secかかるようになりました。

今回、コンテナのアップデート方法は省略しますが、同様にCloudShell上で、
Dockerイメージのビルド→ECRへイメージ更新→ECSの更新
を行なっています。

ECSの更新が完了後再度アプリにアクセスすると

現在時刻の表示に時間がかかるようになったのがわかります。
この原因を何も知らないていで、運用保守担当になった気持ちで、AWSコンソール上から追ってみようと思います。

確認1: Synthetics Canaryをみてみる

まずは外形監視を確認してみます。
今回は「Webページは表示はされるものの、通常と比べると表示が遅い」というものになっています。今回のCanaryはステータスコードによる異常をモニタリングするものになっているため、異常は検知していません。

今回は、ここからは何もわからなそうでした。

確認2: Container Insightsをみてみる

続いてContainer Insightsです。本ブログの序盤で紹介したアップデート内容も含んでいます。

今まではサービスごとまでしかリソース状況を確認できませんでしたが、今回のアップデートでECSタスク/コンテナレベルの確認もできるようになっています。
各アプリのリソース状況が簡単にわかるようになったため、スペック不足の判断やタスク固有の異常の特定など調査が捗りそうです。

ただ、今回はこちらもリソース状況に異常は見受けられず、リソース不足による問題ではないことがわかります。

続いて、x-rayを確認しますが、
Container Insightsのページ下部から飛べるようになったのも便利アップデートですね。

確認3: X-Rayをみてみる

続いて、X-Rayでアプリケーションのトレースを確認してみます。
下記の通り対象のノードを選択し、トレースの絞り込みを行います。

「応答時間」でソートしてみると何やらものすごく時間がかかっている処理がありそうです。
試しに開いてみます。

すると、バックエンド処理#2にすごく時間がかかっていることがわかります。これでほぼ犯人は特定できたので、あとは原因を特定する作業になっていきます。

今回はコンポーネント間通信(DynamoDBへの処理)に遅延を発生させませんでした。
そのため、「Backend#2」の処理時間が伸びていますが、本来ですと、「Backend#2 - DynamoDB」が伸びるような表示になるはずです。その時に考えられるのが、、、

  • DynamoDBのスキャン量が多くて「DynamoDB」処理が遅延している
    → クエリの最適化
  • DynamoDBのキャパシティ容量不足しているため遅延している
    → キャパシティ見直し

などが発生していると思うのでその問題対策をおこなっていく形となります。

どちらにせよ、リソースモニタリングやURL監視だけではここまで深い調査を行うことは難しいかったので、コンポーネントが複数存在してやりとりが行うようなシステムではX-Rayはすごく便利そうです。

動作検証その2: DynamoDBの権限剥奪

いろいろ触っている中で便利そうな機能があったので紹介します。

なんらかのオペレーションミスでセキュリティグループの設定や、IAMの権限不足など、追加開発時に設定が一部足りていないことはよくあることかと思います。その原因調査をX-Rayの方から見てみようと思います。

まずは下記の通り、backend用 ECSタスクロールからDynamoDBの権限を削除します。

Webページ上の表示は問題ないように見えますが、DynamoDBの権限を削除したのでDynamoDBのレコードは更新されておらず、Webページの表示とDBに保存されている値に差異が出てしまっています。

今回は省略してX-Rayだけ確認します。

X-Rayの画面からBackend#2のトレースを確認します。
ノードから「Backend#2」を選択し、「クエリに追加」を押下後、「クエリの実行」を押下します。

すると直近のトレース結果が表示されるので一つ確認してみます。

まずはトレースマップです。
DynamoDBへの接続が失敗していることがわかります。

もう少し詳しく確認するには下部にある、「セグメントのタイムライン」から確認できます。

「障害 (5xx)」となっている項目を押下し、「例外」を確認します。
すると、なぜエラーとなっているかそのログを確認することができ、スタックトレースも出ています。

CloudWatchLogsに出力しているアプリケーションログ等を追わずともX-Rayからエラー内容を確認できるのは素晴らしく便利ですね。

まとめ

今回は、「Amazon ECSのAmazon CloudWatch Container Insightsでオブザーバビリティ強化された」アップデートを機にContainer Insights/X-Rayを触ってみました。
従来のモニタリングだけではわからなかった問題も、アップデートでオブザーバビリティ・各サービスの連携がより強化されたおかげもあり、調査時間がすごく短縮できそうなことがわかりました!
今回は活躍しませんでしたが、コンテナレベルのリソースモニタリングも役立つ機能間違いなし!なので、ECSの本番運用時は積極的に取り入れることをおすすめします。

アプリ開発を行なっている方・オブザバビリティに興味がある方はぜひ導入検討してみてください。

投稿者プロフィール

makuta
2024 Japan AWS Top Engineers

AWSを使ったサーバレスアーキテクチャ・コンテナサービスの設計・構築を担当。