
AWS_ECSでECRのイメージを使用する #376
少し業務で触れたので、勉強のために整理しておきます。
Amazon ECR (Elastic Container Registry)
AWS マネージドコンテナイメージレジストリサービスで、つまりAWS版のDocker Hubのようなイメージです。Dockerイメージを任意のCLIを使用してプッシュ、プル、管理できます。Github Actionsと連携して、あるブランチにマージされたらECRにプッシュする、といった体制を作ることも可能です。
また、IAMで許可されたユーザーやEC2インスタンス、ECSタスクがコンテナリポジトリとイメージにアクセスできます。
つまりECRはECSと統合が可能で、本番環境へのデプロイがスムーズになります。
Amazon ECS (Elastic Container Service)
言わずと知れたAWSのコンテナオーケストレーションサービスです。複数のDockerコンテナを簡単に実行、停止、管理できます。上記の通りECRと統合できるので、AWS上で簡単にECRからdocker pullして、docker runできるイメージです。
起動タイプがEC2かFargateかを選択できます。
EC2は柔軟に細かい設定が可能ですが、自分で設定をやり切る&保守していかなければなりません。Fargateはコンテナ向けのサーバーレスコンピューティングエンジンで、細かいところはAWSが全てやってくれますがEC2ほど細かい設定はできません。
我々のチームではFargateを採用しています。
ECSがECRからイメージをプルするには
Fargateのパターンで整理します。
タスク実行IAMロールでECSコンテナにECRへのアクセス許可を付与
ECSのタスク定義でECRのイメージを指定
タスク実行IAMロールでECSコンテナにECRへのアクセス許可を付与
タスク実行IAMロールは公式で以下のように定義されています。
タスク実行ロールは、ユーザーに代わって AWS API コールを実行するためのアクセス許可を Amazon ECS コンテナと Fargate エージェントに付与します。
ここでは管理IAMポリシーであるAmazonECSTaskExecutionRolePolicyを付与します。このポリシーには以下のアクセス許可が含まれます。
ecr:GetAuthorizationToken — プリンシパルが認証トークンの取得できるようにします。認証トークンは IAM 認証情報を表し、IAM プリンシパルによってアクセスされる Amazon ECR レジストリへのアクセスに使用できます。受け取る認証トークンは 12 時間有効です。
ecr:BatchCheckLayerAvailability — コンテナイメージが Amazon ECR プライベートリポジトリにプッシュされると、イメージレイヤーごとにすでにプッシュされているかどうかが確認されます。プッシュされた場合、そのイメージレイヤーはスキップされます。
ecr:GetDownloadUrlForLayer— コンテナイメージが Amazon ECR プライベートリポジトリからプルされると、この API は、キャッシュされていない各イメージレイヤーに対して 1 回呼び出されます。
ecr:BatchGetImage— コンテナイメージが Amazon ECR プライベートリポジトリから取得されると、この API が 1 回呼び出され、イメージマニフェストが取得されます。
logs:CreateLogStream— プリンシパルが、指定したロググループの CloudWatch Logs ストリームを作成できるようにします。
logs:PutLogEvents — ログイベントの Batch を指定されたログストリームにアップロードすることをプリンシパルに許可します。
以下のように記述されます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
ECSのタスク定義でECRのイメージを指定
アクセス許可が付与されたら、ECSのタスク定義でイメージを指定します。
このタスク定義とは、ECSでコンテナを起動するための情報を記載したものです。イメージを指定するだけでなく、vCPUとメモリサイズをどうするか、portはどうするか、コンテナが終了したり失敗した時の設定(再起動など)などができます。vCPUやメモリの性能は後から変更可能です。
で、このタスク定義では、Amazon ECR プライベートリポジトリでホストされているコンテナイメージを指定できます。イメージを指定する際は完全な registry/repository:tag の名前を使用する必要があります。
例えば以下のようになります。"image"部分が該当箇所です。
{
"family": "task-definition-name",
...
"containerDefinitions": [
{
"name": "container-name",
"image": "aws_account_id.dkr.ecr.region.amazonaws.com/my-repository:latest",
...
}
],
...
}
上記は公式のサンプルコードなのですが、タグの「latest」に注目してください。
現在はlatestタグを本番環境で使用することは推奨されていないようです。詳しくは追ってないのですが、dev環境用のイメージとタグが重複してしまい、複数の異なるバージョンが本番環境で稼働してしまった事例があるみたいでした。
そのため、本番用のECSタスクではlatest以外のタグでイメージを指定した方が良さそうです。我々のチームではECRイメージに「prod」や「dev」といったタグを付けて、本番環境用と開発環境用で使い分けています。
ここまでお読みいただきありがとうございました!