AWS CLIでFargateを使用してECSクラスターの作成し、Lambdaを使用してECSイベントをCloudWatchログに書き込んでみた。

2021.11.18

はじめに

Elastic Container Service(ECS)

Amazon ECS は、フルマネージドコンテナサービスであり、クラスターでコンテナを簡単に実行、停止、管理できます。コンテナは、タスク定義で定義されます。新規または既存の VPC 内にECS クラスターを作成できます。AWS Fargate またはAmazon EC2 インスタンスのクラスターでタスクとサービスを実行できます。ECSを使用するには、タスクとサービスを作成する必要があります。

 

Task Definition

タスク定義はECS で Docker コンテナを実行するために使います。1 つのタスク定義に複数のコンテナを定義できます。タスク定義はJSONファイルです。タスク定義は、アプリケーションのパラメータを指定します。

タスク定義のパラメータ:

  • Docker イメージ
  • 起動タイプ
  • CPU とメモリ
  •  ネットワーキングモード
  • コマンド
  • IAM ロール
  • データボリューム

 

ECS Services

サービスを使用して、クラスターで指定された数のタスクを同時に実行することができます。ロードバランサーをECSに関連付けて、トラフィックを分散できます。

 

AWS Fargate

Fargate はECS を使用して、サーバーを管理する必要なくコンテナを実行できるテクノロジーです。Fargateでは、仮想マシンをプロビジョニングと設定する必要がありません。Fargate を使用してタスクやサービスを実行する場合、CPU およびメモリ要件を指定します。

Fargateでは次のオペレーティングシステムがサポートされています:

  • Amazon Linux 2
  • Windows Server 2019 Full
  • Windows Server 2019 Core

 

 

この記事では、CLIを使用してECSクラスターとFargate Linuxタスク定義を作成して、Lambdaを使用してECSイベントをCloudWatch ログに書き込んでみました。

 

やってみた

ECS クラスターの作成

このコマンドを使用して、名前でクラスターを作成しておきます。

aws ecs create-cluster --cluster-name ecs-fargate --region us-east-1

 

 

ECSコンソールでクラスターを見ることができます。

 

タスク定義の登録

Fargate Linuxタスク定義ファイル [ JSON File ] を作成しておきます「task.json」。ファイルには、アプリケーションをホストするために必要なパラメータが含まれています。

 

{
    "family": "fargate-task-Definition", 
    "networkMode": "awsvpc", 
    "requiresCompatibilities": [ "FARGATE" ], 
    "cpu": "256", 
    "memory": "512",
    "containerDefinitions": [
        {
            "name": "fargate-web-app", 
            "image": "httpd:2.4", 
            "portMappings": [
                {
                    "containerPort": 80, 
                    "hostPort": 80, 
                    "protocol": "tcp"
                }
            ], 
            "essential": true, 
            "entryPoint": [ "sh", "-c" ],
            "command": [ "/bin/sh -c \"echo '<html> <head> <title>ECS FARGATE</title> </head><body> <h2>Application hosted using ECS-Fargate</h2></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\"" ]
       }
    ]
}

 

タスク定義パラメータの説明

  • family : ファミリーが必要です。ファミリーは複数バージョンのタスク定義の名前のようなものです。
  • networkMode : ネットワーキングモードはコンテナで使用されます。
    • EC2 Linux インスタンス : 有効な値 -  none, bridge, awsvpc, host 。
    • EC2 Windows インスタンス :  有効な値  - default , awsvpc。
    • Fargate : 有効な値  -  awsvpc。
  • 起動タイプ -  "requiresCompatibilities" - 有効な値:  EC2, FARGATE, EXTERNAL
  • Task size : タスクに使用される CPU とメモリの合計量を指定します。
    • cpu
    • memory
  • containerDefinitions : コンテナの Docker デーモンに渡されるコンテナ定義のリストを指定します。
    • name :コンテナの名前。
    • image : コンテナの開始に使用するイメージ。
    • portMappings: ポートを指定します。
    • essential : true - コンテナが停止すると、タスクのすべてのコンテナは停止されます。

 

このコマンドを使用してタスク定義を登録しておきます。

aws ecs register-task-definition --cli-input-json file://task.json --region us-east-1

 

作成したタスクはECSコンソールで確認できます。

 

サービスの作成

CLIでこのコマンドを使用してパブリックサブネットにサービスを作成しておきます。

aws ecs create-service --cluster ecs-fargate --service-name FargateService --task-definition fargate-task-Definition:1 --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[subnet-id],securityGroups=[sg-id],assignPublicIp=ENABLED}" --region us-east-1

 

コンソールでサービスを見ることができます。

 

  • タスクのENIのPublic DNSを使ってWebApplicationをチェックしておきます。

 

Lambda 関数の作成

名前 を入力して、Runtimeで Python 3.7 を選択して、Lambda 関数を作成しておきます。

 

Function codeで、コードを編集しておきます。

import json
def lambda_handler(event, context):
    if event["source"] != "aws.ecs":
       raise ValueError("Supports input from ECS Service only")
    print(json.dumps(event))

 

イベントルールの作成

  • EventBridgeコンソールで、RulesでCreate ruleを選択しておきます。
  • イベントの名前 を入力して、Define patternでこれらのオプションを選択しておきます。
    • Event matching pattern : Pre-defined pattern
    • Service provider : AWS
    • Service Name : ECS
    • Event type : All Events

 

 

  • TargetでLambdaを選択して、イベントルールの作成しておきます。

 

イベントのログの詳細を確認する

  • 新しいタスクを作成するか、既存のタスクを停止します。このアクションにより、いくつかのイベントログが作成されます。
  • CloudWatchコンソールで、Logsを選択して Lambda 関数のロググループを選択して、イベントのログを見ることができます。

 

 

ログのスクリーンショット

 

まとめ

AWS CLIでECSクラスターとFargate Linuxタスク定義を作成して、Lambdaを使用してECSイベントをCloudWatch ログに書き込んでみました。