Amazon Web Services ブログ

BuildKit クライアント用の Amazon ECR でのリモートキャッシュサポートの発表

この記事は Announcing remote cache support in Amazon ECR for BuildKit clients (記事公開日 : 2023 年 10 月 24 日) の翻訳です。

この機能は、バージョン 25.0 のリリース時に Docker によってプリインストールされ、サポートされる予定です。この機能は、Buildkit バージョン 0.12 以降ですでにリリースされており、現在は Finch バージョン 0.8 以降で利用可能です。

導入

Amazon Elastic Container Registry (Amazon ECR) は、お客様がコンテナイメージとアーティファクトを保存、共有、デプロイするために使用する、完全マネージドなコンテナレジストリです。Amazon ECR は、AWS 環境と非 AWS 環境の両方で、お客様のビルドとデプロイのパイプラインの一部として、数十万人のお客様によって使用されています。

お客様が Amazon ECR や他のレジストリで最も頻繁に作業するのは、コンテナイメージのパッケージ化とレジストリへの保存を担当するコンテナクライアントです。これらの多くのクライアントは、 BuildKit として知られる一般的なオープンソースのイメージビルドツールキットを使用しています。これには、 Docker (23.0 以降)、 Finch 、 Earthly などのクライアントが含まれます。ビルド時に、クライアントはコンテナイメージの各レイヤーを、イメージが完成するまで 1 つずつビルドします。 一部のレイヤーはビルド間であまり変更されないため、クライアントはビルドしたすべてのレイヤーのローカルコピーを保存し、その後のビルドでこのローカルキャッシュを再利用します。これは、毎回レイヤーを再ビルドするよりもはるかに高速です。 ただし、これはビルドランナーまたはワーカーが各ビルド実行ごとに同じコンピュート環境で実行される場合にのみ機能します。 GitHub Actions や GitLab CI Enterprise などの一般的な CI/CD プラットフォームは、ビルドごとに一時的なコンピュートを使用するため、ローカルキャッシュを構築および使用することができません。

ソリューションの概要

一時的なコンピュートツールでもキャッシュを使用できるようにするために、 BuildKit は 2020 年にリモートキャッシュをエクスポートする機能を導入しました。 これらのリモートキャッシュは、ローカルのレイヤーキャッシュと同様に機能します (つまり、レイヤーは格納され、スクラッチから再構築する代わりに使用されます) 。 唯一の違いは、ビルドされた各レイヤーがリモートレジストリに送信され、後続のビルドでローカルキャッシュにない場合に取得されることです。 AWS のお客様は、この機能を使用してイメージのビルドを速めることを望んでおり、 Amazon ECR でのサポートを求めていました。 ただし、これらのキャッシュを格納するために使用されるフォーマットは、 Open Containers Initiative (OCI) 形式ではありませんでした。 Amazon ECR は OCI 準拠のレジストリであるため、このリモートキャッシュフォーマットを Amazon ECR にプッシュすると、検証に失敗します。

Without remote cache, the Docker client needs to build ever layer from scratch because there is no local cache. With remove cache, the Docker client finds the remote cache and uses it instead of building from scratch.

BuildKit は最近バージョン 0.12 をリリースしました。このバージョンには、リモートビルドキャッシュを OCI 互換の方法で生成および保存できるソリューションを提供しています。これには Amazon ECR エンジニアからの貢献が含まれています。これは、 BuildKit が Amazon ECR のように OCI 仕様を実装するレジストリでビルドキャッシュを保存および取得できることを意味します。このアップデートにより、ビルドおよびプッシュされたイメージとは別に、キャッシュイメージを Amazon ECR リポジトリにプッシュできるようになります。このキャッシュイメージは、後のビルドで参照でき、ノート PC からのプッシュか、 GitLab や GitHub Actions などのプラットフォーム上の本番 CI/CD ビルドからのプッシュかに関わらず、プッシュ時間を大幅に短縮することができます。

ウォークスルー

Amazon ECRでのリモートキャッシュの使い方

これらの例では、 Docker を使用します。バージョン 25.0.0 以降を実行していることを確認してください。これには、 Amazon ECR やその他の OCI 互換レジストリで機能するために必要な変更が含まれている BuildKit 0.12 が含まれています。これらの例は、ローカルの開発環境で実行するか、 CI/CD プラットフォームのビルドスクリプトで使用できます。

例えば次のようにして、 CI/CD には Docker を使用してイメージをローカルでビルドし、その後ビルドしたイメージを Amazon ECR にプッシュするビルドステップをおこないます。

docker build -t <account-id>.dkr.ecr.<aws-region>.amazonaws.com/buildkit-test:image .

