Amazon EC2 Container Registry(ECR)でECS/Elastic BeanstalkのDockerイメージをホストする(1/12アップデート)
2016/01/12 Elastic Beanstalkの部分をアップデートしました。
ども、大瀧です。 1週間ほど前に、Dockerレジストリサービス Amazon EC2 Container Registry (以下ECR)がリリースされました。今回は、AWSでDockerを扱う2サービス ECS(EC2 Container Service)とElastic BeanstalkでECRを利用する手順をご紹介します。
とりあえず動かしてみる
ECSのFirst Run画面が更新され、サンプルのECSクラスタに加えてECRリポジトリがサクッと作成できるようになったので試してみます。ECRは現時点ではバージニアリージョンでしか使えないことに注意しましょう。
AWS Management ConsoleからECS管理画面を表示し、バージニア北部リージョンを選択すると、初期画面が表示されます。[Deploy a sample application onto an Amazon ECS Cluster]を選択するとECSクラスタ一式、[Store container images securely with Amazon ECR]を選択するとECRリポジトリが作成されます。今回は両方のチェックをオンにし、[Continue]をクリックします。
ウィザードでは、ECRリポジトリの作成画面が先に表示されます。Docker Hubではリポジトリ名がユーザー名
/イメージ名
という形式でしたが、ECRではユーザー専用のためユーザー名を付ける必要は必ずしもありません。その代わり先に管理画面もしくはAPIからリポジトリを作成しておかないとdocker push
がエラーになるので注意しましょう。PushするDockerイメージがたくさんあるのであればAWS CLIでスクリプト化するのが良さそうですね。
今回はDocker公式のブログエンジンGhostのイメージを試すので、[Repository Name]を「ghost」として[Next step]をクリックします。
リポジトリが作成され、そのあとのdocker push
の手順が画面に表示されます。この辺りの操作はDocker HubへのPushと特に変わりません。
ECRへのログイン
ECRの認証はDocker Hubと互換性があり、aws ecr get-login
コマンドでログインコマンドの一式を確認できます。
$ aws ecr get-login --region us-east-1 docker login -u AWS -p <長いパスワード文字列> -e none https://XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com $
このパスワードには24時間の期限が設定されているので、以下のようにエイリアスを作っておくと、期限が切れたときの再取得が楽にできるでしょう。
$ alias ecrrefresh='aws ecr get-login --region us-east-1 | bash' $ ecrrefresh WARNING: login credentials saved in /Users/ryuta/.docker/config.json Login Succeeded $
また、認証情報は別のAPIGetAuthorizationToken
で取得することできます。期限のほかクレデンシャルが構造化されて取得できるので、AWS SDKなどを用いるときにはこちらを利用する方が使い勝手が良さそうです。後述のECS AgentもGetAuthorizationToken
を内部で呼んでいるようです。
ECRへのDockerイメージのPush
ローカルに用意したDockerイメージ(事前にdocker pull ghost
を実行しました)に、ECRに対応するタグ名を設定してPushします。タグ名はランダムではなく以下の規則があるので、CIツールによる自動化もそこまで難しくはなさそうです。
<アカウントID>.dkr.ecr.<リージョン名>.amazonaws.com/<リポジトリ名>:<タグ名>
$ docker tag -f ghost:latest XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/ghost:latest $ docker images | grep ghost ghost latest d257ec7ecd87 11 days ago 350.7 MB XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/ghost latest d257ec7ecd87 11 days ago 350.7 MB s $ docker push XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/ghost:latest The push refers to a repository [XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/ghost] (len: 1) :(中略) latest: digest: sha256:8adc9901e470e326cefd5236e0e3da0209af314000000c07f9e04c7cfea3bba3 size: 41200 $
ECRにPushできましたっ!AWS Management Consoleは[Next step]でウィザードを進めましょう。
ECSの場合
続いてECS周りの作成画面が表示されます。タスク定義の画面では、[Image]に先ほど作成したECRリポジトリのlatestタグのイメージが自動でセットされます。今回はGhostを実行するイメージなので、Container PortをGhostのデフォルトポート 2368に変更し、[Next step]をクリックします。
サービスの設定は従来通りです。ELBの設定を変更し、追加しましょう。
必要に応じて、サービス用のIAMロール作成を画面の指示に従って行いましょう。[Next step]をクリックします。
クラスタの設定も従来通りです。任意のインスタンスタイプ、キーペアを設定しましょう。
インスタンスに設定するIAMロールは注意が必要です。ECRからのDockerイメージのPullはインスタンスで実行するECSエージェントがECRのAPIをコールして行うため、IAMロールにECRに関する権限を与える必要があります。マネージドポリシーのAmazonEC2ContainerServiceforEC2Role
が既に対応しているので、これをIAMポリシーに紐付けて使うのがオススメです。
[Review & launch] - [Launch Instance & Run Service]で作成が開始します。しばらく様子を見ましょう。
手元で試したときにはサービスの作成でエラーになったため、ECSのサービス管理画面から再度サービスを作成しました。ちょっとした不具合なので、しばらくしたら修正されるでしょう。
というわけでECSクラスタおよびサービスが作成され、ECRのDockerイメージがECSで実行されました!念のためELBのホスト名にアクセスしてみると、Ghostの初期画面が表示されます。
Elastic Beanstalkの場合
2016/01/12 ECR on Elastic Beanstalkがサポートされました。
2015/12/28時点では動きませんでした。理由は後述します。
Elastic Beanstalkでは、Multi-container DockerとDockerという2つのソリューションスタックでDockerがサポートされます。Multi-container Dockerは内部でECSが動くため、ECRとの連携もECSエージェントが上手くやってくれそうです。ECRのGhostイメージを利用するMulti-container Docker向けのDockerrun.aws.json
ファイルを作成しました。
{ "AWSEBDockerrunVersion": 2, "containerDefinitions": [ { "name": "ghost", "image": "XXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/ghost:latest", "essential": true, "memory": 128, "portMappings": [ { "hostPort": 80, "containerPort": 2368 } ] } ] }
以下のeb create
のメッセージにありますが、EBのインスタンスからECS/ECRにアクセスするためにaws-elasticbeanstalk-ec2-role
ロールに権限を付与しておきましょう。先ほどのマネージドポリシーAmazonEC2ContainerServiceforEC2Role
が楽です。
では、EBCLIでEnvironmentを作ってみます。
$ eb init (中略 ECRを利用するためにus-east-1リージョンを選びましょう) $ eb create WARNING: The Multi-container Docker platform requires additional ECS permissions. Add the permissions to the aws-elasticbeanstalk-ec2-role or use your own instance profile by typing "-ip {profile-name}". For more information see: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_ecstutorial.html#create_deploy_docker_ecstutorial_role Enter Environment Name (default is ECRTest-dev): Enter DNS CNAME prefix (default is ECRTest-dev): : (中略) : ERROR: Encountered error starting new ECS task: { "failures": [ { "reason": "ATTRIBUTE", "arn": "arn:aws:ecs:us-east-1:XXXXXXXXXXXX:container-instance/639c43f8-9ffb-4656-93a3-01c272285485" } ], "tasks": [] } (Ctrl + Cでコマンド終了) $
ちょっと情報少なめのエラーになりました。これは、ECRに対応するECS Agentのバージョンは1.7以上という要件によるもので、現在利用できるMulti-container Dockerソリューションスタックの最新版(v2.0.4)で実行されるECSエージェントのバージョンが1.6と不足しているためです。ソリューションスタックの説明からはECSエージェントのバージョンはわからないので、コンテナインスタンスを立ててaws ecs describe-container-instances
で確認するのが確実です。
$ aws ecs describe-container-instances \ --container-instances XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX \ --region us-east-1 (中略) "attributes": [ (中略) { "name": "com.amazonaws.ecs.capability.ecr-auth" } ], "versionInfo": { "agentVersion": "1.7.0", "agentHash": "191dbd5", "dockerVersion": "DockerVersion: 1.7.1" } } ] } $
$ aws ecs describe-container-instances \ --container-instances XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX \ --cluster awseb-ECRTest-dev-XXXXXXXXXX \ --region us-east-1 (中略) "attributes": [ (中略) { "name": "com.amazonaws.ecs.capability.logging-driver.syslog" } ], "versionInfo": { "agentVersion": "1.6.0", "agentHash": "34235e3", "dockerVersion": "DockerVersion: 1.7.1" } } ] }
ソリューションスタックが更新され、ECSエージェントのバージョンが上がれば、ECRが使えるようになると思います。しばし待ちましょう。
まとめ
ECRをECSとElastic Beanstalkで使う手順をご紹介しました。Beanstalkの方は正常稼働を確認したわけではないので、サポート後に問題が無いかどうか、後追いで確認しますね。