AWS

ECSのCPU使用率が閾値を超えた時にCloudWatchアラームでメール通知する

スポンサーリンク
ECSのCPU使用率が閾値を超えた時に、CloudWatchアラームでメール通知する AWS
スポンサーリンク
スポンサーリンク

ECS(Fargate)のCPU使用率が閾値を超えた時に、CloudWatchアラームからSNSでメール通知する

FargateタイプのECSを作成すると、デフォルトでCPUとメモリ使用率がCloudWatchメトリクスに配信されます。
今回はCloudWatchアラームを使って、CPU使用率に閾値を設定し、上限を超えた時にメールで通知することを目指します。

構築する環境

Diagram of Email notification via CloudWatch Alarm when ECS CPU usage exceeds threshold.

プライベートサブネットに、FargateタイプのECSを作成します。

プライベートサブネットからCloudWatchにメトリクスを配信するために、コンテナ用サブネットに、メトリクス用VPCエンドポイントを作成します。

CloudWatchアラームで、CPU使用率に関する閾値を設定します。
使用率が0.1%を超えた時に、SNSにメッセージをパブリッシュするように設定します。

SNSはメールアドレスをサブスクライバーとして設定します。

EC2インスタンスを作成します。
コンテナにアクセスするためのクライアントして使用します。

2つの目的で、NATゲートウェイを作成します。
1つ目はECSコンテナを作成するために、DockerHubからNginxの公式イメージを取得するためです。
2つ目はEC2インスタンスにApache Benchをインストールするためです。Apache BenchはECSコンテナに対して実行し、大量のリクエストを生成することで、CPU使用率を高めてアラームを発生させます。

上記の用途での使用が済めば、NATゲートウェイは不要となります。
今回はCloudFormationカスタムリソースを使用して、最終的にNATゲートウェイ等を削除するように設定します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

awstut-fa/070 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

テンプレートファイルのポイント解説

ECS(Fargate)に関する基本的な事項は、以下のページをご確認ください。

プライベートサブネットにFargateを配置する方法については、以下のページをご確認ください。

CloudFormationカスタムリソースを使用して、NATゲートウェイ等を自動的に削除する方法については、以下のページをご確認ください。

SNSトピック

Resources: Topic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref MailAddress Protocol: email TopicName: !Ref Prefix
Code language: YAML (yaml)

Subscriptionプロパティがポイントです。
サブスクライバーとしてメールアドレスを指定する場合は、Protocolプロパティに「email」を、Endpointプロパティにメールアドレスを指定します。

メールアドレスをSNSサブスクライバーに指定する方法については、以下のページをご確認ください。

VPCエンドポイント

Resources: CloudWatchMetricsEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref EndpointSecurityGroup2 ServiceName: !Sub "com.amazonaws.${AWS::Region}.monitoring" SubnetIds: - !Ref ContainerSubnet VpcEndpointType: Interface VpcId: !Ref VPC
Code language: YAML (yaml)

プライベートサブネットに配置されたFargateのメトリクスをCloudWatchに配信するためには、メトリクス用VPCエンドポイントを作成します。

以下が本エンドポイントに適用するセキュリティグループです。

Resources: EndpointSecurityGroup2: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-EndpointSecurityGroup2" GroupDescription: Allow HTTPS from ContainerSecurityGroup. VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: !Ref HTTPSPort ToPort: !Ref HTTPSPort SourceSecurityGroupId: !Ref ContainerSecurityGroup
Code language: YAML (yaml)

Fargateに適用したセキュリティグループを送信元として、443/tcpのインバウンド通信を許可する内容です。

CloudWatchアラーム

Resources: Alarm: Type: AWS::CloudWatch::Alarm Properties: AlarmActions: - !Ref TopicArn ComparisonOperator: GreaterThanThreshold Dimensions: - Name: ClusterName Value: !Ref ClusterName - Name: ServiceName Value: !Ref ServiceName EvaluationPeriods: 1 MetricName: CPUUtilization Namespace: AWS/ECS Period: 60 Statistic: Average Threshold: 0.1
Code language: YAML (yaml)

AlarmActionsプロパティで、アラーム条件を満たした時に実行するアクションを設定します。
先述のSNSトピックを指定し、SNSのパブリッシャーに登録します。

Namespaceプロパティで、メトリクスを収集する対象サービスを設定します。
ECS/Fargateのメトリクスを収集する場合は、「AWS/ECS」を指定します。

MetricNameプロパティで収集するメトリクスを設定します。
CPU使用率を収集したいので、「CPUUtilization」を指定します。

Dimensionsプロパティで、対象のECS/Fargateリソースを特定するための特徴を指定します。
ECS/Fargateの場合、2つの特徴を設定できます。

  • ClusterName:ECSクラスターの名前
  • ServiceName:ECSサービスの名前

