[レポート] Dive deep into Amazon ECR #AWSreInvent #CON405

re:Invent 2023 の Dive deep into Amazon ECR のセッションレポートです。 ECR の裏側がガッツリ話されており、見応え抜群なセッションでした。
2024.01.06

こんにちは! AWS 事業本部コンサルティング部のたかくに(@takakuni_)です。

今回は、 re:Invent 2023 の Breakout セッションの 1 つ 「Dive deep into Amazon ECR (CON405)」 をレポートしていきたいと思います。

セッション概要

Amazon ECR is a secure, fully managed, and highly available container registry that serves more than 15 billion image pulls weekly and offers integrated lifecycle management, replication, image scanning, and caching features. Through its support of Open Container Initiative (OCI) standards, Amazon ECR works with the open source tools that customers use every day to publish images and deploy container workloads. Join this session for a deep dive and see how Amazon ECR is designed, follow the lifecycle of an image through the service, and discover how Amazon ECR operates at scale.

動画

みどころ

実際に動画見ていただくのがベストだと思うので、個人的に選んだ見どころをご紹介できればと思います。

コンテナイメージの管理について

はじめに、コンテナアプリケーションを起動するために必要なステップとして、コンテナイメージの作り方、レジストリへの保管について説明がありました。

架空のアプリケーションとして、 GenAI を利用した CardWhisperer アプリケーションを作る設定で話が始まります。

コンテナイメージの管理方法には業界標準(OCI)が存在しており、 ECR へのプッシュも OCI 形式の API リクエストを利用して管理されます。

ECR の内部構造

Docker コマンドで ECR へイメージプッシュした際、「ECR 側はどのような構造で、動いているのか」の説明がありました。

docker コマンドなどの OCI 形式のリクエストの場合は、 Proxy を経由, AWS CLI および、SDK の場合は フロントエンドサービスへ転送される仕組みで、 Proxy では、 クライアントから受け取った OCI 形式の API リクエストをフロントエンドで受け取れる API に変換して、中継する役割を担います。

また、コンテナイメージのタグ情報やメタデータの保管は DynamoDB へ、 Manifest や Layer は S3 に保管されます。

S3 の部分に関しては、以前から妄想していたのですが、メタデータの保管や API 変換の部分は初知りだったため、とても興奮しました。

イメージプッシュの一連の流れ

ECR へプッシュするまでに利用する API が以下のスライドになります。

Layer と Manifest ファイルで利用する API が分かれており、イメージプッシュが中断された場合でも、再開できるよう Layer のプッシュから始まり、 Manifest のプッシュで終わるよう設計されています。

いきなり、 Layer のアップロードを行うのではなく、 BatchCheckLayerAvailability API を利用して、 Layer が以前にアップロードされたかどうかを確認します。

重複した Layer のアップロードを避け、帯域含めて無駄なコストを削減する仕組みが実装されていて、大変興味深いパートでした。

BatchCheckLayerAvailability が完了すると、 Layer をプッシュするために InitiateLayerUpload が呼び出されます。順序立てて行われるのではなく、各レイヤーで並行してアップロードされる点について注意です。

InitiateLayerUpload は、あくまで Layer アップロードの準備であり、 クライアントに S3 のマルチパートアップロードで利用するアップロード ID を返すようです。

マルチパートアップロードの準備ができたら、とうとう UploadLayerPart です。

Proxy サービスはクライアントとコネクションを張りつつフロントエンドサービスへ、 20 メガバイト程度のチャンクに分割して送信します。フロントエンドサービスでは各レイヤーのダイジェストの計算しメタデータサービスへの転送、 S3 へ Layer データの転送を行います。メタデータサービスはダイジェストの計算途中の結果を DynamoDB に保管しながら、最終的なダイジェスト結果を返す役割を担います。

300 台以上のホストを束ねるクラスターでサービス提供されており、ステートレスアプリケーションの作り方という意味でも非常に参考になりました。

Layer アップロード最後のステップで CompleteLayerUpload で、 Layer アップロードが完了した旨を ECR へ伝えます。 マルチパートアップロードの CompleteMultipartUpload もこの処理で行われます。

これで Layer のアップロードは完了です。続いて、 Manifest のアップロードに移ります。

Manifest ファイルのアップロードは PutImage で行われます。

フロントエンドサービスは Proxy から受けとった API リクエストをもとにメタデータサービスを呼び出します。 メタデータサービスで Manifest ファイルの PutObject, Manifest や Layer が S3 のどこに保存したか等のメタデータを DynamoDB に保管します。

クライアントから見れば、 docker image push のようなシンプルなコマンド経由の API リクエストに見えますが、裏では思った以上に複雑で意外でした。ただ一つ一つの処理に意味のあり、大変面白いパートだったと思います。

余談ですが、 Proxy サーバーは Amazon ECR proxy と呼ばれているみたいです。

This operation is used by the Amazon ECR proxy and is not generally used by customers for pulling and pushing images. In most cases, you should use the docker CLI to pull, tag, and push images.

Amazon Elastic Container Registry API Reference InitiateLayerUpload

イメージプルの一連の流れ

イメージプルでは、次のような仕組みで行われています。 Layer のダウンロードが ECR を介して配信されていない部分、気になりますね...

イメージプルはプッシュと逆で Manifest ファイルの取得から始まります。

Manifest ファイルのダウンロードは BatchGetImage で行われます。

フロントエンドサービスは、メタデータサービスに対してイメージタグまたは、イメージダイジェストを利用して Manifest ファイルをリクエストします。

メタデータサービスでは、必要に応じて DynamoDB を利用して、 Manifest ファイルの居場所の特定し、 S3 から Manifest ファイルのダウンロードします。 ダウンロードされた Manifest ファイルはフロントエンドサービス → プロキシサービス → クライアントの順番に返されていく仕組みです。

Manifest ファイルをもとに Layer 情報を認識し、次のステップで必要なイメージを ECR に要求します。

GetDownloadUrlForLayer では、 Layer のダウンロードを行います。

フロントエンドサービスおよびメタデータサービスで Layer の居場所に対して、署名付き URL を生成します。307 レスポンスと 生成した 署名付き URL をもとにリダイレクトさせ、 S3 から直接 Layer をダウンロードさせるよう設計されています。

データダウンロード部分を S3 にオフロードすることで ECR サービスのリソースを逼迫させない意図があるようです。

コンテナイメージの pull は push に比べて、多くのリソースを消費することが予想できます。

コンテナイメージに限らず、ファイルアップロード/ダウンロードの仕組みを実装したい場合の 1 つのアイデアとして使ってみたいなと思いました。

まとめ

以上、「Dive deep into Amazon ECR」のセッションレポート(個人的見どころ)でした。

今回、ご紹介したコンテナイメージの pull / push の他に、ライフサイクルポリシーやイメージスキャンの裏側ロードマップなども解説された濃いセッションでとても見応えがありました。

ECR を利用している方なら、ぜひ一度ご覧いただくのをお勧めします!

AWS 事業本部コンサルティング部のたかくに(@takakuni_)でした!