見出し画像

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のパターンで整理します。

  1. タスク実行IAMロールでECSコンテナにECRへのアクセス許可を付与

  2. ECSのタスク定義でECRのイメージを指定


タスク実行IAMロールでECSコンテナにECRへのアクセス許可を付与

タスク実行IAMロールは公式で以下のように定義されています。

タスク実行ロールは、ユーザーに代わって AWS API コールを実行するためのアクセス許可を Amazon ECS コンテナと Fargate エージェントに付与します。

Amazon ECS タスク実行IAM ロール

ここでは管理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 を指定されたログストリームにアップロードすることをプリンシパルに許可します。

AmazonECSTaskExecutionRolePolicy

以下のように記述されます。

{
  "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」といったタグを付けて、本番環境用と開発環境用で使い分けています。


ここまでお読みいただきありがとうございました!

参考


この記事が気に入ったらサポートをしてみませんか?