こんにちは、キエンです。
現在、いこレポにてCodeBuildを使用してDockerイメージのビルドや自動化テストなどを実行しています。 開発効率を上げるため、CodeBuildの実行時間を改善しようと思っています。一つの改善案としてDocker レイヤーキャッシュを使用することです。
AWS CodeBuildのローカルキャッシュを試してみる
AWS CodeBuildのローカルキャッシュってとは
今年2月にCodeBuildのローカルキャッシュ機能が公開されました。ローカルキャッシュの特徴は
- ビルドホストのみが利用できるキャッシュをそのビルドホストにローカルに保存する
- キャッシュはビルドホストですぐに利用できる
- 大規模な中間ビルドアーティファクトに適当する
- ビルドパフォーマンスはネットワーク転送時間の影響を受けない
- 3つのキャッシュモードがあり( 1 つ以上選択する必要ある)
- Docker レイヤーキャッシュ
- ソースキャッシュ
- カスタムキャッシュ
Docker レイヤーキャッシュを実際に試してみる
対象ビルドプロジェクト
- 自動化テスト実行のビルドプロジェクト
- ECRからDockerイメージをプルする
- コンテナを立ち上げて、Rspecを実施する
- Dockerイメージビルドのビルドプロジェクト
- Dockerイメージをビルドする
- ECRにプッシュする
アーティファクト設定
結果
自動化テスト実行のビルドプロジェクト
設定前
設定後 設定後、2回目の実行にDockerイメージのプルはローカルキャッシュから使用するようになって、2分を減らせました。たったの 簡単設定ですぐに効果が出ていますね。
Dockerイメージビルドのビルドプロジェクト
設定前
設定後 これはスゴイですね。設定後、2回目の実行に6分34秒から23秒になりました。完全に改善できそうですね。ただが。。。
一時間後、再実行 一時間後、もう一度やってみたら、ローカルキャッシュを使用できなくなって、設定前の状態に戻りました。次のビルドはまたローカルキャッシュを使用できるようになります。
=> ローカルキャッシュはビルド後一時的のみ使用できるそうです。
結論
- 設定が簡単、すぐに使える
- Dockerのイメージのプルやビルドする際の高速化が望める
- ローカルキャッシュはビルド後一時的のみ使用できる
- 希薄なビルドを実行している場合は、利点が得られない
いこレポで自動化テストのビルドは一日中でよくやっているため、AWS CodeBuildのDocker レイヤーキャッシュを使用すると効果が出ています。 一方、Dockerイメージビルドのビルドは希薄に実行しているので、利点が得られないです。
Dockerイメージビルドする時--cache-fromの使用を試してみる
最近、Dockerイメージのビルド高速化といえば、BuildKitがよく聞かれていますね。 BuildKit使用する、使用しないの場合、--cache-fromの使用方が異なるため、BuildKitもちょっとお話したいと思います。
BuildKitってとは
BuildKitは次世代高速コンテナビルドで以下の特徴があり
- Dockerfileの各ステージを並列実行できる
- コンパイラやパッケージマネージャのキャッシュを使える
- AWSやSSHなどの鍵を安全に扱える
- Dockerfile以外の言語も使える(Buildpackesなど)
- root権限無しで実行できる
- 最新のDockerなら、export DOCKER_BUILDKIT=1するだけですぐに使える
BuildKitはすごいと思いますが、いこレポのDockerイメージは複数ステージではないのでBuildKitを使用してもあまり効果が出ていません。
サポートDockerバージョン
サポートバージョン | |
---|---|
--cache-from | 17.09以上 |
BuildKit | 18.09以上 |
BuildKitを使用なしで--cache-fromを付けるDockerビルドを試してみる
buildspec.ymlの変更
現在の buildspec.yml
version: 0.2 phases: pre_build: commands: - $(aws ecr get-login --no-include-email --region ap-northeast-1) build: commands: - docker build -t ${IMAGE_REPO_NAME}:base -f ./config/docker/Dockerfile-rails-base post_build: commands: - docker push ${REPO_DOMEIN}/${IMAGE_REPO_NAME}:base
buildspec .ymlを以下のように書きます。
- イメージビルドする前にECRから前回にビルド済みのイメージをプルする
- イメージビルドする時、--cache-fromを付けると、pre_buildでプルしたイメージをキャッシュとして使用して新規のイメージをビルドする
version: 0.2 phases: pre_build: commands: - $(aws ecr get-login --no-include-email --region ap-northeast-1) # ECRから前回にビルド済みのイメージをプルする - docker pull ${REPO_DOMEIN}/${IMAGE_REPO_NAME}:base || true build: commands: # --cache-fromを付けると、pre_buildでプルしたイメージをキャッシュとして使用して新規のイメージをビルドする - docker build --cache-from ${REPO_DOMEIN}/${IMAGE_REPO_NAME}:base -t ${IMAGE_REPO_NAME}:base -f ./config/docker/Dockerfile-rails-base post_build: commands: - docker push ${REPO_DOMEIN}/${IMAGE_REPO_NAME}:base
結果
ビルドコストは6分33秒から1分50秒になりました。数時間後再実行しても効果が出ていますね。嬉しいです。
ビルドのログでUsing Cacheが表示すれば成功ですね。
今回の実験は効果を見えましたが、イメージプルのコストとイメージビルドのコストからキャッシュを使用する価値があるかどうか考えた方が良いと思います。 データ量だけ多くてイメージ等、逆に遅くなることもあります。
BuildKitを使用ありで--cache-fromを付けるDockerビルドを試してみる
環境変数はDOCKER_BUILDKIT=1をしてから、「BuildKitを使用なし」場合の通りにもう一度やってみます。
残念ですが、今回エラーが出ていました。
調べてみたら、BuildKitを使用するとキャッシュフォーマットが異なるため、直接--cache-fromを使用できません。 その代わり、buildctl build --export-cacheする必要がありそうです。 github.com
ちなみに、BuildKitを使用する場合、--cache-fromを使用するため、現時点で以下のことをする必要があります。
- buildctlをインストールする (buildkit Github)
- buildctl build --export-cacheを使用して、イメージのキャッシュをエクスポートする
# --export-cache options # mode=min (default): only export layers for the resulting image # mode=max: export all the layers of all intermediate steps # ref=docker.io/user/image:tag: reference for registry cache exporter # dest=path/to/output-dir: directory for local cache exporter buildctl build --export-cache ${REPO_DOMEIN}/${IMAGE_REPO_NAME}:base
- export-cacheが完了したら、これでdocker build --cache-from を使えるようになる
まとめ
- AWS CodeBuildのローカルキャッシュ
- 設定が簡単、すぐに使える
- Dockerのイメージのプルやビルドする際の高速化が望める
- ローカルキャッシュはビルド後一時的のみ使用できる
- 希薄なビルドを実行している場合は、利点が得られない
- Dockerイメージビルドする時--cache-fromを付ける
- ポイントは:
- イメージビルドする前にECRから前回にビルド済みのイメージをプルする
- イメージビルドする時、--cache-fromを付けると、pre_buildでプルしたイメージをキャッシュとして使用して新規のイメージをビルドする
- Dockerのイメージのビルドする際の高速化が望める
- イメージプルのコストとイメージビルドのコストからキャッシュを使用する価値があるかどうか判断が必須
- データ量だけ多くてイメージ等、逆に遅くなることもある
- BuildKitを使用する場合、直接--cache-fromを使用できない、buildctl build --export-cacheをする必要あり
- ポイントは:
最後に
アクトインディではエンジニアを募集していますね、ぜひご応募してください。 actindi.net