[アップデート] AWS CodeBuild から、コンテナイメージのビルドを高速化させる、Docker Server 機能がリリースされました
こんにちは!クラウド事業本部コンサルティング部のたかくに(@takakuni_)です。
AWS CodeBuild から、コンテナイメージのビルドを高速化させる、Docker Server 機能がリリースされました。
AWS Blog も合わせて公開されています。
Docker Server 機能
Docker Server 機能は CodeBuild 上で Docker 用にリモートサーバーを別途ホストし、コンテナイメージのビルドを行う機能です。
この機能を使うことで、コンテナイメージのビルドを同一の Docker サーバー上で実行可能(キャッシュが利用可能)になるため、イメージのビルドを高速化させる効果が見込めます。
AWS Blog ではビルド時間を 98% 短縮し、24分54秒から16秒に短縮できた
そうです。(見せ方についてミスリードにならないか、少し気になりますが、それでもキャッシュはありがたいですね)
Accelerate CI/CD pipelines with the new AWS CodeBuild Docker Server capability より画像引用
アップデート前まで
アップデート前まで CodeBuild における、コンテナイメージのキャッシュには、以下の手段が考えられていました。
ローカルキャッシュの場合、ビルドが同一ホスト上であれば、キャッシュを利用できるといった仕組みで、必ずしもキャッシュが利用できる保証がないが、あった時はラッキーくらいのの温度感でした。
対してリザーブドキャパシティの場合は、保持期間を過ぎるとキャッシュがクリアされてしまう仕様で、永続的にキャッシュを保持するのはコスト感が気になる仕様でした。
仕組み
今回の Docker Server 機能は図にすると、以下のイメージです。
- 通常のビルド環境に加えて、
docker
コマンド用にリモートホストを起動 - ビルド環境でコンテナイメージビルドが発生した際に、リモートサーバーへコマンドを伝達
- リモートサーバー上でコンテナイメージのビルド
- 1時間ビルドリクエストが発生しない場合、サーバーが停止しクールダウン期間に入ります
- クールダウン状態からビルドリクエストが発生した場合、サーバーを起動しビルドを開始
- 永続ストレージは、再利用されるまで、最大一ヶ月保持
料金
Docker Server は秒単位の課金です。また、料金層が 2 種類あります。
便宜上、ビルド可能な状態をウォームアップ、休眠期間をクールダウンと表現します。
東京リージョンの場合、
ウォームアップ期間中は、以下の料金で利用されます。
インスタンスタイプ | メモリ | CPU | 1秒あたりの料金 |
---|---|---|---|
arm1.small | 4 GiB | 2 | $0.00004 |
general1.small | 4 GiB | 2 | $0.00004 |
arm1.medium | 8 GiB | 4 | $0.00007 |
general1.medium | 8 GiB | 4 | $0.00008 |
arm1.large | 16 GiB | 8 | $0.00015 |
general1.large | 16 GiB | 8 | $0.00016 |
arm1.xlarge | 64 GiB | 2 | $0.00059 |
general1.xlarge | 64 GiB | 2 | $0.00063 |
arm1.2xlarge | 128 GiB | 4 | $0.00118 |
general1.2xlarge | 128 GiB | 4 | $0.00126 |
クールダウン期間中は、インスタンスタイプにかかわらず、以下の料金が発生します。
Docker Server が有効になっている、各プロジェクトで 1 秒あたり $0.000000037
1 ヶ月(2,592,000 秒)* $0.000000037 = $0.095904 のため、そこまで気にならない価格で、ストレージを保持できそうです。
コスト面で言うと、オンデマンドの分数をどれほどキャッシュで減らせられるかが、肝になってきます。
以下のようにテーブル形式でまとめました。Docker Server が高上がりに見えてしまうのですが、あくまで初回起動時の費用対効果で、額面から見えないキャッシュ利用による、副次的な効果が期待できると思います。
分数 | Docker Server | オンデマンド EC2 | リザーブドキャパシティ |
---|---|---|---|
0.5 | 0.245354 | 0.00425 | 0.153 |
1 | 0.246554 | 0.00425 | 0.153 |
5 | 0.273154 | 0.02125 | 0.153 |
10 | 0.306404 | 0.0425 | 0.153 |
15 | 0.339654 | 0.06375 | 0.153 |
20 | 0.372904 | 0.085 | 0.153 |
25 | 0.406154 | 0.10625 | 0.153 |
30 | 0.439404 | 0.1275 | 0.153 |
35 | 0.472654 | 0.14875 | 0.153 |
40 | 0.505904 | 0.17 | 0.153 |
45 | 0.539154 | 0.19125 | 0.153 |
50 | 0.572404 | 0.2125 | 0.153 |
55 | 0.605654 | 0.23375 | 0.153 |
60 | 0.638904 | 0.255 | 0.153 |
65 | 0.672154 | 0.27625 | 0.16575 |
やってみた
それでは Docker Server を利用して、キャッシュを体感してみます。
以下のサンプルに従い操作してみます。
ファイルの配置
GitHub に buildspec.yml
と Dockerfile
の 2 つを配置しました。
version: 0.2
phases:
build:
commands:
- docker buildx build .
- docker run helloworld echo "Hello, World!"
FROM public.ecr.aws/amazonlinux/amazonlinux:latest
RUN echo "Hello World"
階層は以下に配置しました。
$ tree .
.
├── Dockerfile
├── README.md
└── buildspec.yml
CodeBuild プロジェクトの作成
プロジェクトの作成を行います。名前は適当な名前を付与します。
今回は、CodePipeline やランナーを使わないため、ソースに GitHub を設定しました。
Docker Server Configuration をオンにします。サーバーのスペックは一番小さいものにしました。
初回ビルド時のログは以下のとおりです。#0 building with "codebuild-docker-server" instance using remote driver
とあるように、docker コマンドの処理がリモートサーバーへオフロードされています。
[Container] 2025/05/17 12:08:06.631562 Running on CodeBuild On-demand
[Container] 2025/05/17 12:08:06.631573 Waiting for agent ping
[Container] 2025/05/17 12:08:07.635422 Waiting for DOWNLOAD_SOURCE
[Container] 2025/05/17 12:08:12.509872 Phase is DOWNLOAD_SOURCE
[Container] 2025/05/17 12:08:12.511342 CODEBUILD_SRC_DIR=/codebuild/output/src864880986/src/github.com/takakuni-classmethod/docker-server-cache
[Container] 2025/05/17 12:08:12.512295 YAML location is /codebuild/output/src864880986/src/github.com/takakuni-classmethod/docker-server-cache/buildspec.yml
[Container] 2025/05/17 12:08:12.517714 Setting HTTP client timeout to higher timeout for Github and GitHub Enterprise sources
[Container] 2025/05/17 12:08:12.517852 Processing environment variables
[Container] 2025/05/17 12:08:13.012399 No runtime version selected in buildspec.
[Container] 2025/05/17 12:08:13.041296 Moving to directory /codebuild/output/src864880986/src/github.com/takakuni-classmethod/docker-server-cache
[Container] 2025/05/17 12:08:13.041455 Cache is not defined in the buildspec
[Container] 2025/05/17 12:08:13.201839 Skip cache due to: no paths specified to be cached
[Container] 2025/05/17 12:08:13.202191 Registering with agent
[Container] 2025/05/17 12:08:13.339744 Phases found in YAML: 1
[Container] 2025/05/17 12:08:13.339763 BUILD: 3 commands
[Container] 2025/05/17 12:08:13.340088 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2025/05/17 12:08:13.340100 Phase context status code: Message:
[Container] 2025/05/17 12:08:13.549669 Entering phase INSTALL
[Container] 2025/05/17 12:08:13.696486 Phase complete: INSTALL State: SUCCEEDED
[Container] 2025/05/17 12:08:13.696512 Phase context status code: Message:
[Container] 2025/05/17 12:08:13.732127 Entering phase PRE_BUILD
[Container] 2025/05/17 12:08:13.733663 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2025/05/17 12:08:13.733681 Phase context status code: Message:
[Container] 2025/05/17 12:08:13.771361 Entering phase BUILD
[Container] 2025/05/17 12:08:13.934407 Running command docker buildx build . -t helloworld --load
#0 building with "codebuild-docker-server" instance using remote driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 113B done
#1 DONE 0.1s
#2 [internal] load metadata for public.ecr.aws/amazonlinux/amazonlinux:latest
#2 DONE 1.7s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/2] FROM public.ecr.aws/amazonlinux/amazonlinux:latest@sha256:ff1fad724e2ef77b8851124cbc35204d1defe63128f077021a2b3e459fcd866f
#4 resolve public.ecr.aws/amazonlinux/amazonlinux:latest@sha256:ff1fad724e2ef77b8851124cbc35204d1defe63128f077021a2b3e459fcd866f 0.0s done
#4 DONE 0.0s
#4 [1/2] FROM public.ecr.aws/amazonlinux/amazonlinux:latest@sha256:ff1fad724e2ef77b8851124cbc35204d1defe63128f077021a2b3e459fcd866f
#4 sha256:d680ca3f92ab1808f4ae68645f57801d7a408a68d8d17cd7b28da6cfad1ad3d7 9.44MB / 53.61MB 0.2s
#4 sha256:d680ca3f92ab1808f4ae68645f57801d7a408a68d8d17cd7b28da6cfad1ad3d7 53.61MB / 53.61MB 0.3s done
#4 extracting sha256:d680ca3f92ab1808f4ae68645f57801d7a408a68d8d17cd7b28da6cfad1ad3d7
#4 extracting sha256:d680ca3f92ab1808f4ae68645f57801d7a408a68d8d17cd7b28da6cfad1ad3d7 1.4s done
#4 DONE 1.8s
#5 [2/2] RUN echo "Hello World"
#5 0.107 Hello World
#5 DONE 0.3s
#6 exporting to docker image format
#6 exporting layers 0.1s done
#6 exporting manifest sha256:b071a221ac7d71b9089f9cb4f095efbde2b0024ea93ab26bb87f667cdcea8a6d 0.0s done
#6 exporting config sha256:20ecf30a2a6d2d8fcf222719b38619a1b88193a344f3300f8d39efcd37db0349 0.0s done
#6 sending tarball
#6 sending tarball 3.2s done
#6 DONE 3.2s
#7 importing to docker
#7 loading layer 7d4a31d52899 49.02MB / 53.61MB 2.5s done
#7 loading layer 5f70bf18a086 32B / 32B 0.0s done
#7 DONE 2.5s
[Container] 2025/05/17 12:08:21.399302 Running command docker run helloworld echo "Hello, World!"
Hello, World!
[Container] 2025/05/17 12:08:22.696008 Phase complete: BUILD State: SUCCEEDED
[Container] 2025/05/17 12:08:22.696022 Phase context status code: Message:
[Container] 2025/05/17 12:08:22.731705 Entering phase POST_BUILD
[Container] 2025/05/17 12:08:22.733333 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2025/05/17 12:08:22.733354 Phase context status code: Message:
[Container] 2025/05/17 12:08:22.783955 Set report auto-discover timeout to 5 seconds
[Container] 2025/05/17 12:08:22.784053 Expanding base directory path: .
[Container] 2025/05/17 12:08:22.787205 Assembling file list
[Container] 2025/05/17 12:08:22.787217 Expanding .
[Container] 2025/05/17 12:08:22.790337 Expanding file paths for base directory .
[Container] 2025/05/17 12:08:22.790351 Assembling file list
[Container] 2025/05/17 12:08:22.790401 Expanding **/*
[Container] 2025/05/17 12:08:22.793775 No matching auto-discover report paths found
[Container] 2025/05/17 12:08:22.793793 Report auto-discover file discovery took 0.009838 seconds
[Container] 2025/05/17 12:08:22.793805 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2025/05/17 12:08:22.793888 Phase context status code: Message:
続いて 2 回目の実行ログです。#4 [1/2] FROM public.ecr.aws/amazonlinux/
の処理が省略されていることがわかりますね。
[Container] 2025/05/17 12:08:43.904292 Running on CodeBuild On-demand
[Container] 2025/05/17 12:08:43.904303 Waiting for agent ping
[Container] 2025/05/17 12:08:44.406786 Waiting for DOWNLOAD_SOURCE
[Container] 2025/05/17 12:08:49.060826 Phase is DOWNLOAD_SOURCE
[Container] 2025/05/17 12:08:49.062250 CODEBUILD_SRC_DIR=/codebuild/output/src1766767497/src/github.com/takakuni-classmethod/docker-server-cache
[Container] 2025/05/17 12:08:49.062762 YAML location is /codebuild/output/src1766767497/src/github.com/takakuni-classmethod/docker-server-cache/buildspec.yml
[Container] 2025/05/17 12:08:49.064766 Setting HTTP client timeout to higher timeout for Github and GitHub Enterprise sources
[Container] 2025/05/17 12:08:49.065080 Processing environment variables
[Container] 2025/05/17 12:08:49.520864 No runtime version selected in buildspec.
[Container] 2025/05/17 12:08:49.540633 Moving to directory /codebuild/output/src1766767497/src/github.com/takakuni-classmethod/docker-server-cache
[Container] 2025/05/17 12:08:49.540658 Cache is not defined in the buildspec
[Container] 2025/05/17 12:08:49.686761 Skip cache due to: no paths specified to be cached
[Container] 2025/05/17 12:08:49.687073 Registering with agent
[Container] 2025/05/17 12:08:49.826784 Phases found in YAML: 1
[Container] 2025/05/17 12:08:49.826803 BUILD: 3 commands
[Container] 2025/05/17 12:08:49.827231 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2025/05/17 12:08:49.827244 Phase context status code: Message:
[Container] 2025/05/17 12:08:50.008324 Entering phase INSTALL
[Container] 2025/05/17 12:08:50.158397 Phase complete: INSTALL State: SUCCEEDED
[Container] 2025/05/17 12:08:50.158417 Phase context status code: Message:
[Container] 2025/05/17 12:08:50.194448 Entering phase PRE_BUILD
[Container] 2025/05/17 12:08:50.195628 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2025/05/17 12:08:50.195639 Phase context status code: Message:
[Container] 2025/05/17 12:08:50.229747 Entering phase BUILD
[Container] 2025/05/17 12:08:50.367031 Running command docker buildx build . -t helloworld --load
#0 building with "codebuild-docker-server" instance using remote driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 113B done
#1 DONE 0.0s
#2 [internal] load metadata for public.ecr.aws/amazonlinux/amazonlinux:latest
#2 DONE 0.1s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/2] FROM public.ecr.aws/amazonlinux/amazonlinux:latest@sha256:ff1fad724e2ef77b8851124cbc35204d1defe63128f077021a2b3e459fcd866f
#4 resolve public.ecr.aws/amazonlinux/amazonlinux:latest@sha256:ff1fad724e2ef77b8851124cbc35204d1defe63128f077021a2b3e459fcd866f 0.0s done
#4 DONE 0.0s
#5 [2/2] RUN echo "Hello World"
#5 CACHED
#6 exporting to docker image format
#6 exporting layers done
#6 exporting manifest sha256:b071a221ac7d71b9089f9cb4f095efbde2b0024ea93ab26bb87f667cdcea8a6d done
#6 exporting config sha256:20ecf30a2a6d2d8fcf222719b38619a1b88193a344f3300f8d39efcd37db0349 done
#6 sending tarball
#6 sending tarball 3.1s done
#6 DONE 3.1s
#7 importing to docker
#7 loading layer 7d4a31d52899 49.58MB / 53.61MB 2.5s done
#7 loading layer 5f70bf18a086 32B / 32B 0.0s done
#7 DONE 2.5s
[Container] 2025/05/17 12:08:54.039390 Running command docker run helloworld echo "Hello, World!"
Hello, World!
[Container] 2025/05/17 12:08:55.283402 Phase complete: BUILD State: SUCCEEDED
[Container] 2025/05/17 12:08:55.283421 Phase context status code: Message:
[Container] 2025/05/17 12:08:55.323332 Entering phase POST_BUILD
[Container] 2025/05/17 12:08:55.326389 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2025/05/17 12:08:55.326409 Phase context status code: Message:
[Container] 2025/05/17 12:08:55.374737 Set report auto-discover timeout to 5 seconds
[Container] 2025/05/17 12:08:55.374779 Expanding base directory path: .
[Container] 2025/05/17 12:08:55.377847 Assembling file list
[Container] 2025/05/17 12:08:55.377862 Expanding .
[Container] 2025/05/17 12:08:55.380902 Expanding file paths for base directory .
[Container] 2025/05/17 12:08:55.380913 Assembling file list
[Container] 2025/05/17 12:08:55.380917 Expanding **/*
[Container] 2025/05/17 12:08:55.384283 No matching auto-discover report paths found
[Container] 2025/05/17 12:08:55.384301 Report auto-discover file discovery took 0.009564 seconds
[Container] 2025/05/17 12:08:55.384377 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2025/05/17 12:08:55.384439 Phase context status code: Message:
まとめ
以上、「AWS CodeBuild から、コンテナイメージのビルドを高速化させる、Docker Server 機能がリリースされました。」でした。
普段、頻繁にデプロイが起きている場合だと、キャッシュを活かしてビルド時間の短縮が図れそうでした。
クラウド事業本部コンサルティング部のたかくに(@takakuni_)でした!