Amazon Web Services ブログ

zstd 圧縮したコンテナイメージを使用して AWS Fargate の起動時間を短縮する

この記事は Reducing AWS Fargate Startup Times with zstd Compressed Container Images (記事公開日 : 2022 年 10 月 13 日) の翻訳です。

AWS Fargate は、Amazon Elastic Container Service (Amazon ECS) および Amazon Elastic Kubernetes Service (Amazon EKS) 上で動作するコンテナワークロードのためのサーバーレスコンピューティングエンジンです。コンテナオーケストレーターがコンテナワークロードをスケジューリングすると、AWS Fargate はそのワークロードを実行するためのサーバーレスなコンピューティング環境を提供し、Amazon EC2 インスタンスの保護、スケール、管理といった運用のオーバーヘッドから解放してくれます。

AWS Fargate では、Amazon ECS タスクや Kubernetes Pod などのコンテナワークロードは、ワークロード終了後に再利用されないシングルユースかつシングルテナントのインスタンスで実行されます。AWS Fargate でワークロードを実行する際に必要なコンテナイメージは、各 Amazon ECS タスクまたは Kubernetes Pod ごとにダウンロードされます。一方で、Amazon ECS コンテナインスタンスKubernetes ノードなどのマルチテナントインスタンスでは、同じワークロードのレプリカによってコンテナイメージがすでにホスト上に存在している可能性があります。マルチテナントインスタンスと比較して、AWS Fargate では毎回イメージをダウンロードして展開する必要があるため、ワークロードの起動が遅くなる可能性があります。zstd 圧縮したコンテナイメージを使用してコンテナイメージの展開を高速化することで、AWS Fargate の起動時間の短縮に役立ちます。

コンテナイメージは、実行時にオーバーレイファイルシステムとして積み重ねられるレイヤーのバンドルとして配布されます。コンテナイメージビルダーは、Amazon Elastic Container Registry (Amazon ECR) などのイメージレジストリにプッシュする際に、各イメージレイヤーを圧縮します。デフォルトでは、コンテナイメージビルダーは gzip 圧縮アルゴリズムを使用して各コンテナイメージレイヤーを圧縮します。コンテナランタイムが各イメージレイヤーをダウンロードすると、ランタイムはその内容をコンテナランタイムストレージシステムに解凍します。

コンテナイメージビルダーとコンテナランタイムは、gzip の代替となるイメージレイヤーの圧縮アルゴリズムとして、zstd をサポートしています。zstd は Meta 社が開発した圧縮アルゴリズムで、同社独自のベンチマークでは、gzip 圧縮アルゴリズムよりも高い圧縮率と高い解凍速度を達成することが示されています。

私たちは、AWS Fargate で zstd 圧縮したコンテナイメージを利用したテストを実施し、Amazon ECS タスクあるいは Kubernetes Pod の起動時間が最大で 27% 短縮されることを確認しました。起動時間の短縮の程度はコンテナイメージによって異なり、より大きなコンテナイメージにおいて大幅に改善されます。機械学習、人工知能、データ分析などのユースケースでは、伝統的に大きなコンテナイメージを使用します。そのため、これらのワークロードでは、zstd 圧縮を採用することで絶大な効果を期待できます。

zstd 圧縮アルゴリズムを用いてコンテナイメージをビルドする

コンテナイメージをビルドするツールは、Docker BuildbuildkitBuildah など複数存在します。この記事では、buildkit を使用して zstd 圧縮したコンテナイメージをビルドします。docker build でよく利用される Docker Engine のネイティブイメージビルダーは、現在 zstd コンテナイメージのサポートに向けて開発中です。こちらから、状況を確認できます。

buildkit は、スタンドアローンのコンテナイメージビルドツールで、Linux マシンまたはコンテナ環境で実行できます。buildkit を実行する最も便利な方法は、Docker Buildx と呼ばれる Docker cli プラグインを使用することです。Docker Buildx は、Docker Desktop のインストール時にプリインストールされており、また Docker Engine を実行している Linux ホストに手動でインストールできます。Docker Buildx をインストールした後は、zstd 圧縮を用いてコンテナイメージをビルドするためのコマンドは、docker build ツールセットで慣れ親しんだものとよく似ているでしょう。

# Buildkit コンテナイメージビルダーを作成する
$ docker buildx create \
  --name zstd-builder \
  --driver docker-container \
  --driver-opt image=moby/buildkit:v0.10.3
 
# Buildx コンテキストを新しいビルダーに変更する
$ docker buildx use zstd-builder

# アプリケーションのソースコードディレクトリ内でビルドを実行する
$ docker buildx build \
  --file Dockerfile \
  --output type=image,name=$IMAGE_URI:$IMAGE_TAG,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true,push=true .

