AWS再入門ブログリレー2022 Amazon ECR編

こんにちは。AWS事業本部トクヤマシュンです。

当エントリは弊社コンサルティング部による『AWS 再入門ブログリレー 2022』の35日目のエントリです。

このブログリレーの企画は、普段AWSサービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。

AWSをこれから学ぼう!という方にとっては文字通りの入門記事として、またすでにAWSを活用されている方にとってもAWSサービスの再発見や2022年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。

では、さっそくいってみましょう。35日目のテーマは「Amazon ECR」です。

Amazon ECRとは?

Amazon Elastic Container Registry(ECR)はフルマネージドなDockerコンテナレジストリサービスです。
自身で作成したり、AWS Marketplaceで購入したDockerコンテナイメージの保存・管理・デプロイが可能です。

コンテナレジストリには、自前で構築するDocker Registryや、Docker社公式が提供しているSaaSであるDocker Hubなどのサービスがあります。
そんな中で、ECRは以下のような特徴を持っています。

  • インフラ運用不要
    • マネージドサービスであるため、運用やスケーリングが不要
  • 高い耐久性・可用性
    • ストレージとして、Amazon S3を利用
  • AWSサービスとの統合
    • IAMユーザーやIAMロールを使ったポリシーで各リポジトリへのアクセス許可設定が可能
    • Amazon ECS、Amazon EKS、AWS Lambdaなどと統合されており、ワークフローの簡略化が可能
    • Code BuildやCode Deproyとも密に連携し、CI/CDパイプライン構築にも利用可能

AWSの他サービスと連携させるのであれば、コンテナレジストリにはECRを使うのがオススメです。

ECRの持つ機能

ECRは、RegistoryRepositoryから構成されます。
1リージョンに対して1つのPublic Registoryと1つのPrivate Registoryを持つことができます。
Registoryの中にはRepositoryを1つ以上作ることができ、コンテナイメージはRepositoryの中に保存します。

Registoryの機能

Registoryには大きく2つの種類があります。

Public Registory

  • 保存したコンテナイメージをAWS外の世界中に公開可能
    • コンテナイメージは自動的にAWSの各リージョンへも展開され、pull時間短縮と可用性向上が図られる
  • 公開されたコンテナイメージは、ECR Public Galleryからpull可能
  • URLはpublic.ecr.aws/エイリアス/という形式
    • エイリアスは、初回作成時にはデフォルトエイリアスというランダム値を割り当て
    • カスタムエイリアスを申請し、承認されれば任意の名前を設定することも可能

Private Registory

  • 保存したコンテナイメージを私的な範囲に公開可能
    • 自社アプリケーションの運用では、基本的にこちらを選択
  • URLはアカウントID.dkr.ecr.リージョン.amazonaws.comという形式
    • AWSアカウントおよびリージョンごとにユニークなURL
  • プルスルーキャッシュ
    • Public RegistoryのRepositoryを、Private Registoryにキャッシュすることが可能
    • ECRのインターフェイスVPCエンドポイントを使うことで、Private SubnetからPublic Registoryの更新内容にアクセス可能
    • 同期は24時間に1回なので、リアルタイムではない
  • レプリケーション
    • 1.クロスリージョンレプリケーション
      • 他リージョンを選択してレプリケーション
    • 2.クロスアカウントレプリケーション
      • 送信先アカウントとリージョンを選択してレプリケーション
      • 送信先のアカウントにはアクセス許可のためのRegistoryポリシーの設定が必要
  • 許可
    • プルスルーキャッシュ機能とレプリケーション機能の許可をAWSプリンシパルに付与
    • Registoryポリシーを使用して許可を記述
  • スキャン
    • 1.基本スキャン
      • CVEデータベースを使用して、プッシュ時に脆弱性のスキャンが可能
    • 2.拡張スキャン
      • Amazon Inspector v2と統合され、自動継続的なスキャンが可能
      • OSとプログラミング言語パッケージの両方の脆弱性についてスキャン

Repositoryの機能

Repositoryも大きく2つの種類があります。

Public Repository

