はじめに
Docker Composeを使うと、ローカル環境で簡単にコンテナを起動・管理できます。
一方、本番環境では、以下のような要件が出てきます。
- コンテナ障害時に自動復旧したい
- 複数のコンテナへ負荷分散したい
- コンテナ数を簡単に増やしたい
- CloudWatch Logsでログを確認したい
- AWS IAMで権限制御したい
このような用途で利用されるのが、Amazon ECSです。
本記事では、Amazon ECS Managed Instancesを使ってNginxを構築します。
また、HTMLファイルはDockerイメージに含めず、Amazon S3に保存した index.html を S3 Files でコンテナへマウントします。
これにより、S3上のHTMLを書き換えるだけで、Nginxの表示内容へ反映される構成を作ります。
ECSとは
Amazon ECSは、AWSが提供するコンテナオーケストレーションサービスです。
Docker Composeが主に1台のサーバー上でコンテナを起動する仕組みであるのに対し、ECSはAWS上で複数のコンテナを管理できます。
Docker Compose
Server
└── nginx
Amazon ECS
ECS Cluster
└── ECS Service
└── ECS Task
└── nginx
ECSでは、コンテナを直接起動するのではなく、以下のような構成で管理します。
| ECSの要素 | 説明 |
|---|---|
| Cluster | コンテナを実行する基盤 |
| Task Definition | コンテナの設計図 |
| Task | Task Definitionから起動される実行単位。1つ以上のコンテナを含められる |
| Service | Task数を維持する仕組み |
| Capacity Provider | コンテナ実行基盤の管理 |
今回作成する構成
今回は以下の構成を作成します。
既存VPC
├── Private Subnet-A
│ ├── 踏み台サーバー
│ ├── Internal ALB
│ ├── S3 Files Mount Target
│ └── ECS Managed Instance
│ └── nginx Task
│
├── Private Subnet-C
│ ├── Internal ALB
│ ├── S3 Files Mount Target
│ └── ECS Managed Instance
│ └── nginx Task
│
└── Amazon S3
└── index.html
↑
S3 Filesでマウント
ポイントは以下です。
| 項目 | 内容 |
|---|---|
| ECS実行基盤 | Managed Instances |
| OS | Amazon Linux |
| VPC | 既存VPC |
| Subnet | Private Subnet |
| ALB | Internal ALB |
| Target Group | IPターゲット |
| Webサーバー | nginx:latest |
| HTML配置先 | Amazon S3 |
| HTMLマウント先 | /usr/share/nginx/html |
| S3 Files接続 | S3 Filesファイルシステムとmount targetを利用 |
| 動作確認 | 踏み台サーバーからInternal ALBへアクセス |
| スケール確認 | Desired Countを1から2へ変更 |
S3バケット名について
S3バケット名はグローバルで一意である必要があります。
そのため、AWSアカウントIDを含めた名前にします。
ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an
例です。
ecs-nginx-demo-123456789012-ap-northeast-1-an
このようにすることで、他のAWSアカウントとバケット名が重複しにくくなります。
S3バケットを作成する
AWSマネジメントコンソールで以下を開きます。
S3 > 汎用バケット > バケットを作成
設定値は以下です。
| 項目 | 設定値 |
|---|---|
| バケットタイプ | 汎用 |
| バケット名 | ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an |
| AWSリージョン | アジアパシフィック(東京)ap-northeast-1 |
| オブジェクト所有者 | ACL無効 |
| パブリックアクセスをすべてブロック | 有効 |
| バケットのバージョニング | 無効 |
| デフォルト暗号化 | Amazon S3 マネージドキー |
| バケットキー | 有効 |
作成後、バケットを開きます。
index.htmlをアップロードする
ローカルPCで以下のファイルを作成します。
ファイル名は index.html です。
<!DOCTYPE html>
<html>
<head>
<title>ECS S3 Files Demo</title>
</head>
<body>
<h1>Hello ECS</h1>
</body>
</html>
S3バケットを開き、以下の順に操作します。
S3 > 対象バケット > オブジェクト > アップロード
設定値は以下です。
| 項目 | 設定値 |
|---|---|
| アップロードファイル | index.html |
| 保存先 | バケット直下 |
| アクセス許可 | 変更なし |
| ストレージクラス | 標準 |
アップロード後、以下のようになっていれば問題ありません。
s3://ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an/index.html
S3 Filesファイルシステムを作成する
S3 FilesをECS Taskへマウントするには、S3バケットだけでは不十分です。
事前に以下が必要です。
| 項目 | 内容 |
|---|---|
| S3バケット | HTMLファイルを保存する場所 |
| S3 Filesファイルシステム | ECSからマウントするファイルシステム |
| Mount target | VPC内からS3 Filesへ接続するためのネットワークエンドポイント |
| Task IAM Role | ECS TaskがS3 FilesとS3を読むためのIAMロール |
| Security Group | ECS Taskからmount targetのTCP 2049へ到達できる設定 |
AWSマネジメントコンソールで以下を開きます。
S3 > S3 Files > ファイルシステムを作成
設定値は以下です。
| 項目 | 設定値 |
|---|---|
| ファイルシステム名 | fs-ecs-nginx-html |
| 関連付けるS3バケット | ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an |
| VPC | ECS Taskを起動する既存VPC |
| Mount target | Private Subnet-A、Private Subnet-C |
| Security Group | 後述の sg-s3files-mount-target
|
作成後、S3 FilesファイルシステムIDを控えます。
fs-XXXXXXXXXXXXXXXXX
Access Pointを利用する場合は、Access Point ARNも控えます。
arn:aws:s3files:ap-northeast-1:<AWSアカウントID>:file-system/fs-XXXXXXXXXXXXXXXXX/access-point/fsap-XXXXXXXXXXXXXXXXX
IAMポリシーを作成する
S3 FilesをECS Taskへマウントするには、S3オブジェクト読み取り権限に加えて、S3 Filesファイルシステムへの接続権限が必要です。
AWSマネジメントコンソールで以下を開きます。
IAM > ポリシー > ポリシーの作成
「JSON」を選択し、以下を入力します。
<AWSアカウントID>、<S3 FilesファイルシステムID>、必要に応じて <S3 Files Access Point ID> を置き換えます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3FilesMount",
"Effect": "Allow",
"Action": [
"s3files:ClientMount",
"s3files:ClientRootAccess"
],
"Resource": [
"arn:aws:s3files:ap-northeast-1:<AWSアカウントID>:file-system/<S3 FilesファイルシステムID>",
"arn:aws:s3files:ap-northeast-1:<AWSアカウントID>:file-system/<S3 FilesファイルシステムID>/access-point/<S3 Files Access Point ID>"
]
},
{
"Sid": "AllowListBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an"
},
{
"Sid": "AllowReadObjects",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an/*"
}
]
}
Access Pointを使わない場合は、Access Point ARNの行は削除します。
ポリシー名は以下にします。
S3FilesReadOnlyForEcsNginx
設定値です。
| 項目 | 設定値 |
|---|---|
| ポリシー名 | S3FilesReadOnlyForEcsNginx |
| 説明 | Allow ECS task to read nginx html files from S3 Files |
IAMロールを作成する
次に、ECS TaskからS3 FilesとS3を読むためのIAMロールを作成します。
AWSマネジメントコンソールで以下を開きます。
IAM > ロール > ロールを作成
設定値は以下です。
| 項目 | 設定値 |
|---|---|
| 信頼されたエンティティタイプ | AWSサービス |
| ユースケース | Elastic Container Service |
| ユースケース詳細 | Elastic Container Service Task |
許可ポリシーで、先ほど作成した以下のポリシーを選択します。
S3FilesReadOnlyForEcsNginx
ロール名は以下にします。
ecs-task-role-nginx-s3files
| 項目 | 設定値 |
|---|---|
| ロール名 | ecs-task-role-nginx-s3files |
| 説明 | Task role for nginx to mount S3 Files |
このロールは、後ほどTask Definitionの Task role に指定します。
Security Groupを作成する
今回必要なSecurity Groupは3つです。
| Security Group名 | 用途 |
|---|---|
sg-ecs-nginx-alb |
Internal ALB用 |
sg-ecs-nginx-task |
ECS Task用 |
sg-s3files-mount-target |
S3 Files mount target用 |
通信経路は以下です。
踏み台サーバー
↓ HTTP:80
Internal ALB
↓ HTTP:80
ECS Task nginx
↓ TCP:2049
S3 Files Mount Target
ALB用Security Groupを作成する
AWSマネジメントコンソールで以下を開きます。
EC2 > セキュリティグループ > セキュリティグループを作成
基本情報です。
| 項目 | 設定値 |
|---|---|
| セキュリティグループ名 | sg-ecs-nginx-alb |
| 説明 | Security group for internal ALB of ECS nginx |
| VPC | 既存VPC |
インバウンドルールです。
| タイプ | プロトコル | ポート | ソース |
|---|---|---|---|
| HTTP | TCP | 80 | 踏み台サーバーのSecurity Group |
踏み台サーバーのSecurity Groupをソースに指定します。
例です。
sg-bastion
アウトバウンドルールです。
| タイプ | プロトコル | ポート | 宛先 |
|---|---|---|---|
| すべてのトラフィック | すべて | すべて | 0.0.0.0/0 |
ALBからECS Taskへ通信するため、アウトバウンドはデフォルトのままで問題ありません。
ECS Task用Security Groupを作成する
同じく以下を開きます。
EC2 > セキュリティグループ > セキュリティグループを作成
基本情報です。
| 項目 | 設定値 |
|---|---|
| セキュリティグループ名 | sg-ecs-nginx-task |
| 説明 | Security group for ECS nginx tasks |
| VPC | 既存VPC |
インバウンドルールです。
| タイプ | プロトコル | ポート | ソース |
|---|---|---|---|
| HTTP | TCP | 80 | sg-ecs-nginx-alb |
ここでは、踏み台サーバーからの直接アクセスは許可しません。
ECS TaskにはALBからのみアクセスさせます。
アウトバウンドルールです。
| タイプ | プロトコル | ポート | 宛先 |
|---|---|---|---|
| NFS | TCP | 2049 | sg-s3files-mount-target |
| HTTPS | TCP | 443 | S3またはインターネット向け |
検証用途でアウトバウンドを 0.0.0.0/0 の全許可にしている場合、上記の通信は含まれます。
S3 Files Mount Target用Security Groupを作成する
S3 Filesはmount targetへNFS相当の通信を行います。
そのため、ECS Task側からmount targetのTCP 2049へ到達できる必要があります。
EC2 > セキュリティグループ > セキュリティグループを作成
基本情報です。
| 項目 | 設定値 |
|---|---|
| セキュリティグループ名 | sg-s3files-mount-target |
| 説明 | Security group for S3 Files mount target |
| VPC | 既存VPC |
インバウンドルールです。
| タイプ | プロトコル | ポート | ソース |
|---|---|---|---|
| NFS | TCP | 2049 | sg-ecs-nginx-task |
アウトバウンドルールはデフォルトのままで問題ありません。
Private Subnet利用時の注意点
今回の構成ではECS TaskをPrivate Subnetに配置し、Public IPを無効にします。
そのため、ECS TaskやManaged Instanceが外部サービスへ到達する経路が必要です。
特に、この記事ではDocker Hubの公式イメージを利用します。
nginx:latest
Docker Hubからイメージを取得するには、Private Subnetからインターネットへ出る経路が必要です。
| 用途 | 必要な経路 |
|---|---|
Docker Hubから nginx:latest をpull |
NAT GatewayまたはNAT Instance |
| S3 APIへアクセス | NAT Gateway、NAT Instance、またはS3 Gateway Endpoint |
| S3 Files mount targetへ接続 | 同一VPC内のmount targetとTCP 2049のSecurity Group許可 |
S3 Gateway EndpointだけではDocker Hubへは到達できません。
閉域寄りの構成にしたい場合は、nginxイメージをECRへ置き、ECR用VPC EndpointとS3 Gateway Endpointを利用する構成にします。
Target Groupを作成する
ALBからECS Taskへ転送するため、Target Groupを作成します。
AWSマネジメントコンソールで以下を開きます。
EC2 > ターゲットグループ > ターゲットグループの作成
基本設定
| 項目 | 設定値 |
|---|---|
| ターゲットタイプ | IPアドレス |
| ターゲットグループ名 | tg-ecs-nginx |
| プロトコル | HTTP |
| ポート | 80 |
| IPアドレスタイプ | IPv4 |
| VPC | 既存VPC |
| プロトコルバージョン | HTTP1 |
今回はECS Serviceと連携するため、ターゲットタイプは IPアドレス にします。
ECS Taskは awsvpc ネットワークモードでENIを持つため、ALBはTaskのIPアドレスへ直接転送します。
ヘルスチェック設定
| 項目 | 設定値 |
|---|---|
| ヘルスチェックプロトコル | HTTP |
| ヘルスチェックパス | / |
| 正常しきい値 | 5 |
| 非正常しきい値 | 2 |
| タイムアウト | 5秒 |
| 間隔 | 30秒 |
| 成功コード | 200 |
Nginxは / にアクセスすると index.html を返します。
そのため、ヘルスチェックパスは / で問題ありません。
ターゲット登録
作成時点ではターゲットを手動登録しません。
ECS Serviceを作成すると、ECSが自動でTaskのIPアドレスをTarget Groupへ登録します。
そのため、ターゲット登録画面では何も選択せずに作成します。
Internal ALBを作成する
AWSマネジメントコンソールで以下を開きます。
EC2 > ロードバランサー > ロードバランサーの作成
「Application Load Balancer」を選択します。
基本設定
| 項目 | 設定値 |
|---|---|
| ロードバランサー名 | alb-ecs-nginx-internal |
| スキーム | 内部 |
| IPアドレスタイプ | IPv4 |
スキームは 内部 を選択します。
これにより、ALBはPrivate Subnet内でのみ利用されます。
ネットワークマッピング
| 項目 | 設定値 |
|---|---|
| VPC | 既存VPC |
| サブネット | Private Subnet-A、Private Subnet-C |
ALBは高可用性のため、2つ以上のAZに配置します。
今回はPrivate Subnetを2つ選択します。
Security Group
| 項目 | 設定値 |
|---|---|
| Security Group | sg-ecs-nginx-alb |
Listener
| 項目 | 設定値 |
|---|---|
| プロトコル | HTTP |
| ポート | 80 |
| デフォルトアクション |
tg-ecs-nginx へ転送 |
作成後、ALBのDNS名を控えます。
例です。
internal-alb-ecs-nginx-internal-xxxxxxxx.ap-northeast-1.elb.amazonaws.com
ECSクラスターを作成する
AWSマネジメントコンソールで以下を開きます。
ECS > Clusters > Create Cluster
Managed Instancesを指定する場合、クラスター作成時にECSがManaged Instances用のCapacity Providerを作成します。
このとき、ECSがEC2インスタンスを起動・管理するための設定も必要です。
主に確認する項目は以下です。
| 項目 | 内容 |
|---|---|
| Subnets | ECS Managed Instancesを起動するサブネット |
| Security group | ECS Managed Instancesに付与するSecurity Group |
| Instance profile | Managed Instancesとして起動されるEC2インスタンスに付与するIAM instance profile |
| Infrastructure role | ECSがManaged Instances基盤をユーザーの代わりに管理するためのIAM role |
設定値は以下です。
| 項目 | 設定値 |
|---|---|
| Cluster name | ecs-cluster-nginx |
| Infrastructure | Managed Instances |
| OS | Amazon Linux |
| VPC | 既存VPC |
| Subnets | Private Subnet-A、Private Subnet-C |
| Security group | ECS Managed Instances用Security Group |
| Instance profile | 新しいインスタンスロールを作成する |
| Infrastructure role | 新しいインフラストラクチャロールを作成する |
Subnets
ここで指定するSubnetsは、ECS Managed Instances、つまりECSが管理するEC2インスタンスを起動するサブネットです。
今回の構成ではPrivate Subnet-AとPrivate Subnet-Cを指定します。
Private Subnet-A
Private Subnet-C
複数AZのPrivate Subnetを指定することで、ECS Managed Instancesを複数AZへ分散できます。
すべてのサブネットは同じVPCに属している必要があります。
また、Private SubnetでDocker Hubの nginx:latest を利用する場合、Managed InstancesがDocker Hubへ到達できる必要があります。
そのため、以下のどちらかを用意します。
| 方法 | 内容 |
|---|---|
| NAT GatewayまたはNAT Instance | Docker Hubから直接pullする場合 |
| ECR + VPC Endpoint | nginxイメージをECRに置き、閉域寄りにする場合 |
S3 Gateway EndpointだけではDocker Hubへは到達できません。
Instance profile
Instance profileは、ECS Managed Instancesとして起動されるEC2インスタンスに付与されるIAM instance profileです。
このinstance profileは、ECS container agentやDocker daemonがECSと通信し、タスクを実行するために使われます。
AWS管理ポリシーのInfrastructure roleを使う場合、instance profile名は ecsInstanceRole で始まる名前にします。
例です。
ecsInstanceRole
既存のinstance profileを使う場合は、ECS Managed Instancesがクラスターへ登録され、タスクを実行できる権限を持っている必要があります。
Infrastructure role
Infrastructure roleは、ECSがユーザーの代わりにManaged Instances基盤を管理するためのIAM roleです。
このroleにより、ECSはManaged Instancesの起動、終了、管理などに必要なAWS APIを呼び出します。
AWS管理ポリシーを使う場合は、以下を付与したroleを指定します。
AmazonECSInfrastructureRolePolicyForManagedInstances
このroleはTask roleやTask execution roleとは別物です。
| Role | 用途 |
|---|---|
| Infrastructure role | ECSがManaged Instances基盤を管理する |
| Instance profile | Managed Instancesとして起動されるEC2インスタンスに付与される |
| Task role | コンテナ内アプリケーションがAWS APIを呼ぶ |
| Task execution role | ECSがイメージ取得やCloudWatch Logs出力を行う |
今回の記事では、Capacity Providerを個別に事前作成せず、クラスター作成時にECSへ自動作成させます。
ただし、Managed Instancesを選ぶ場合は、Subnets、Instance profile、Infrastructure roleが正しく指定されていることを確認します。
Task Definitionを作成する
AWSマネジメントコンソールで以下を開きます。
ECS > Task definitions > Create
Task Definition基本設定
| 項目 | 設定値 |
|---|---|
| Task definition family | nginx-task |
| Launch type | Managed Instances |
| Network mode | awsvpc |
| Task role | ecs-task-role-nginx-s3files |
| Task execution role | ecsTaskExecutionRole |
Task roleには、S3 FilesでS3を読むためのロールを指定します。
Task execution roleは、ECSがコンテナイメージ取得やCloudWatch Logs出力に使うロールです。
通常は ecsTaskExecutionRole を利用します。
Task size
| 項目 | 設定値 |
|---|---|
| CPU | 1 vCPU |
| Memory | 3 GB |
Nginxの簡単な検証なので、デフォルト値で十分です。
コンテナを追加する
Task Definition作成画面で、コンテナを追加します。
コンテナ基本設定
| 項目 | 設定値 |
|---|---|
| Container name | nginx |
| Image URI | nginx:latest |
| Essential container | Yes |
| Private registry authentication | Off |
Image URIについて
今回はDocker Hubで公開されている公式Nginxイメージを利用します。
nginx:latest
これは、Docker Hub上のNginx公式イメージの最新版タグを意味します。
ECRを使う場合は以下のようなURIになります。
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest
今回はECRは使わず、Docker Hubの nginx:latest を直接指定します。
Private SubnetでDocker Hubを利用するため、NAT GatewayまたはNAT Instanceが必要です。
Port mappings
| 項目 | 設定値 |
|---|---|
| Container port | 80 |
| Protocol | TCP |
| Port name | nginx-80-tcp |
| App protocol | HTTP |
Nginxはコンテナ内で80番ポートをListenします。
ALBからもHTTP:80でアクセスするため、Container portは80にします。
CloudWatch Logsを設定する
コンテナのログ設定を行います。(デフォルト値)
| 項目 | 設定値 |
|---|---|
| Log collection | 有効 |
| Log driver | awslogs |
| Log group | /ecs/nginx-task |
| Region | ap-northeast-1 |
| Stream prefix | ecs |
NginxのアクセスログやエラーログをCloudWatch Logsで確認できるようになります。
S3 Files Volumeを設定する
Task DefinitionのVolume設定で、S3 Filesを追加します。
Volume設定
| 項目 | 設定値 |
|---|---|
| Volume name | s3-html-volume |
| Volume type | S3 Files |
| File System | fs-XXXXXXXXXXXXXXXXX |
| Access Point | 必要に応じて作成済みAccess Point |
| S3 prefix | / |
File Systemには、先ほど作成したS3 Filesファイルシステムを指定します。
S3 prefixはバケット直下を利用するため / にします。
つまり、以下のファイルがコンテナ内に見えるようになります。
s3://ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an/index.html
↓
/usr/share/nginx/html/index.html
Mount points
コンテナ nginx に対して、以下のマウント設定を追加します。
| 項目 | 設定値 |
|---|---|
| Container | nginx |
| Source volume | s3-html-volume |
| Container path | /usr/share/nginx/html |
| Read only | 有効 |
Nginx公式イメージでは、HTMLの公開ディレクトリは以下です。
/usr/share/nginx/html
ここへS3 Filesをマウントすることで、S3上の index.html がNginxのトップページになります。
ここまででTask Definitionの設定は完了です。
ECS Serviceを作成する
AWSマネジメントコンソールで以下を開きます。
ECS > Clusters > ecs-cluster-nginx > Services > Create
Service基本設定
| 項目 | 設定値 |
|---|---|
| Compute options | Capacity provider strategy |
| Capacity provider | Managed Instances作成時に自動作成されたもの |
| Task definition Family | nginx-task |
| Service name | nginx-service |
| Desired tasks | 1 |
Networking
| 項目 | 設定値 |
|---|---|
| VPC | 既存VPC |
| Subnets | Private Subnet-A、Private Subnet-C |
| Security group | sg-ecs-nginx-task |
| Public IP | Disabled |
今回はPrivate Subnet構成のため、Public IPは無効にします。
Load balancing
すべて先ほど作成したロードバランサーとターゲットグループを選択します。
| 項目 | 設定値 |
|---|---|
| Load balancer type | Application Load Balancer |
| Load balancer | alb-ecs-nginx-internal |
| Listener | HTTP:80 |
| Target group | tg-ecs-nginx |
| Container | nginx |
| Container port | 80 |
ECS Serviceを作成すると、Taskが起動し、TaskのIPアドレスがTarget Groupへ自動登録されます。
動作確認する
ECS Service作成後、以下を確認します。
ECS > Clusters > ecs-cluster-nginx > Services > nginx-service
Tasksタブで、Taskの状態が以下になっていることを確認します。
RUNNING
次にTarget Groupを確認します。
EC2 > ターゲットグループ > tg-ecs-nginx > Targets
TaskのIPアドレスが登録され、状態が以下になっていれば正常です。
healthy
踏み台サーバーからALBへアクセスします。
curl http://<Internal ALBのDNS名>
以下のように表示されれば成功です。
<h1>Hello ECS</h1>
S3のHTMLを書き換えて反映確認する
S3の index.html を更新します。
<!DOCTYPE html>
<html>
<head>
<title>ECS S3 Files Demo</title>
</head>
<body>
<h1>Hello ECS Version2</h1>
</body>
</html>
アップロード後、少し待ってから踏み台サーバーで再度確認します。
curl http://<Internal ALBのDNS名>
以下のように変われば成功です。
<h1>Hello ECS Version2</h1>
Dockerイメージの再作成も、ECS Serviceの更新も不要です。
タスク数を増やす
ECS Serviceを更新し、Task数を増やします。
ECS > Clusters > ecs-cluster-nginx > Services > nginx-service > Update
Desired tasksを変更します。
| 項目 | 変更前 | 変更後 |
|---|---|---|
| Desired tasks | 1 | 2 |
更新後、TasksタブでTaskが2つ起動していることを確認します。
RUNNING Task: 2
Target Groupでも、登録済みターゲットが2つになります。
EC2 > ターゲットグループ > tg-ecs-nginx > Targets
構成は以下のようになります。
Internal ALB
│
├── nginx Task 1
└── nginx Task 2
ALBが2つのTaskへ負荷分散します。
CloudWatch Logsを確認する
CloudWatch Logsを開きます。
CloudWatch > Logs > Log groups > /ecs/nginx-task
ログストリームを開くと、Nginxのログを確認できます。
踏み台サーバーから何度かアクセスします。
curl http://<Internal ALBのDNS名>
ログが出力されれば、CloudWatch Logs連携も正常です。
Docker Composeとの違い
Docker Composeでは、基本的に1台のサーバー上でコンテナを起動します。
Docker Compose
Server
└── nginx
ECSでは、ServiceがTask数を維持します。
Amazon ECS
Cluster
└── Service
├── Task 1
└── Task 2
Taskが停止しても、Serviceが指定された数に戻そうとします。
今回であれば、Desired tasksを2にしている場合、1つのTaskが停止しても、ECSが新しいTaskを起動しようとします。
ECSを利用するメリット
ECSを利用すると、以下のようなメリットがあります。
- コンテナ障害時の自動復旧
- Desired tasksによる簡単なスケールアウト
- ALBとの連携
- CloudWatch Logsとの統合
- IAMによる権限制御
- S3 FilesによるHTML更新の簡素化
- Managed Instancesによるインスタンス管理負荷の軽減
まとめ
本記事では、Amazon ECS Managed Instancesを利用して、Nginxを構築しました。
また、HTMLファイルをDockerイメージに含めず、Amazon S3に保存し、S3 FilesでNginxコンテナへマウントしました。
S3 FilesをECSで利用するには、S3バケットだけでなく、S3 Filesファイルシステム、mount target、Task IAM Role、Security Groupの設定が必要です。
Amazon ECSは、簡単にコンテナ環境を構築・運用でき、スケールもできるため、従来のDocker環境に比べ本番運用に適しています。