docker push <account-id>.dkr.ecr.<aws-region>.amazonaws.com/buildkit-test:image
Apache Configuration

Amazon ECR にキャッシュを入力し、その後のビルドで使用するようにするには、ビルドコマンドに –cache-to および –cache-from オプションを追加します。

docker build -t <account-id>.dkr.ecr.<my-region>.amazonaws.com/buildkit-test:image \
--cache-to mode=max,image-manifest=true,oci-mediatypes=true,type=registry,ref=<account-id>.dkr.ecr.<my-region>.amazonaws.com/buildkit-test:cache \
--cache-from type=registry,ref=<account-id>.dkr.ecr.<my-region>.amazonaws.com/buildkit-test:cache .

docker push <account-id>.dkr.ecr.<my-region>.amazonaws.com/buildkit-test:image
Apache Configuration

一見多くの設定があるように見えますが、追加したことを順を追って見ていきましょう。

cache-to と cache-from という 2 つの新しいオプションセットがあります。 cache-to オプションは、 ref という引数のコンテキストキーで指定されたイメージ URI に基づいて、エクスポート先(または作成先)のリモートキャッシュを指定します。ここでのイメージ URI は、実際にビルドされているタグ付きイメージとは異なることに注意してください。必要に応じて、キャッシュの URI を Amazon ECR の別のリポジトリを指すように設定できますが、これは必須ではありません。 type という引数のコンテキストキーで指定された値 registry は、レジストリにプッシュするリモートキャッシュを作成していることを意味します。 Buildkit 0.12 で導入された新しいコンテキストキーは image-manifest です。このキーの値を true に設定すると、レジストリに OCI 互換バージョンのリモートキャッシュを保存できるようになりました。また、 image-manifest を使用するには oci-mediatypes を true に設定する必要があるため、それも設定しています。リモートキャッシュは ref のイメージ URI で暗黙的にプッシュされるため、ビルドステップに別の push コマンドを追加する必要はありません。

cache-from オプションは、Dockerfile で特定のビルドステップを実行する代わりに BuildKit が取得できるキャッシュの場所を指定します (ただし、そのレイヤーとそれ以前のレイヤーについて何も変更されていない場合)。この場合、cache-to で指定したキャッシュマニフェスト URI を持つ Amazon ECR リポジトリから取得されます。

要約すると、 cache-to はリモートキャッシュマニフェストをエクスポートし将来のビルドを高速化するための準備をするものであり、 cache-from はエクスポートされたリモートキャッシュマニフェストを利用して、現在のビルドを高速化します。キャッシュが最初に存在しない場合、 cache-from は諦めてキャッシュを使用しないため、新しいビルドステップに両方を同時に導入できます。この 1 つの変更により、レイヤーが変更されるたびに新しいビルドがリモートキャッシュを更新し、すべてのビルドが常に最新のキャッシュを使用します。

このビルドを実行して AWS コンソールに移動し、 Amazon ECR にプッシュされた内容を確認してみましょう。

Amazon ECR console showing the cache stored as an artifact of type "other"

イメージとキャッシュがあることがわかります。後続のビルドでは、 Dockerfile のキャッシングのベストプラクティスに従うビルドの場合、イメージのビルドステップがかなり速くなるはずです。

CI/CD ソリューションを最新バージョンの Docker または BuildKit にアップデートする方法については、 CI/CD プロバイダーのドキュメントを参照してください。代表的な CI/CD ソリューションのアップデート方法の例を紹介します。

  • GitLab CI の場合 GitLab Runner の docker image の tag を最新バージョンの dind に簡単に変更できるはずです。
  • GitHub Actions では、setup-buildx-action を、バージョンが最新に設定されているか、バージョン文字列が 0.12 以降に設定されていることを確認してください。
  • Travis CI の場合は、こちらから Travis インストレーションを更新できます。
  • CircleCI の場合、yml の setup_remote_docker にあるバージョンを、こちらに示されているサポートされている最新のバージョンに変更できるはずです。

まとめ

このブログ記事で説明したソリューションを使用すると、 Amazon ECR にリモートビルドキャッシュを保存することでコンテナのビルドを高速化できます。私たちの信条は、 AWS のお客様だけでなく、 OCI のようなオープンソースコミュニティや標準にも適したソリューションを提供することです。 Amazon ECR では、 BuildKit へのサポートの組み込みが、よりオープンで互換性のあるリモートキャッシュソリューションを実現したと考えています。今すぐ CI/CD のビルドパイプラインでリモートキャッシュをお試しいただき、高速で一貫したイメージビルド時間のメリットを体験してください!

筆者
Matt Kang

翻訳はソリューションアーキテクトの瀧田 直斗が担当しました。原文はこちらです。