FargateでContainer Insightsを有効化してトラフィックでアラームを設定する
以下のページで、FargateタイプのECSにおいて、CPU使用率が閾値を超えた時に、CloudWatchアラームでメール通知する構成をご紹介しました。
ECSクラスターのContainer Insight機能を有効化すると、より詳細なメトリクスを取得することができます。
今回はContainer Insightで取得できるトラフィック情報を使って、CloudWatchアラームでメール通知することを目指します。
構築する環境
プライベートサブネットに、FargateタイプのECSを作成します。
ECSクラスターのContainer Insight機能を有効化します。
プライベートサブネットからCloudWatchにメトリクスを配信するために、コンテナ用サブネットに、メトリクス用VPCエンドポイントを作成します。
CloudWatchアラームで、ネットワークの送信量/受信量に関する閾値を設定します。
通信量が100Bytes/Secを超えた時に、SNSにメッセージをパブリッシュするように設定します。
SNSはメールアドレスをサブスクライバーとして設定します。
EC2インスタンスを作成します。
コンテナにアクセスするためのクライアントして使用します。
2つの目的で、NATゲートウェイを作成します。
1つ目はECSコンテナを作成するために、DockerHubからNginxの公式イメージを取得するためです。
2つ目はEC2インスタンスにApache Benchをインストールするためです。Apache BenchはECSコンテナに対して実行し、大量のリクエストを生成することで、CPU使用率を高めてアラームを発生させます。
上記の用途での使用が済めば、NATゲートウェイは不要となります。
今回はCloudFormationカスタムリソースを使用して、最終的にNATゲートウェイ等を削除するように設定します。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/072
テンプレートファイルのポイント解説
今回の構成は、基本的に冒頭でご紹介したページと同様です。
本ページはContainer Insightを有効化し、そこから取得できるメトリクスからアラームを設定する方法を中心に取り上げます。
Container Insightの有効化
Resources:
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${Prefix}-cluster"
ClusterSettings:
- Name: containerInsights
Value: enabled
Code language: YAML (yaml)
Container Insightはクラスターリソースで有効化します。
ClusterSettingsプロパティにおいて、Nameに「containerInsights」を、Valueに「enabled」を設定することで、Container Insightを有効化します。
CloudWatchアラーム
Resources:
Alarm1:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Ref TopicArn
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: ClusterName
Value: !Ref ClusterName
- Name: ServiceName
Value: !Ref ServiceName
EvaluationPeriods: 1
MetricName: NetworkRxBytes
Namespace: ECS/ContainerInsights
Period: 60
Statistic: Average
Threshold: 100
Unit: Bytes/Second
Alarm2:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Ref TopicArn
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: ClusterName
Value: !Ref ClusterName
- Name: ServiceName
Value: !Ref ServiceName
EvaluationPeriods: 1
MetricName: NetworkTxBytes
Namespace: ECS/ContainerInsights
Period: 60
Statistic: Average
Threshold: 100
Unit: Bytes/Second
Code language: YAML (yaml)
Container Insightから取得できるメトリクスを使用して、CloudWatchアラームを設定する場合、Namespaceプロパティに「ECS/ContainerInsights」を設定します。
取得するメトリクスの対象をクラスター・サービスレベルで条件づける場合、Dimensionsプロパティに「ClusterName」および「ServiceName」を指定します。
Container Insightから取得できるネットワーク関係の情報は「NetworkRxBytes」と「NetworkTxBytes」があります。
それぞれ受信量と送信量です。
2つのアラームのMetricNameプロパティに、それぞれを設定します。
ComparisonOperator、EvaluationPeriods、Period、Statistic、Thresholdプロパティでアラーム条件を設定します。
これらをまとめますと、60秒ごとに受信量/送信量を評価し、過去1回分のメトリクスの平均値が100Bytes/Secを超えた場合は、アラーム条件を満たすということになります。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- SNSトピック:fa-072
- ECSクラスター:fa-072-cluster
- ECSサービス:fa-072-service
- EC2インスタンス:i-06b8f677825287fba
メールアドレスの認証
SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。
詳細につきましては、以下のページをご確認ください。
リソース確認
AWS Management Consoleから各リソースを確認します。
SNSトピックを確認します。
正常にSNSトピックが作成されていることがわかります。
加えて、サブスクライバーとして登録したメールアドレスが登録されていることもわかります。
またこのメールアドレスのStatusの値を見ると「Confirmed」とあり、認証が完了していることもわかります。
続いてECS(Fargate)を確認します。
正常にECSクラスター・サービス・タスクが作成されています。
Dockerhubから最新版のNginxのイメージを取得し、そこからコンテナが作成されています。
タスクに割り当てられているプライベートアドレスが「10.0.3.230」ということもわかります。
CloudWatchアラームを確認します。
まず受信量のアラームです。
正常にアラームが作成されています。
現在は閾値である100Bytes/Sec未満であるため、状態は「OK」であり、アラーム状態にはなっていません。
次に送信量のアラームです。
こちらも正常にアラームが作成されています。
現在は閾値である100Bytes/Sec未満であるため、状態は「OK」であり、アラーム状態にはなっていません。
動作確認
準備が整いましたので、EC2インスタンスにアクセスします。
インスタンスへのアクセスはSSM Session Managerを使用します。
% aws ssm start-session --target i-06b8f677825287fba
Starting session with SessionId: root-089994be40366b049
sh-4.2$
Code language: Bash (bash)
SSM Session Managerの詳細につきましては、以下のページをご確認ください。
curlコマンドを使って、タスク内のコンテナにアクセスします。
sh-4.2$ curl http://10.0.3.230/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Code language: Bash (bash)
正常にアクセスできました。
Fargate上でNginxコンテナが動作していることがわかります。
これからFargateの送受信量を上昇させて、CloudWatchアラームにアクションを起こさせます。
送受信量を高めるために、Apache Benchを使用して、大量のリクエストを生成して負荷をかけます。
まずApacheがインストールされている確認します。
sh-4.2$ sudo yum list installed | grep httpd
generic-logos-httpd.noarch 18.0.0-4.amzn2 @amzn2-core
httpd.aarch64 2.4.54-1.amzn2 @amzn2-core
httpd-filesystem.noarch 2.4.54-1.amzn2 @amzn2-core
httpd-tools.aarch64 2.4.54-1.amzn2 @amzn2-core
Code language: Bash (bash)
ユーザーデータによって、正常にApacheがインストールされたようです。
Apache Benchを実行します。
Fargate上のコンテナ(タスク)に対して、10万回のリクエストを生成します。
sh-4.2$ ab -n 100000 http://10.0.3.230/
This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 10.0.3.230 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/1.23.1
Server Hostname: 10.0.3.230
Server Port: 80
Document Path: /
Document Length: 615 bytes
Concurrency Level: 1
Time taken for tests: 35.863 seconds
Complete requests: 100000
Failed requests: 0
Total transferred: 84800000 bytes
HTML transferred: 61500000 bytes
Requests per second: 2788.38 [#/sec] (mean)
Time per request: 0.359 [ms] (mean)
Time per request: 0.359 [ms] (mean, across all concurrent requests)
Transfer rate: 2309.13 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 0 0 0.0 0 1
Waiting: 0 0 0.0 0 1
Total: 0 0 0.1 0 1
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 1
98% 1
99% 1
100% 1 (longest request)
Code language: Bash (bash)
Apache Benchによる負荷によって、送受信量が高まったはずです。
改めてCloudWatchアラームを確認します。
送受信量が100Bytes/Secを超えました。
閾値を超えましたので、2つのアラーム状態が「OK」から「In alarm」に変更になりました。
履歴を見ると、アラーム状態になったことによって、Actionとして、SNSにメッセージを送信したことがわかります。
すぐさま登録したアドレスに、以下の2つのメールが届きます。
メールの本文は、CloudWatchアラームの内容となっています。
このようにContainer Insightで取得できるメトリクスを使って、CloudWatchアラームでメール通知することができました。
まとめ
Container Insightで取得できるメトリクスを使って、CloudWatchアラームでメール通知する方法を確認しました。