Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CircleCIでLayer Cachingを使わずにdocker buildを高速化する

CircleCIでLayer Cachingを使わずにdocker buildを高速化する

【東京】CircleCI ユーザーコミュニティ ミートアップ #9
https://circleci.connpass.com/event/242577/

URLリンクも有効なGoogle Slide版は
https://docs.google.com/presentation/d/1UpRyHsdx4bpBWE9P0VWznVCcupmjVWfmEXRoMbcAeIQ/edit?usp=sharing

Kenta Kase

April 21, 2022
Tweet

More Decks by Kenta Kase

Other Decks in Programming

Transcript

  1. 自己紹介 所属:DeNAのSWETグループ(SoftWare Engineer in Test) Twitter: @Kesin11, GitHub: Kesin11 CI/CDサービスのマニアなので有名なサービスは大体チョットワカル

    主な業務 モバイルゲーム開発のJenkins構築、運用、パイプライン構築 社内CircleCI Serverの運用チーム
  2. RUN –mount=type=cache (正式な名称はよくわからない。便宜上Mount cacheと呼びます) DockerfileのRUNに追加する RUN --mount=type=cache,target=/root/.cache/go-build go build …

    RUN中にディレクトリ指定でマウントしたボリュームを次のビルドで使い回す パッケージやビルドキャッシュを使い回せると次のビルドが早くなる
  3. Registry cache docker buildx build -f Dockerfile \ --cache-to=type=registry,mode=max,ref=$CACHE_IMAGE:cache \

    --cache-from=type=registry,ref=$CACHE_IMAGE:cache \ -t $IMAGE:latest . ビルドするイメージとは別にキャッシュ用レイヤーを別イメージとしてpushする mode=maxにするとマルチステージの中間も含めて全レイヤーがpushされる マルチステージビルドでもキャッシュを有効に使える
  4. Registry cache docker buildx build -f Dockerfile \ --cache-to=type=registry,mode=max,ref=$CACHE_IMAGE:cache \

    --cache-from=type=registry,ref=$CACHE_IMAGE:cache \ -t $IMAGE:latest . キャッシュとしてのイメージはdocker run可能なものではないので混ざらない ようにイメージ名を別にした方が安全 CircleCIはコンテナレジストリの機能を提供していないので GitHub/AWS/GCPあたりのレジストリを自分で用意する
  5. Local cache docker buildx build -f Dockerfile \ --cache-to=type=local,mode=max,dest=/tmp/docker_cache \

    --cache-from=type=local,src=/tmp/docker_cache \ -t $IMAGE:latest . キャッシュ用レイヤーをローカルに書き出す キャッシュとしての効果はRegistryと同じ mode=maxの効果も同じ
  6. Local cache docker buildx build -f Dockerfile \ --cache-to=type=local,mode=max,dest=/tmp/docker_cache \

    --cache-from=type=local,src=/tmp/docker_cache \ -t $IMAGE:latest . CircleCIのキャッシュ機能と併用して次回のビルドで使い回せる 注意:書き出されるディレクトリの中身は上書きではなく太り続ける キャッシュ戦略をミスると古いファイルも残り続けてしまい、無駄なネット ワーク転送が増え続けて本末転倒になってしまう
  7. 実験 CircleCI-Public/circleci-cliをforkしてdocker build中でバイナリをビルド するようなDockerfileを作成 中身はほぼ go mod, go build これをCircleCI上でビルドさせる

    https://github.com/Kesin11/my-circleci-docker-build-sandbox 詳細が気になる人はDockerfileや.circleci/config.ymlを参照
  8. おまけ:CircleCI上のbuildxのセットアップ 実はRegistry cacheを使うには以下のコマンドでbuildxの設定が必要 docker buildx create --use ローカルでは問題ないがCircleCIだと以下のようなエラーになった error: could

    not create a builder instance with TLS data loaded from environment. Please use `docker context create <context-name>` to create a context for current environment and then create a builder instance with `docker buildx create <context-name>` ワークアラウンドとして以下のようにセットアップすれば動く docker context create circleci docker buildx create --use circleci 参考 https://support.circleci.com/hc/en-us/articles/360058095471-How-To-Use-Docker-Buildx-in-Remote-Docker- http://www.er.crichardson.com/post/microservices/2022/01/18/build-multi-arch-docker-images-circleci.html
  9. おまけ:.dockerignoreが超重要 何気ない `COPY . .` がキャッシュを無効化する docker build時にディレクトリの中身がcontextとしてビルダーに送られる contextも完全に一致しないとレイヤーキャッシュが効かない docker

    buildするのに本来は不要なファイルが含まれていないか? .git/の中身はコミットされるごとに変わる .circleci/config.ymlは当然CircleCIの設定を変更すると変わる .gitは気をつけていたが、.circleciを忘れていて実験を何度かやり直すハメになり ました・・・キャッシュの振る舞いが変だと思ったら.dockerignoreをチェックしよう
  10. 参考 RUN —mount=type=cacheの公式ドキュメント(buildkit) buildkitのREADME(Cacheの項目) docker buildx buildの公式ドキュメント How To Use

    Docker Buildx in Remote Docker?(CircleCI Support Center) BuildKitでイメージをビルドする(buildkitとbuildxの解説) Dockerイメージのビルドで使うキャッシュの種類 - レイヤーキャッシュ、BuildKit の--mount=type=cache