上記コマンドの --output フラグを分解してみましょう。

  • type=image – buildkit にコンテナイメージを生成するように指示します。
  • name=$IMAGE_URI:$IMAGE_TAG – 完成したコンテナイメージのイメージ名とイメージタグです。
  • oci-mediatypes=true – (デフォルトの Docker Image v2 Schema 2 標準の代わりに) コンテナイメージを OCI v1 イメージ標準に基づいてビルドします。
  • compression=zstd – デフォルトの gzip 圧縮アルゴリズムの代わりに、zstd 圧縮アルゴリズムを使用します。
  • force-compression=true – このフラグは、既にレジストリに保存されている gzip 圧縮されたイメージレイヤー (コンテナベースイメージなど) を、zstd で再圧縮して異なるイメージレイヤーとして保存するために必要です。
  • compression-level=3 – zstd には 22 段階の圧縮レベルがあります。圧縮レベルが高いほど、コンテナイメージのサイズは小さくなりますが、イメージレイヤーを解凍するための CPU リソースも増加します。AWS Fargate の起動時間を短縮するには、ワークロードの開始前にイメージレイヤーをダウンロードして解凍する必要がありますが、最高レベルの圧縮が最速の AWS Fargate の起動時間をもたらすとは限りません。最適な圧縮レベルを見つけるために、自身のコンテナイメージで検証すると良いでしょう。私たちのテストでは、圧縮レベル 3 が最適でした。
  • push=true – コンテナイメージをビルドした後、そのイメージをレジストリにプッシュします。イメージの圧縮はレジストリにプッシュする際に行われるため、このフラグは必須です。

docker buildx imagetools inspect コマンドでイメージマニフェストを取得することで、レジストリ内のコンテナイメージの圧縮アルゴリズムを確認できます。以下の出力の各イメージレイヤーの mediaType に注目してください。

$ docker buildx imagetools \
    inspect --raw \
    $IMAGE_URI:$IMAGE_TAG
{
   "mediaType": "application/vnd.oci.image.manifest.v1+json",
   "schemaVersion": 2,
   "config": {
      "mediaType": "application/vnd.oci.image.config.v1+json",
      "digest": "sha256:12fe1c9ed0facc73b17a4ceb431c3d160182c67f333e38d0a5677dfa1c18c4b6",
      "size": 14833
   },
   "layers": [
      {
         "mediaType": "application/vnd.oci.image.layer.v1.tar+zstd",
         "digest": "sha256:f2b553fe6ae26832d4beafd0c4ef3c4690b88f340360aef0f79800eb99ba8754",
         "size": 24229715
      },
      {
         "mediaType": "application/vnd.oci.image.layer.v1.tar+zstd",
         "digest": "sha256:7ec3184be813e46f2cd0fa7044d232a09cca5a1594c6e3efc4c7998ad63a1cff",
         "size": 34621023
      },
      ...

AWS Fargate で zstd 圧縮したコンテナイメージを実行する

AWS Fargate プラットフォームバージョンは、AWS Fargate インフラストラクチャの特定の実行環境、すなわちカーネルとコンテナランタイムのバージョンを参照するために使用されます。AWS Fargate プラットフォームバージョン 1.4 では、コンテナランタイムとして containerd を使用します。containerd は、zstd 圧縮したコンテナイメージを実行するための唯一の依存関係です。Amazon ECS または Amazon EKS で AWS Fargate を使用して zstd コンテナイメージを使用するために、プラットフォームまたはランタイムの設定を変更する必要はありません。唯一必要なワークロードの変更は、タスク定義または Pod Spec で参照するコンテナイメージを、zstd 圧縮でビルドした新しいコンテナイメージに更新することだけです。

Amazon EKS でマネージドノードグループまたはセルフマネージドノードを使用しているお客様は、ランタイムとして containerd が有効化されている限り、zstd 圧縮したコンテナイメージを使用できます。

zstd コンテナイメージのサポート状況

zstd レイヤーの暗号化サポートは、アップストリームの Open Container Initiative (OCI) Image Specification にマージされましたが、まだリリースマイルストーンには至っていません。OCI Image Specification の一部として zstd を仕様化するための作業は、こちらで確認できます。

また、開発者ワークフローの一部として、すべてのコンテナツールが zstd 圧縮したコンテナイメージをサポートしている訳ではありません。zstd 圧縮したコンテナイメージの利点がより広く知られるようになるにつれて、開発者ツールのギャップが縮まることが期待されます。まだ zstd をサポートしていない人気のツールは以下の通りです。

  • Docker Engine – zstd 圧縮したコンテナイメージは、Docker Engine では起動できません。Docker Engine の zstd 圧縮したコンテナイメージのサポートに関する状況は、こちらで確認できます。
  • この記事の執筆時点では、Aquasec の TrivyQuay の ClairAmazon ECR ベーシックスキャンなどのコンテナイメージ脆弱性スキャナーは、zstd 圧縮したコンテナイメージレイヤーのスキャンをサポートしていません。(訳注 : 2022 年 10 月 18 日時点で、Amazon Inspector が提供する Amazon ECR 拡張スキャンは zstd 圧縮したコンテナイメージレイヤーのスキャンをサポートしています。Amazon ECR ベーシックスキャンの zstd 圧縮したコンテナイメージレイヤーのサポートはロードマップにあります。)

まとめ

この記事では、AWS Fargate で動作するコンテナワークロードの起動にかかる時間を短縮するために、zstd 圧縮したコンテナイメージを使用する方法を紹介しました。OCI レジストリで既にサポートされていることを含め、コンテナイメージビルダーとコンテナランタイムを利用中のお客様は、zstd 圧縮したコンテナイメージを利用するためにインフラストラクチャを変更する必要はありません。