【ビルド高速化!】AWS CodeBuildが次世代高速コンテナビルドのBuildKitをサポートしました

216件のシェア(すこし話題の記事)

「え?これまじか、やばいやろ」

年明け、正月休みモードでのんべんたらりとFacebookを眺めていたら、驚きのニュースが!しばらく、全然更新される気配がなかったCode BuildのDockerランタイムバージョンが、いきなり最新にアップデートされたとのことです。

AWS CodeBuild で Docker 18.09 が使えるようになったので BuildKit をためしてみた

BuildKitは次世代高速コンテナビルドで、ちょっとした設定変更で皆さんのDockerビルドも高速化できる可能性が十分あるので、是非導入を検討してみましょう。

BuildKit きたか…!!

  ( ゚д゚) ガタッ
  /   ヾ
__L| / ̄ ̄ ̄/_
  \/   /

AWS Code BuildのDockerランタイムバージョン18.09.0対応

今回のアップデートで、AWS Code Buildで利用できるマネージド型イメージのDockerランタイムに、バージョン18.09.0が新たに利用できるようになりました。リリース内容はこちら。

Docker Images Provided by AWS CodeBuild - AWS CodeBuild

従来、AWS Code Buildで提供されていたDockerバージョンは17.09.0で、Docker本家でのリリース日が2017年9月26日と、結構古いものでした。

今回新しく提供されたバージョン18.09.0は2018年11月8日リリースのもので、2019年1月4日現在の最新Dockerバージョンとなります。

Docker Engine release notes | Docker Documentation

AWS Code Buildでは、ビルド環境として自分でビルドしたコンテナイメージを使うこともできますが、今回マネージドとして提供されたことによりイメージの管理を自分で実施する必要なく、AWS公式のセキュアなビルドイメージを利用することができます。

バージョン18.09.0対応でなにがうれしいの?

一番インパクトがあるのが、BuildKitへの対応です。BuildKitのメンテナであるNTT須田さんのスライドがめちゃくちゃわかりやすいので、まずは一読をオススメします。従来のDocker buildの不満点とBuildKitによる改善点がまとまっています。

BuildKitによる高速でセキュアなイメージビルド

DAG構造を採用した中間言語であるLLBを用いることで、各レイヤーの依存関係を正確に表現し、キャッシュが良く効くようになっています。これにより、従来はマルチステージビルドにおいて依存関係がないビルドも直列で実行されていたのが、BuildKitによる並列実行が可能になっています。

BuildKitの使い方は、環境変数DOCKER_BUILDKIT1を設定するだけ。

また、新しいDockefile構文RUN --mount=type=cacheや、機密情報を安全にマウント可能なRUN --mount=type=secretによる、S3やSSH鍵のコンテナ内利用もサポートされています。

BuildKitまとめ

その他BuildKitのまとめを須田さん資料より引用しますが、これ完全に次世代ビルドです。

  • Dockerfileの各ステージを並列実行できる
  • コンパイラやパッケージマネージャのキャッシュを使える
  • AWSやSSHなどの鍵を安全に扱える
  • Dockerfile以外の言語も使える(Buildpackesなど)
  • root権限無しで実行できる
  • 最新のDockerなら、export DOCKER_BUILDKIT=1するだけですぐに使える

Code BuildでmobyプロジェクトをBuildKitでBuildしてみる

AWS Code Buildを利用して、BuildKitの有無によるビルド時間の比較を実施してみます。

利用するDockerfile

今回は本家mobyプロジェクトのDockerfileを利用します(mobyプロジェクトは、OSSとしてのDocker)。

moby/moby: Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

利用するbuildspec.yml

今回、BuildKitの有無でビルド時間の差分を把握するため、Code Buildで利用するbuildspec.ymlを2種類用意します。環境変数のセットとDockerビルドするだけの非常にシンプルなものです。

BuildKitを利用するときは、環境変数DOCKER_BUILDKIT1をセットする必要があるため、それぞれの環境変数に00と1を用意しました。また、ビルド時のキャッシュを無効にするために、両方で--rm --no-cacheを指定します。

