スマートキャンプ、エンジニアの入山です。
2020年7月にDockerとAWSのコラボレーションにより、単一コマンドでDocker ComposeのyamlファイルからAmazon ECS上に各コンテナをデプロイできる機能追加が発表され、非常に注目を集めました!
From Docker Straight to AWS - Docker Blog
AWS and Docker collaborate to simplify the developer experience | Containers
ローカルでDockerを利用して開発を行っている方々は、ほぼ間違いなくDocker Composeを利用してアプリの動作に必要な各コンテナを一括管理しているかと思いますが、このECS Pluginを利用するとAmazon ECSへの各コンテナのデプロイとECSの動作に必要な各AWSリソースを一括して自動構築してくれます。
今回は、そんなDockerのECS PluginがDocker for MacのStable版でリリースされ、実際に試してみたので紹介したいと思います!
DockerのECS Pluginとは
DockerのECS Pluginは、DockerとAWSのコラボレーションにより実現したDockerの拡張機能で、docker-compose.ymlに記述された各コンテナリソースをAmazon ECSのFargate上に直接デプロイすることができる仕組みです。
ローカルで普段実行しているdocker-composeコマンドと同じく、upやdownなどのシンプルな単一コマンドでAWSへのデプロイが自動実行され、ECSの実行に必要な各NW設定や外部公開するためのLBなども一括して作成してくれることが特徴です!
今回は以下のDocker公式ドキュメントを参考に、動作確認を行っていきます。
検証環境
今回検証に利用した環境は、以下となります。
- Docker for Mac
- Stable : 2.4.0.0
- Dockerレジストリ
- Amazon ECR
- アプリケーション
7月のリリース当初はDocker for MacのEdge版でしか利用できず、再インストールや既存のイメージが全て消えてしまうなど、リスクも多かったので手を出しにくかったですが、9/15リリースのバージョン2.3.0.5でStable版に統合されたので安心して試すことができます!
事前準備
Amazon ECS用のcontext作成
Dockerコマンドのデプロイ先にAWSを指定するために、専用のContextを作成します。 公式のサンプルに従って、myecscontextという名前でContextのcreateコマンドを実行します。
$ docker context create ecs myecscontext
対話形式で以下内容の入力が求められるので、順番に入力していきます。
- AWS Profile
- AWS CLIなどを利用していて既存のProfileが存在する場合は、選択肢から選択が可能
- 新しくProfileを登録する場合はnew profileを選択し、profile名を入力
- Region
- 東京リージョンを指定(ap-northeast-1)
- Credentials(既存Profileを選択した場合は省略可能)
- AWS Access Key ID
- AWS Secret Access Key
Contextの作成が完了したら、作成されたContextの確認を行います。
以下のようにmyecscontextが作成されており、TYPEがecsとなっていれば成功です!
$ docker context ls NAME TYPE DESCRIPTION ... default * moby Current DOCKER_HOST based configuration myecscontext ecs ap-northeast-1
ECSアカウント設定変更
DockerのECS Pluginを利用するために、ECSのアカウント設定でサービス名の新しいARN形式のオプトインを有効にする必要があります。有効になっていない場合は、デプロイ時にエラーが発生します。
以下のコマンドでECSの各設定の状況を確認できます。LongArnFormatに関する項目が対象の設定になります。
$ aws ecs list-account-settings --effective-settings { "settings": [ { "name": "containerInstanceLongArnFormat", "value": "disabled", "principalArn": "arn:aws:iam::123456789012:user/docker-ecs-user" }, { "name": "serviceLongArnFormat", "value": "disabled", "principalArn": "arn:aws:iam::123456789012:root" }, { "name": "taskLongArnFormat", "value": "disabled", "principalArn": "arn:aws:iam::123456789012:user/docker-ecs-user" } ] }
LongArnFormatに関する設定を、以下のコマンドを実行して有効化します。
$ aws ecs put-account-setting-default --name containerInstanceLongArnFormat --value enabled $ aws ecs put-account-setting-default --name serviceLongArnFormat --value enabled $ aws ecs put-account-setting-default --name taskLongArnFormat --value enabled
こちらの設定については、Edge版で少し内容が異なりますが、以下の記事を参考にさせていただきました!
DockerイメージをECRへPush
DockerのECS Pluginを利用してECSへデプロイする場合は、事前にDockerイメージをコンテナレジストリにPushしておく必要があります。今回は同じAWSアカウントのECRをレジストリとして利用します。
Docker公式のリポジトリをcloneし、サンプルアプリケーションのディレクトリに移動します。
$ git clone https://github.com/docker/ecs-plugin.git $ cd ecs-plugin/example/
今回の要となるdocker-compose.ymlを編集します。
- imageの部分をECRのリポジトリに変更
image: 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/example:latest
- ECRを利用する場合は、コンテナレジストリの認証が不要のため、以下の部分を削除
x-aws-pull_credentials: <<<your arn for your secret you can get with docker ecs secret list>>>
イメージをPushするため、ECRの認証を行います。
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com Login Succeeded
認証が完了したら、DockerイメージをPushします。
$ docker-compose push Pushing frontend (012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/example:latest)... The push refers to repository [012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/example] f180fef4ee81: Layer already exists 2c3fd1bbef62: Layer already exists 4d7eb43f9ca3: Layer already exists 3c3553e7865b: Layer already exists 22ee430ae503: Layer already exists 60faa6c61cf1: Layer already exists cfd52085ef97: Layer already exists 408e53c5e3b4: Layer already exists 50644c29ef5b: Layer already exists latest: digest: sha256:0632336b6cd907468e9ea435b5e4039b5cf4450265e62860f62d8d8696fc0109 size: 2201
ECRにイメージがPushされていることを確認します。
$ aws ecr list-images --repository-name example { "imageIds": [ { "imageDigest": "sha256:0632336b6cd907468e9ea435b5e4039b5cf4450265e62860f62d8d8696fc0109", "imageTag": "latest" } ] }
ここまでで準備は完了です!
ECSへデプロイ
先程作成したECSデプロイ用のContext(myecscontext)を利用するよう、Dockerの設定を変更します。
$ docker context use myecscontext myecscontext
Contextの変更が完了したら、ローカルでDocker Composeを起動するのと同じようにupコマンドを実行します。これだけで、AWSへのデプロイが始まります!
$ docker compose up [+] Running 17/17 ⠿ example CREATE_COMPLETE 247.0s ⠿ ExampleDefaultNetwork CREATE_COMPLETE 6.0s ⠿ FrontendTaskExecutionRole CREATE_COMPLETE 22.0s ⠿ Cluster CREATE_COMPLETE 7.0s ⠿ BackendTaskExecutionRole CREATE_COMPLETE 22.0s ⠿ CloudMap CREATE_COMPLETE 48.0s ⠿ ExampleLoadBalancer CREATE_COMPLETE 153.0s ⠿ FrontendTCP5000TargetGroup CREATE_COMPLETE 1.0s ⠿ LogGroup CREATE_COMPLETE 1.0s ⠿ ExampleDefaultNetworkIngress CREATE_COMPLETE 1.0s ⠿ FrontendTaskDefinition CREATE_COMPLETE 3.0s ⠿ BackendTaskDefinition CREATE_COMPLETE 3.0s ⠿ BackendServiceDiscoveryEntry CREATE_COMPLETE 3.0s ⠿ FrontendServiceDiscoveryEntry CREATE_COMPLETE 2.0s ⠿ BackendService CREATE_COMPLETE 80.0s ⠿ FrontendTCP5000Listener CREATE_COMPLETE 1.0s ⠿ FrontendService CREATE_COMPLETE 82.0s
表示されたリソースのステータスが全てCREATE_COMPLETEとなれば、AWSへのデプロイは完了です!
今回のサンプルアプリケーションでは、ECSのタスクやタスク定義をはじめ、LBやNW関連を含む17リソースが250秒程で自動作成されたようです。
psコマンドを実行すると、各コンテナの稼働状況とLBのエンドポイントが表示されます。
$ docker compose ps ID NAME REPLICAS PORTS example-BackendService-hfEA5K76syiR backend 1/1 example-FrontendService-j829cZjBATkR frontend 1/1 ExampleLoadBalancer-0123456789012.elb.ap-northeast-1.amazonaws.com:5000->5000/tcp
表示されたLBのエンドポイントにアクセスしてみると、サンプルアプリケーションが動作していることが確認できました!
リソースの削除
デプロイしたリソースについては、ローカルのDocker Composeと同じようにdownコマンドを実行するだけで、AWS上の各リソースが一括削除されます。
$ docker compose down
まとめ
今回は、DockerのECS Pluginを利用したAmazon ECSへのデプロイを紹介しました。
以下の記事で紹介したAWS Coplilotなども含め、コンテナアプリの実行環境構築やデプロイが、誰でも簡単に行えるように日々整備されていっており、個人開発アプリの公開や新規プロダクトのプロトタイプ検証など、様々な用途で利用できそうです!
DockerのECS Pluginは、GAに向けて本番アプリケーションの構築を移行できるレベルを目指しているようなので、今後のアップデートが楽しみです。是非皆さんも試してみてください!