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

DockerCIビルドを一歩先へ Buildkitを運用前提で試食してみた / Docker ci with buildkit

DockerCIビルドを一歩先へ Buildkitを運用前提で試食してみた / Docker ci with buildkit

Hiroki Tanaka

June 14, 2019
Tweet

More Decks by Hiroki Tanaka

Other Decks in Programming

Transcript

  1. DockerCIビルドを
    一歩先へ
    Buildkitを
    運用前提で
    試食してみた
    2019/06/14
    タナカヒロキ @dabits

    View Slide

  2. 自己紹介
    {
    id: ‘dabits’,
    name: ‘タナカヒロキ’,
    company: ‘株式会社エイチームライフスタイル’,
    division: ‘CTO室 (like a SRE)’,
    hobby: ‘アニソンDJ’,
    }

    View Slide

  3. View Slide

  4. 前回のあらすじ

    View Slide

  5. この数ヶ月、
    KPIにCI/CDの時間を設定して
    ビルドの高速化を
    してきました。

    View Slide

  6. その一環でDocker buildの
    チューニングを
    行ってきました。

    View Slide

  7. multi stage buildを使って
    やっと早くなってきたぞ!

    View Slide

  8. そんなとき

    View Slide

  9. DockerCon ‘19でとある発表が

    View Slide

  10. https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices

    View Slide

  11. https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices

    View Slide

  12. 今まで調べたこと
    全部書いてあるやんけ

    View Slide

  13. 今からビルドを早くしたい人

    View Slide

  14. https://www.slideshare.net/Docker/dcsf19-dockerfile-best-practices

    View Slide

  15. 絶対読んだ方がいいですよ!
    全部詰まってます!

    View Slide

  16. というお話でした。

    View Slide

  17. その次の改善ポイント

    View Slide

  18. 昨年発表された
    「Buildkit」を使った高速化

    View Slide

  19. https://docs.google.com/presentation/d/1fy_xBVY15fNEOs0
    DbuY79wKmp_POBBHAeZaGCUNQi-M/edit#slide=id.g3b87
    b4748c_0_0

    View Slide

  20. が、今回のお話です。

    View Slide

  21. View Slide

  22. Buildkit導入対象
    ● Ruby on rails
    ● Assets precompileを使っている
    ● Webpacker compileも使っている(移行期間中, 併用期)

    View Slide

  23. 早速Buildkit対応
    していきましょう

    View Slide

  24. View Slide

  25. Buildkitでの高速化ポイント
    ● 並列ビルド
    ○ multi stage buildになっていれば空気を読んで並列に
    ● キャッシュマウント
    ○ RUNの頭に--mount-type=cache,target=/hoge
    command...と書くと該当のディレクトリをマウントして
    キャッシュしてくれる

    View Slide

  26. 今回の並列ビルド対象
    ● 1つ目のペア : bundle install vs yarn install
    ● 2つ目のペア : assets precompile vs webpack compile

    View Slide

  27. 今回のキャッシュマウント対象
    ● apk install
    ● bundle install
    ● yarn install
    ● assets precompile
    ● webpack compile

    View Slide

  28. View Slide

  29. bundleとyarnの
    並列インストール

    View Slide

  30. FROM ruby:2.5.5-alpine3.8 as builder
    RUN apk update && apk upgrade && \
    apk add --no-cache git mysql-dev nodejs nodejs-npm libxml2-dev imagemagick-dev && \
    npm install -g yarn
    WORKDIR /app
    COPY Gemfile Gemfile.lock ./
    RUN bundle install -j4 --without development test deployment
    COPY package.json yarn.lock ./
    RUN yarn install --production --frozen-lockfile

    View Slide

  31. # syntax = docker/dockerfile:experimental
    FROM ruby:2.5.5-alpine3.8 as base-builder
    RUN apk update && apk upgrade && \
    apk add --no-cache git mysql-dev nodejs nodejs-npm libxml2-dev imagemagick-dev && \
    npm install -g yarn
    WORKDIR /app
    FROM base-builder as bundle-builder
    COPY Gemfile Gemfile.lock ./
    RUN bundle install -j4 --without development test deployment
    FROM base-builder as yarn-builder
    COPY package.json yarn.lock ./
    RUN yarn install --production --frozen-lockfile

    View Slide

  32. assetsとwebpackの
    並列コンパイル

    View Slide

  33. ...
    COPY ./app/assets /app/app/assets
    RUN bundle exec rails assets:precompile
    ...
    COPY frontend ./frontend
    RUN yarn run webpack --config config/webpack/production.js

    View Slide

  34. FROM base-builder as modules-builder
    COPY --from=bundle-builder /app/Gemfile /app/Gemfile.lock ./
    COPY --from=yarn-builder /app/package.json /app/yarn.lock ./
    FROM modules-builder as assets-builder
    ...
    COPY ./app/assets /app/app/assets
    RUN bundle exec rails assets:precompile
    FROM modules-builder as webpack-builder
    ...
    COPY frontend ./frontend
    RUN yarn run webpack --config config/webpack/production.js

    View Slide

  35. FROM ruby:2.5.5-alpine3.8 as release

    COPY --from=builder /app/vendor/bundle/ /app/vendor/bundle/

    View Slide

  36. FROM ruby:2.5.5-alpine3.8 as release

    COPY --from=modules-builder /app/vendor/bundle /app/vendor/bundle
    COPY --from=webpack-builder /app/public /app/public
    COPY --from=assets-builder /app/public /app/public

    View Slide

  37. キャッシュマウント

    View Slide

  38. ...
    RUN apk update && apk upgrade && \
    apk add --no-cache git mysql-dev nodejs nodejs-npm libxml2-dev imagemagick-dev && \
    npm install -g yarn
    WORKDIR /app

    View Slide

  39. ...
    RUN --mount=type=cache,target=/var/cache/apk \
    apk update && apk upgrade && \
    apk add --no-cache git mysql-dev nodejs nodejs-npm libxml2-dev imagemagick-dev && \
    npm install -g yarn
    WORKDIR /app

    View Slide

  40. ...
    FROM base-builder as bundle-builder
    COPY Gemfile Gemfile.lock ./
    RUN bundle install -j4 --without development test deployment
    FROM base-builder as yarn-builder
    COPY package.json yarn.lock ./
    RUN yarn install --production --frozen-lockfile

    View Slide

  41. ...
    FROM base-builder as bundle-builder
    COPY Gemfile Gemfile.lock ./
    RUN --mount=type=cache,target=/app/tmp \
    bundle install --path=/app/tmp/bundle -j4 --without development test deployment
    FROM base-builder as yarn-builder
    COPY package.json yarn.lock ./
    RUN --mount=type=cache,target=/app/tmp \
    --mount=type=cache,target=/usr/local/share/.cache/yarn \
    yarn install --modules-folder=/app/tmp/node_modules --production --frozen-lockfile

    View Slide

  42. FROM base-builder as modules-builder
    COPY --from=bundle-builder /app/Gemfile /app/Gemfile.lock ./
    COPY --from=yarn-builder /app/package.json /app/yarn.lock ./

    View Slide

  43. FROM base-builder as modules-builder
    COPY --from=bundle-builder /app/Gemfile /app/Gemfile.lock ./
    COPY --from=yarn-builder /app/package.json /app/yarn.lock ./
    RUN --mount=type=cache,target=/app/tmp \
    mkdir -p /app/vendor && \
    cp -r /app/tmp/bundle /app/vendor/bundle && \
    cp -r /app/tmp/node_modules /app/node_modules

    View Slide

  44. ..
    COPY ./app/assets /app/app/assets
    RUN bundle exec rails assets:precompile
    ...
    COPY frontend ./frontend
    RUN yarn run webpack --config config/webpack/production.js

    View Slide

  45. ..
    COPY ./app/assets /app/app/assets
    RUN --mount=type=cache,target=/app/tmp \
    mkdir -p /app/tmp/assets /app/public && mv /app/tmp/assets /app/public/assets && \
    bundle exec rails assets:precompile && \
    cp -r /app/public/assets /app/tmp/assets
    ...
    COPY frontend ./frontend
    RUN --mount=type=cache,target=/app/tmp \
    mkdir -p /app/tmp/packs /app/public && mv /app/tmp/packs /app/public/packs && \
    yarn run webpack --config config/webpack/production.js && \
    cp -r /app/public/packs /app/tmp/packs

    View Slide

  46. 結果

    View Slide

  47. 結果
    ● Dockerfile : 約140行!
    ● ビルド時間
    ○ 初回フルビルド : 853s→683s (x1.25 Faster)
    ○ packageを追加 : 844s→294s (x2.87 Faster)
    ○ assetsのみを更新 : 482s→208s (x2.32 Faster)
    ※AWS EC2 t3.small : 2Core, Memory 2GB, Swap 4GBで検証

    View Slide

  48. ここまでが
    ローカル上でのお話

    View Slide

  49. いかにしてCIに組み込むか

    View Slide

  50. CIに組み込む際のポイント
    ● Docker layer cacheを保持できること
    ○ buildkitは--cache-fromが使えない
    ○ docker layer cacheに頼らざるを得ない
    ● mountしたデータを保持できること
    ○ dindで都度立ち上げるとmountデータが消えてしまう

    View Slide

  51. 考えうる選択肢
    ● dockerdを共通で使う・・・✗
    ○ 並列で複数サービスのビルドが走ると詰まる
    ● dindの/var/lib/dockerを保持させる・・・✗
    ○ 実装が大変すぎる
    ● buildkit対応しているクラウドサービスを使う・・・△
    ○ AWS:cacheが途中でexpire, GCP:非対応, CircleCIなら

    View Slide

  52. うちはGitlab-CIを使っているので

    View Slide

  53. 諦めました

    View Slide

  54. みんなどうしてるんだろう?

    View Slide

  55. 今後試してみようと思うこと
    ● 1サービス1dockerdをCI用に立てたままにする
    ○ pros : 手軽にキャッシュを保持できる
    ○ cons : サービス増えるたびにdockerd増やすの...?
    ● Buildkitを捨ててGCP+Kanikoにする
    ○ pros : CI周りの面倒なことを考えなくて済む
    ○ cons : 並列vsKanikoの最適化はどれだけ差があるか?

    View Slide

  56. と、この資料
    書いている途中に

    View Slide

  57. https://medium.com/nttlabs/buildkit-on-kubernetes-d37a0
    3150192

    View Slide

  58. 事例出てきたやんけ

    View Slide

  59. NTT須田さんいつも
    ありがとうございます!

    View Slide

  60. View Slide

  61. まとめ
    ● Buildkitでビルドを高速化するには
    ○ 並列ビルド+キャッシュマウント
    ● CIのフローに組み込むには
    ○ 規模が小さければdockerd使い回しでOK
    ○ 規模が大きければお金払うor実装する必要ありかも
    ● Dockerfile Best Practices はバイブル
    ● 最近のBuildkit事情はNTT須田さんの資料をみる

    View Slide

  62. ありがとうございました

    View Slide

  63. Any Questions?

    View Slide