version: 0.2

env:
  variables:
    DOCKER_BUILDKIT: "0"

phases:
  build:
    commands:
      - docker build --rm --no-cache -t moby:normal .
version: 0.2

env:
  variables:
    DOCKER_BUILDKIT: "1"

phases:
  build:
    commands:
      - docker build --rm --no-cache -t moby:buildkit .

これらのファイルを、Forkしたmobyプロジェクトのリポジトリ直下に追加し、Pushしておきます。

CodeBuildの設定

CodeBuildの設定は非常にシンプル。今回は、BuildKit用とノーマル用の2つのビルドプロジェクトを用意します。

  • プロジェクト名
    • ノーマル用:moby-normal-build
    • BuidKit用:moby-buildkit-build
  • ソース:上で用意したリポジトリを選択。

  • 環境:マネージド型イメージのDockerランタイムで、バージョン18.09.0が選択可能になっているのでそちらを指定。

  • Buildspec
    • ノーマル用:normal_buildspec.yml
    • BuidKit用:buildkit_buildspec.yml

その他は全てデフォルトにしておきます。

ビルド時間が約1.36倍向上

それぞれのビルドプロジェクトを起動し、ビルドにかかった時間を測定しました。

  • ノーマル用でのビルド時間:7分12秒
  • BuildKit用でのビルド時間:5分16秒

ビルド時間で約1.36倍の速度向上が確認できました。もちろんこの値は、Dockerfileの構造やCode Buildで利用するコンピューティング環境に依存するので一概には言えませんが、ランタイムバージョンを挙げて、環境変数を設定しただけの結果としてはかなりインパクトがあるんじゃないでしょうか。

BuildKitを利用すると、ビルドログの出力内容も変わるので面白いです。ぜひ皆さんも一度お試しください。ローカル環境でやっても楽しいですよ。

ノーマル用ビルドのログ。

BuildKit用ビルドのログ。

前バージョンCode BuildからBuildKitへの移行方法

現在、Code BuildでDocker buildしてい人も非常に多いかと思いますが、BuildKitへ移行するときの変更点は基本的に以下の2つのみです。

  • ランタイムバージョンの変更(17.09.0 → 18.09.0)
  • ビルド環境への環境変数の設定(export DOCKER_BUILDKIT=1)

Code Buildに対して環境変数を設定方法として、上の例ではbuildSpec.ymlに指定しましたが、他にも設定方法は複数あります。

  • buildspec.ymlのvariablesで指定
  • buildspec.ymlのparameter-storeで指定
  • CodeBuildプロジェクトの環境変数で指定
  • ビルド実施時の環境変数上書き

このあたりは下記記事が非常に詳しいので、是非皆さんの環境に合わせて一番運用がフィットしている方法を選択いただければと思います。

[CodeBuild]buildspec.ymlでの環境変数指定方法あれこれまとめ | DevelopersIO

まとめ「簡単な設定変更で、コンテナ運用のライフサイクル全般が高速化される可能性有り」

Dockerビルドの高速化は、コンテナ開発〜運用のライフサイクルにおいて非常に重要な要素です。

Dockerを普段遣いされている環境では、CI/CDも整備されていてコードプッシュからの自動ビルド→環境適用を自動化している人も多いんじゃないでしょうか。特に、すでにマルチステージビルドを採用していてそれらのステージに依存関係がない場合は、確実に早くなります。

もちろん、事前検証による評価は必須ですが前述したように設定変更はそれほど手間ではないため、まずは皆さんの環境で気軽に試してみていただければと思います。

それでは、今日はこのへんで。濱田(@hamako9999)でした。

docker buildの参考記事

先日参加したこちらのイベント、docker buildに命をかけた人たちの超マニアックで有用な話が満載だったので、Dockerfileの書き方に悩んでいる全ての人にオススメです。

【docker buildのマニアックすぎる狂宴】Container Build Meetup #1に参加してきた #container_build | DevelopersIO