Amazon Elastic Container Service(Amazon ECS)は、クラスター上のDockerコンテナーを簡単に実行、停止、および管理できる、Amazon独自の非常にスケーラブルで高性能なコンテナー管理サービスです。
ECSを使用すると、独自のクラスター管理インフラストラクチャをインストール、操作、および拡張する必要がなくなります。Dockerアプリケーションの起動と停止、クラスターステータスのクエリなどを実行できるのは、単純なAPI呼び出しだけです。クラスター内のコンテナーの場所は、リソース要件、分離戦略、および可用性要件に従って調整できます。ECSは、Amazon Elastic Container Registry、Elastic Load Balancing、Elastic Block Store、Elastic Network Interfaces、Virtual Private Cloud、IAMおよびCloudTrailを統合して、さまざまなコンテナー化されたアプリケーションまたはサービスを実行するための完全なソリューションを提供します。
ECSは、Amazon SageMakerやAmazon Lexなど、他の多くのAWSサービスに適用されている実績のあるソリューションです。これは、ECSの安全性、信頼性、および可用性を証明するのに十分であり、実稼働環境で使用できます。
スタートアップの種類
ECSは、FargateとEC2の2つのスタートアップタイプをサポートしています。
Fargateスタートアップの種類
Fargateスタートアップタイプは、基盤となるインフラストラクチャを構成および管理する必要はありません。コンテナ化されたアプリケーションを実行するには、タスク(Kubernetesポッドと同等)を定義し、CPU、メモリ、ネットワーク、IAMポリシーなどを指定するだけです。
EC2スタートアップの種類
EC2起動タイプを使用すると、コンテナ化されたアプリケーションを、それ自体が管理するEC2インスタンスのクラスターで実行できます。
Fargate起動タイプを使用して、Amazon EC2インスタンスサーバーまたはクラスターを管理する必要なく、サービスまたはタスクを開始し、ECSによって管理されるサーバーレスインフラストラクチャで実行できます。より細かく制御するには、EC2スタートアップタイプを使用できます。
以下では、Fargateスタートアップタイプを使用して、Angular 9統合Spring Boot 2 Spring BootおよびAngularアプリケーションをデプロイする方法について説明します。
Dockerイメージを作成する
Spring BootプロジェクトのDockerfileファイル:
Dockerfile.spring
FROM openjdk:8-jdk-slim
WORKDIR app
ARG APPJAR=target/heroes-api-1.0.0.jar
COPY ${APPJAR} app.jar
ENTRYPOINT ["java","-jar","app.jar"]
AngularプロジェクトのDockerfile:
Dockerfile.angular
FROM httpd:2.4
ARG DISTPATH=./dist/
ARG CONFFILE=./heroes-httpd.conf
COPY ${DISTPATH} /usr/local/apache2/htdocs/
COPY ${CONFFILE} /usr/local/apache2/conf/httpd.conf
例としてApacheへのデプロイメントを取り上げ、次のコマンドを実行してhttpd.confを取得します。
docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf> heroes-httpd.conf
構成ファイルを変更し、proxy_module、proxy_http_module、rewrite_moduleを有効にしてから、次のコンテンツを追加します。
ProxyPreserveHost on
ProxyPass "/api" "http://127.0.0.1:8080/api"
ProxyPa***everse "/api" "http://127.0.0.1:8080/api"
RewriteEngine on
RewriteRule ^/$ /en/index.html
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^/zh /zh/index.html
RewriteRule ^/en /en/index.html
Apacheプロキシバックエンドアドレスを使用して、これら2つのイメージをタスクに含めます。
イメージのビルド
次のコマンドを実行して、イメージをビルドします。
docker build --build-arg APPJAR=heroes-api-1.0.0.jar -f Dockerfile.spring -t heroes-api .
docker build -f Dockerfile.angular -t heroes-web .
画像をECRにプッシュ
Amazon Elastic Container Registry(Amazon ECR)は、開発者がDockerコンテナーイメージを簡単に保存、管理、デプロイできるDocker Container Registryサービスです。
- ECRリポジトリを作成する
まず、コンソールから作成できる2つのECRリポジトリを作成するか、次のAWS CLIコマンドを実行します。
aws ecr create-repository --repository-name heroes/heroes-api
aws ecr create-repository --repository-name heroes/heroes-web
- ECRリポジトリにログインします。
次のコマンドを実行します。
`aws ecr get-login --no-include-email`
或
aws ecr get-login-password | docker login --username AWS --password-stdin 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn
- 画像をマーク
docker tag heroes-api:latest 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-api:latest
docker tag heroes-web:latest 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-web:latest
- イメージをプッシュ
docker push 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-api:latest
docker push 888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-web:latest
クラスターを作成する
Amazon ECSクラスターは、タスクまたはサービスの論理的なグループです。1つのアカウントで複数のクラスターを作成して、リソースを独立させることができます。
Fargateクラスターの作成は非常に簡単です。ECSクラスターコンソールに入り、[クラスターの作成]をクリックし、[ネットワークのみ]クラスターテンプレートを選択し、[次へ]をクリックして、クラスター名「heroes」を入力し、[作成]をクリックします。
タスク定義を作成する
タスク定義はアプリケーションのブループリントに似ており、Amazon ECSでDockerコンテナーを実行するにはタスク定義が必要です。
Fargateタスク定義で指定できるいくつかのパラメーター:
- タスクのDockerイメージ
- タスクのCPUとメモリの数
- タスクログの構成
- タスクが使用するIAMロール
- タスクのコンテナーに使用されるデータ量
- コンテナーが開始時に実行するコマンド
タスク定義を作成するには、次の手順を実行します。
- ECSタスク定義コンソールに入り、[タスク定義の作成]をクリックします
- FARGATEスタートアップの種類を選択し、[次へ]をクリックします
- 構成タスクおよびコンテナー定義ページで、タスク定義名(ヒーロー)を入力し、タスクの役割を選択して、タスクのメモリーとCPUを構成します
メモリとCPUの効果的な組み合わせ
CPU値 | メモリ値(MiB) |
---|---|
256(.25 vCPU) | 512 MB、1 GB、2 GB |
512(.5 vCPU) | 1 GB、2 GB、3 GB、4 GB |
1024(1 vCPU) | 2 GB、3 GB、4 GB、5 GB、6 GB、7 GB、8 GB |
2048(2 vCPU) | 4GBから16GB(1GB刻み) |
4096(4 vCPU) | 8GBから30GB(1GB刻み) |
コンテナストレージと共有ボリュームの
Fargateスタートアップタイプ。タスクの最大コンテナストレージは10GBで、複数のコンテナが使用する共有ボリュームの最大サイズは4GBです。共有ボリュームを追加するには、[ボリューム構成]セクションの[ボリュームの追加]をクリックし、ボリューム名を入力して[追加]をクリックします。タスクストレージは短期間のストレージであることに注意してください。Fargateタスクが停止すると、ストレージは削除されます。
コンテナーを追加する
次に、コンテナー定義セクションの[コンテナーの追加]ボタンをクリックして、heroes-apiコンテナーとheroes-webコンテナーを
追加します。マウントポイントと構成ログは、高度なコンテナー構成の下部にある[ストレージとログ]セクションに追加できます:
デフォルト、 FargateタスクはログをCloudWatch Logに記録し、各コンテナーのロググループ名とログストリームプレフィックスを設定できます。
最後に、「作成」をクリックしてタスクの定義を完了します。
サービスを作成
サービスは、Amazon ECSクラスター内の指定された数のタスク定義インスタンスを同時に実行および管理できます。何らかの理由でタスクが失敗または停止した場合、サービススケジューラは別のタスク定義インスタンスを開始してそれを置き換え、使用された計画戦略に従ってサービス内のタスクの予想数を保持します。
サービスで予想されるタスク数を維持することに加えて、ロードバランサーを使用してサービスを実行することもできます。ロードバランサーは、サービスに関連するさまざまなタスク間でトラフィックを分散します。
ECSコンソールでは、クラスターとタスク定義からサービスを作成できます。タスク定義を例にとると、手順は次のとおりです。
基本パラメーターの構成
ヒーロータスク定義を選択し、[アクション]-> [サービスの作成]をクリックして、[サービスの構成]ページで次のパラメーターを入力します。
- スタートアップの種類:FARGATE
- クラスター:ヒーロー
- サービス名:ヒーロー
- タスク数:1
- 展開タイプ:ローリング更新
次へをクリックします。
ネットワーク構成は
[VPCとセキュリティグループ]セクションにあり、クラスターVPCとサブネットを選択します。セキュリティグループ名はデフォルトで自動的に生成されます。[編集]をクリックしてセキュリティグループ名を変更するか、既存のセキュリティグループを選択できます。新しいセキュリティグループを作成することを選択した場合、デフォルトでポート80の受信ルールが構成されます。
ELBを使用しており、パブリックIPは必要ありません。パブリックIPを自動的に割り当てるオプションをDISABLEDに設定します。
ロードバランシングで
は、ターゲットグループを作成せずに新しいALBを作成します。
- ロードバランサーの種類:アプリケーションロードバランサー
- ロードバランサー名:新しく作成したALBを選択します
- コンテナーを選択します:heroes-web:80:80をクリックし、[ロードバランサーに追加]をクリックして、次のパラメーターを入力します:
プロダクションリスナーポート:新しい80
プロダクションリスナープロトコル:HTTP
ターゲットグループ名:新しいecs-heroes
ターゲットグループプロトコル:HTTP
Auto Scaling
サービスのセットアップ Auto Scaling:サービスの予想数を調整しないでください
確認して確認した後、「サービスの作成」をクリックします。
クラスターインターフェイスに戻ると、ヒーロークラスターにサービスと実行中のタスクが含まれていることがわかります。
サービスは
クラスタータスクインターフェイスに限定されています。現在のタスクを停止すると、新しいタスクが後で自動的に再起動され、ELBターゲットグループが自動的に更新されます。
Amazon ECSサービススケジューラには、障害が繰り返し発生した後に再起動するサービスタスクの頻度を制限するロジックが含まれています。
ECSサービスタスクが常にRUNNING状態に入ることができない場合(PENDINGからSTOPPEDに直接ジャンプします)、その後の再起動の試行間隔は、最大15分まで徐々に増加します
サービスにアクセスする
には、heroesクラスター->タスクに移動し、タスクをクリックして、タスクの詳細ページに移動します。タスクのプライベートIPアドレスを確認できます。内部ネットワークでは、プライベートIPを使用して、各タスクによってデプロイされたアプリケーションにアクセスできます。パブリックネットワークは、ELBを介してサービスにアクセスします。
ログ構成
awslogs
デフォルトでは、Fargateタスクはawslogsログドライバーを使用してログをCloudWatch Logに記録します。
awslogsログドライバーオプション
オプション | する必要がある | 説明 |
---|---|---|
awslogs-create-group | 番号 | ロググループを自動的に作成するには、IAMポリシーにlogs:CreateLogGroup権限が含まれている必要があります。デフォルト値はfalseです。 |
awslogs-region | はい | ログドライバーがDockerログを送信する領域 |
awslogs-group | はい | ログドライバーがログストリームを送信するロググループ |
awslogs-stream-prefix | はい | ログストリームのプレフィックス、ログストリームの形式:prefix-name / container-name / ecs-task-id |
awslogs-datetime-format | 番号 | Python strftime形式で複数行の開始位置モードを定義する |
awslogs-multiline-pattern | 番号 | 正規表現を使用して複数行の開始位置パターンを定義する |
注:awslogs-datetime-formatとawslogs-multiline-patternの両方が同時に設定されている場合、awslogs-datetime-formatオプションが優先されます。複数行のロギングは、すべてのログメッセージに対して正規表現の解析とマッチングを実行します。これは、ロギングのパフォーマンスに悪影響を及ぼす可能性があります。
FireLensの統合
FireLens for Amazon ECSは、ログをAWSサービスまたはAWSパートナーネットワーク(APN)宛先にルーティングして、ログの保存と分析を行うことができます。FireLensは、FluentdおよびFluent Bitと組み合わせて使用できます。AWSは、CloudWatch LogsおよびKinesis Data Firehose用のFluent Bitイメージとプラグインを提供します。独自のFluentdまたはFluent Bitイメージを使用することもできます。
Fluent BitとFluentdは2つのログ収集ツールです。FluentBitプラグインはリソースを節約し、より効率的です。FluentBitをログルーターとして使用することをお勧めします。
前に作成したタスクを選択し、[Create New Revision]をクリックしてFireLensの統合を有効にします。
上の図に示すように、fluentbitを選択すると、イメージアドレスが自動的に入力され、[ 適用 ]をクリックしてlog_routerコンテナーが自動的に追加されます。
CloudWatchプラグインを使用するには、タスクロールにCreateLogGroup、CreateLogStream、DescribeLogStreams、PutLogEventsの権限が必要です。AmazonKinesisFirehoseプラグインを使用するには、 "firehose:PutRecordBatch"権限が必要です。
log_routerを構成する
{
"essential": true,
"image": "128054284489.dkr.ecr.cn-north-1.amazonaws.com.cn/aws-for-fluent-bit:latest",
"name": "log_router",
"firelensConfiguration": {
"type": "fluentbit"
},
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/firelens",
"awslogs-region": "cn-north-1",
"awslogs-create-group": "true",
"awslogs-stream-prefix": "firelens"
}
},
"memoryReservation": 50
}
ログルーターのログはawslogsによって駆動され、CloudWatchに記録されます。
以下では、Fluent Bitを使用してログをCloudWatch LogsとKinesis Data Firehoseに転送します。
ログをCloudWatch Logsに転送する
コンテナーheroes-apiのログ構成を変更します。ドライバーが「awsfirelens」を選択し、ログオプション「名前」が「cloudwatch」に設定され、CloudWatch Logsプラグインが有効になっています。その他の構成は次のとおりです。
{
"essential": true,
"image": "888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-api:latest",
"name": "heroes-api",
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "cloudwatch",
"region": "cn-north-1",
"log_group_name": "/ecs/heroes-api",
"log_stream_prefix": "from-fluent-bit",
"auto_create_group": "true"
}
}
}
タスクを変更したら、[作成]をクリックしてタスク定義を保存します。
クラスターコンソールに戻り、作成したサービスを選択し、[更新]をクリックして、最新のタスク定義を選択し、[新しいデプロイメントを強制する]を選択して、サービスを段階的に保存します。
サービスの更新が成功すると、新しいタスクが作成され、Cloud Watchコンソールに入ってログを表示します。ログの形式は次のとおりです。
{
"container_id": "cda4f603d8e485d48fd7e1a77b3737026221c165b8f6d582ed78bd947a12b911",
"container_name": "/ecs-heroes-2-heroes-api-c2f3d4a8bdbcf3f9e601",
"ecs_cluster": "arn:aws-cn:ecs:cn-north-1:888888888888:cluster/isd",
"ecs_task_arn": "arn:aws-cn:ecs:cn-north-1:888888888888:task/078dd364-28b6-4650-b294-5eac6b39d08f",
"ecs_task_definition": "heroes:2",
"log": " /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\",
"source": "stdout"
}
ご覧のとおり、container_id、container_name、ecs_cluster、ecs_task_arn、ecs_task_definition、およびsourceという新しい識別フィールドがログに追加されています。
タスクの定義中に、[JSON経由で構成]をクリックし、fluentbitオプションenable-ecs-log-metadataをfalseに設定して、上記の3つのecsメタデータを無効にします。
"firelensConfiguration": {
"type": "fluentbit",
"options": {
"enable-ecs-log-metadata": "false"
}
}
コンテナーのログ構成では、log_keyオプションがログ項目のみを転送するために追加されます。
"log_key": "log"
CloudWatch Logsプラグインでサポートされるオプション:
- リージョン:AWSリージョン
- log_group_name:CloudWatchロググループ名
- log_stream_name:CloudWatchログストリーム名
- log_stream_prefix:ログストリーム名の接頭辞。log_stream_nameオプションと互換性がありません。
- log_key:デフォルトでは、ログレコード全体がCloudWatchに送信されます。キー名が指定されている場合、指定されたアイテムのみがCloudWatchに送信されます
- log_format:ログ形式
- auto_create_group:ロググループを自動的に作成します。デフォルト値はfalseです。
ログをAmazon Kinesis Data Firehoseに転送する
Kinesis Data Firehoseプラグインでサポートされるオプション:
- リージョン:AWSリージョン
- delivery_stream:Kinesis Data Firehose配信ストリームの名前
- data_keys:デフォルトでは、ログレコード全体がKinesisに送信されます。キー名が指定されている場合、指定されたアイテムのみがKinesisに送信されます。複数の名前はコンマで区切られます。
Kinesis Data Firehose配信ストリームは、Amazon S3、Amazon Redshift、Amazon Elasticsearch Serviceにログを送信できます。
S3を例にとると、まずトランスポートストリームheroes-web-logをS3に作成し、次にコンテナーheroes-webのログ構成を変更します。ドライバーは「awsfirelens」を選択し、ログオプション「名前」は「firehose」に設定され、Kinesisが有効になっています。 Data Firehoseプラグイン、その他の構成は次のとおりです。
{
"essential": true,
"image": "888888888888.dkr.ecr.cn-north-1.amazonaws.com.cn/heroes/heroes-web:latest",
"name": "heroes-web",
"logConfiguration": {
"logDriver":"awsfirelens",
"options": {
"Name": "firehose",
"region": "cn-north-1",
"delivery_stream": "heroes-web-log",
"data_keys": "log"
}
},
"memoryReservation": 100
}
タスク定義を保存してサービスを更新したら、S3に移動してログを表示できます。
ECSとEKS
Amazon Elastic Kubernetes Service(Amazon EKS)は、フルソースのKubernetesサービスであり、オープンソースのKubernetesを実行して、コンテナー化されたアプリケーションをデプロイ、管理、スケーリングします。EKSはKubernetesコントロールプレーンを使用する必要がなく、Kubernetesの実行による主要な運用上の負担を排除し、AWSインフラストラクチャの管理ではなくアプリケーションの構築に集中できるようにします。EKSは、複数のAWSアベイラビリティゾーンにわたって実行でき、Kubernetesと互換性があり、Kubernetesコミュニティによって提供される既存のすべてのプラグインとツールを使用でき、標準のKubernetes環境で実行されているすべてのアプリケーションをEKSに簡単に移行できます。
Universal
ECSはAWS独自のテクノロジーであり、EKSはオープンソースのKubernetesを実行します。したがって、デプロイ環境がAWSに限定されていない場合、たとえば、Google GKE(Google Kubernetes Engine)、Microsoft AKS(Azure Kubernetes Service)、または標準のKubernetesにデプロイする場合は、EKSを選択する必要があります。
Simplicity
ECSは、AWSコンソールから簡単にデプロイできる、すぐに使用できるソリューションです。EKSは少し複雑で、より多くの構成が必要であり、より多くの専門知識が必要です。
価格
ECSは追加料金を請求せず、コンテナーが使用したコンピューティングリソースに対してのみ支払います。EKSクラスターは1時間あたり0.688 CNYを支払う必要があり(Kubernetes名前空間とIAMセキュリティポリシーを使用して、EKSクラスターを使用して複数のアプリケーションを実行できます)、Kubernetesワーカーノードの実行に使用されるAWSリソースは、実際の使用量に応じて支払う必要があります。
ECS、EKS、およびKubernetesの3つのコンテナーオーケストレーションソリューションをテストおよび比較した後、私は作業でECSを選択しました。ECSはプロジェクトのニーズを完全に満たし、展開、運用、保守が容易になり、コストが削減されます。