ComparisonOperator、EvaluationPeriods、Period、Statistic、Thresholdプロパティでアラーム条件を設定します。
これらをまとめますと、60秒ごとにCPU使用率を評価し、過去1回分のメトリクスの平均値が0.1%を超えた場合は、アラーム条件を満たすということになります。

(参考)EC2インスタンス

Resources: Instance: Type: AWS::EC2::Instance Properties: IamInstanceProfile: !Ref InstanceProfile ImageId: !Ref ImageId InstanceType: !Ref InstanceType NetworkInterfaces: - DeviceIndex: 0 SubnetId: !Ref InstanceSubnet GroupSet: - !Ref InstanceSecurityGroup UserData: !Base64 | #!/bin/bash -xe yum update -y yum install httpd -y
Code language: YAML (yaml)

特別な設定は不要です。
UserDataプロパティで、インスタンスの初期化時にApacheをインストールするように記載します。

ユーザーデータに関する詳細につきましては、以下のページをご確認ください。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • SNSトピック:fa-070
  • ECSクラスター:fa-070-cluster
  • ECSサービス:fa-070-service
  • EC2インスタンス:i-02da326aa09a0a86c

メールアドレスの認証

SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。

詳細につきましては、以下のページをご確認ください。

リソース確認

AWS Management Consoleから各リソースを確認します。

SNSトピックを確認します。

Detail of SNS.

正常にSNSトピックが作成されていることがわかります。

加えて、サブスクライバーとして登録したメールアドレスが登録されていることもわかります。
またこのメールアドレスのStatusの値を見ると「Confirmed」とあり、認証が完了していることもわかります。

続いてECS(Fargate)を確認します。

Detail of ECS 1.
Detail of ECS 2.

正常にECSクラスター・サービス・タスクが作成されています。
Dockerhubから最新版のNginxのイメージを取得し、そこからコンテナが作成されています。
タスクに割り当てられているプライベートアドレスが「10.0.3.221」ということもわかります。

CloudWatchアラームを確認します。

Detail of CloudWatch Alarm 1.
Detail of CloudWatch Alarm 2.

アラームが正常に作成されています。
ディメンジョン情報に基づいて、先ほど確認したFargateのCPU使用率が収集できています。
現在は閾値である0.1%未満であるため、状態は「OK」であり、アラーム状態にはなっていません。

動作確認

準備が整いましたので、EC2インスタンスにアクセスします。
インスタンスへのアクセスはSSM Session Managerを使用します。

% aws ssm start-session --target i-02da326aa09a0a86c Starting session with SessionId: root-0a2289244a1ac6d6f sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

curlコマンドを使って、タスク内のコンテナにアクセスします。

sh-4.2$ curl http://10.0.3.221/ <!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のCPU使用率を上昇させて、CloudWatchアラームにアクションを起こさせます。
CPU使用率を高めるために、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.221/ 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.221 (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.221 Server Port: 80 Document Path: / Document Length: 615 bytes Concurrency Level: 1 Time taken for tests: 37.224 seconds Complete requests: 100000 Failed requests: 0 Total transferred: 84800000 bytes HTML transferred: 61500000 bytes Requests per second: 2686.45 [#/sec] (mean) Time per request: 0.372 [ms] (mean) Time per request: 0.372 [ms] (mean, across all concurrent requests) Transfer rate: 2224.71 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 6 Processing: 0 0 0.1 0 11 Waiting: 0 0 0.1 0 11 Total: 0 0 0.1 0 11 Percentage of the requests served within a certain time (ms) 50% 0 66% 0 75% 0 80% 0 90% 1 95% 1 98% 1 99% 1 100% 11 (longest request)
Code language: Bash (bash)

Apache Benchによる負荷によって、CPU使用率が高まったはずです。

改めてCloudWatchアラームを確認します。

Detail of CloudWatch Alarm 3.
Detail of CloudWatch Alarm 4.

CPU使用率が8%を超えました。
アラーム発生の閾値を超えましたので、状態が「OK」から「In alarm」に変更になりました。
履歴を見ると、アラーム状態になったことによって、Actionとして、SNSにメッセージを送信したことがわかります。

すぐさま登録したアドレスに、以下のメールが届きました。

Email from SNS.

メールの本文は、CloudWatchアラームの内容となっています。
このようにCloudWatchアラームを使用することによって、特定のメトリクスが閾値を超えた時に、SNSと連携してメールで通知することができました。

まとめ

CloudWatchアラームを使って、Fargateのメトリクスに閾値を設定し、上限を超えた時にメールで通知する方法を確認しました。

タイトルとURLをコピーしました