Public Repositoryでは、Repository名を設定します。
オプションとして、ロゴやコンテンツタイプ、Repositoryの概要、イメージの使用方法に関する情報を提供することも可能です。

Private Repository

Private Repositoryでは下の設定が可能です。

  • タグのイミュータビリティ
    • 有効化すると、同じタグを使用した後続イメージのプッシュによりイメージタグが上書きされることを防ぐ
    • すべてのイメージのタグをユニークにすることで、latestタグの運用をRepositoryレベルで禁止する、などが可能
  • 暗号化
    • KMSを使用して、Repositoryに保存されているイメージを暗号化
    • 暗号化キーはデフォルトではAWS所有のキー
    • 自身で作成したKMSキーを設定することも可能

Private Repositoryを作成してpushしてみる

それでは、Private Repositoryを作成してpushしてみます。

クライアントマシン環境

クライアントマシンでは、次のバージョンを使います。

  • OS
    • macOS Big Sur Version 11.6.5
  • aws-cli
    • 2.4.16
  • Docker Desktop
    • 4.6.1

またローカルにecr-testというディレクトリを作成し、下のDockerfileを作成しておきます。

ecr-test/Dockerfile

FROM alpine:3.15.1
CMD ["echo","Hello World"]

Repository作成

マネジメントコンソールから、Repositoryを作成します。 今回は下の画像の通り設定してtestというRepositoryを作成します。

設定できれば、リポジトリを作成をクリックします。

RepositoryへのDockerイメージpush

ECRにtestというRepositoryを作成できました。
マネジメントコンソールから、プッシュコマンドの表示をクリックします。

すると、DockerイメージをtestRepositoryにpushするためのコマンドが4つ表示されます。

クライアントのターミナルから、ecr-testディレクトリでこれら4つのコマンドを実行します。

xxxxxxx@xxxxxxx ecr-test % aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin AWSアカウント番号.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
xxxxxxx@xxxxxxx ecr-test % docker build -t test .                                                                                                                             
[+] Building 0.9s (5/5) FINISHED                                                                                                                                                                                          
 => [internal] load build definition from Dockerfile                                                                                                                                                                 0.0s
 => => transferring dockerfile: 87B                                                                                                                                                                                  0.0s
 => [internal] load .dockerignore                                                                                                                                                                                    0.0s
 => => transferring context: 2B                                                                                                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/alpine:3.15.1                                                                                                                                                     0.9s
 => CACHED [1/1] FROM docker.io/library/alpine:3.15.1@sha256:d6d0a0eb4d40ef96f2310ead734848b9c819bb97c9d846385c4aca1767186cd4                                                                                        0.0s
 => exporting to image                                                                                                                                                                                               0.0s
 => => exporting layers                                                                                                                                                                                              0.0s
 => => writing image sha256:8597e2c888b061820f07bcf32674ceaa26b5b510b8f8c004e7c623c27177beca                                                                                                                         0.0s
 => => naming to docker.io/library/test                                                                                                                                                                              0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
xxxxxxx@xxxxxxx ecr-test % docker tag test:latest AWSアカウント番号.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest
xxxxxxx@xxxxxxx ecr-test % docker push AWSアカウント番号.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest
The push refers to repository [AWSアカウント番号.dkr.ecr.ap-northeast-1.amazonaws.com/test]
534ef0372885: Pushed 
latest: digest: sha256:5deb9e49c07e84ba35cd0523d03098fad9b2766bee8af6f9d7bf045afb4e1c8f size: 527

testRepositoryにイメージをpushすることができました。

Repositoryに保存したイメージはECSやEKSから参照することで、実際のコンテナとして動かすことができます。

なお、今回はタグにlatestを付けましたが、本番運用の場合には各イメージをユニークに設定できるタグを設定することをオススメします。

終わりに

以上、『AWS 再入門ブログリレー 2022』の 35日目のエントリ『Amazon ECR』編でした。紹介しきれていない機能や日々のアップデートがあるのでぜひチェックしてみてください。
明日 (3/24) は繁松昂大の「AWS Auto Scaling」の予定です。お楽しみに!!