Skip to main content
Copyright(c)2022 NTT Corp. All Rights Reserved.
BuildKitの概要と最近の機能
2022/8/20
⽇本電信電話株式会社
ソフトウェアイノベーションセンタ
徳永 航平
Container Runtime Meetup #4
Copyright(c)2022 NTT Corp. All Rights Reserved. 2
名前
徳永 航平
GitHub:@ktock / Twitter:@TokunagaKohei
所属 ⽇本電信電話株式会社
興味
コンテナ、特にコンテナランタイム
containerdレビュワ、BuildKitメンテナ
Container Runtime Meetup共同運営
Copyright(c)2022 NTT Corp. All Rights Reserved. 3
⽬次
BuildKitの概要
1.
3. BuildKitの中⾝の概要
4. BuildKit v0.10からの機能と
これからのBuildKit
2. BuildKitのさまざまな機能
Copyright(c)2022 NTT Corp. All Rights Reserved. 4
BuildKitの概要
1.
⽬次
3. BuildKitの中⾝の概要
4. BuildKit v0.10からの機能と
これからのBuildKit
2. BuildKitのさまざまな機能
Copyright(c)2022 NTT Corp. All Rights Reserved. 5
BuildKitの概要
l Moby傘下のコンテナビルダプロジェクト
l `docker build`(要`DOCKER_BUILDKIT=1`)のコアコンポーネント(since 18.09)
l Dockerに限らずKubernetes上でのビルドや汎⽤のビルダフレームワークとして
も使われる
l Moby&Docker, img, OpenFaaS Cloud, container build interface,
Tekton Pipelines, The Sanic builud tool, vab, Rio, kim, PouchContainer,
Docker Buildx, Okteto Cloud, Earthly earthfiles, Gitpod, Dagger, envd
l 対応⾔語︓Dockerfile, Buildipacks, Mockerfile, Gockerfile, bldr, HLB,
Earthly, Cargo Wharf, Nix, mopy, envd, cue(Dagger)
採⽤例
https://github.com/moby/buildkit#used-by
https://github.com/moby/buildkit#exploring-llb
Copyright(c)2022 NTT Corp. All Rights Reserved. 6
BuildKitプロジェクトのあゆみ
2018 2019 2020 2021 2022
v0.3.0 v0.4.0 v0.5.0 v0.8.0 v0.10.0
(10⽉) (3⽉) (4⽉) (12⽉) (3⽉)
〜2017
[1] https://docs.docker.com/engine/release-notes/18.09/#new-features ; [2] https://docs.docker.com/engine/release-notes/19.03/#19030 ; [3] https://github.com/knative/build-templates/pull/70 ; [4]
https://github.com/tektoncd/catalog/pull/20 ; [5] https://github.com/moby/buildkit/pull/1446 ; [6] https://github.com/moby/buildkit/pull/2522 ; [7] https://github.com/moby/buildkit/pull/2615
v0.6.0
(8⽉)
v0.7.0
(3⽉)
v0.9.0
(7⽉)
11⽉ Docker Engine 18.09に採⽤[1]
3⽉ Docker EngineにBuildx plugin採⽤[2]
10⽉ Knative Build Templateに採⽤[3]
5⽉ Tektonに採⽤※[4]
4⽉ Earthlyに採⽤※ [5]
※ BuildKitプロジェクトへの報告⽇基準
12⽉ Gitpodに採⽤※ [6]
2⽉ Daggerに採⽤※ [7]
Copyright(c)2022 NTT Corp. All Rights Reserved. 7
4つの側⾯から⾒るBuildKit
dockerd
BuildKit
docker build
Docker API
buildkitd
buildctlなど
任意のツール Cluster
buildkitd
buildkitd
buildkitd
buildkitd
buildctl
buildkitd
Dockerのビルド機能
(`DOCKER_BUILDKIT=1`)
汎⽤Dockerfileビルダ
Dockerfile
任意の
ビルド記
述⾔語
Kubernetes向け
分散ビルダ
汎⽤の
ビルダ/ランタイム
フレームワーク
Dockerfile
Copyright(c)2022 NTT Corp. All Rights Reserved. 8
側⾯1︓Dockerの⼀部(docker build)
l `docker build`の実装(since 18.09)
l 環境変数`DOCKER_BUILDKIT=1`を指定することでBuildKitを有効化できる
l dockerd にBuildKitが直接統合されている
dockerd
BuildKit
docker build
Docker API
Copyright(c)2022 NTT Corp. All Rights Reserved. 9
側⾯2︓汎⽤Dockerfileビルダ
l `buildkitd`というデーモンを使ってDockerfileのビルドが可能(gRPC APIを提供)。 buildkitd
のクライアントとして動作するビルダがある
• Docker Buildx(後述) https://github.com/docker/buildx
• nerdctl: Docker互換のcontainerd CLI https://github.com/containerd/nerdctl
l buildkitが提供するライブラリを使ってbuildkitdをアプリケーションに埋め込むことも可能
• e.g. img https://github.com/genuinetools/img
• Jess Frazelle (Oxide Computer)が開発。daemonless, rootlessなイメージビルダ
img
buildkitd
docker buildx
gRPC API
nerdctl build
buildctl
gRPC API
BuildKit
CLI
Copyright(c)2022 NTT Corp. All Rights Reserved. 10
側⾯3︓Kubernetes向け分散ビルダ
l buildkitdをKubernetes上で分散稼働させることが可能
l さまざまなデプロイパターンがある
Deployment+Service StatefulSet Job
ランダムロードバランシング。
レジストリを介したキャッ
シュ共有により⾼速なビルド
が可能。
クライアント側でのロードバ
ランシング。consistent hash
を使えば効率的にローカル
キャッシュを活⽤可能。
ワンショットなビルド実⾏。
BuildKitデーモンの⻑期稼動が
不要。ローカルキャッシュは
ビルドのたびに削除。
Cluster
BuildKit
buildctl
BuildKit
BuildKit
BuildKit
Service
BuildKit
buildctl
BuildKit
BuildKit BuildKit
buildctl
+
BuildKit
kubectl
Cluster Cluster
https://github.com/moby/buildkit/tree/master/examples/kubernetes
Copyright(c)2022 NTT Corp. All Rights Reserved. 11
側⾯4︓汎⽤のビルダ/ランタイムフレームワーク
l BuildKitはLLBというビルドの中間表現をサポート
l Dockerfileのみならず様々なビルド⽤の⾔語を定義可能
l ビルドだけでなくテストなども実⾏可能なCI/CDフレームワークを提供するプロジェク
トもある(e.g. Earthly, Dagger)
BuildKit
Mockerfile Gockerfile HLB
Earthly
bldr
Nix
Cargo
Wharf
mopy envd
Dockerfile Buildpacks
…
Dagger
(cue)
https://github.com/moby/buildkit#exploring-llb
Copyright(c)2022 NTT Corp. All Rights Reserved. 12
BuildKitの概要
1.
⽬次
3. BuildKitの中⾝の概要
4. BuildKit v0.10からの機能と
これからのBuildKit
2. BuildKitのさまざまな機能
Copyright(c)2022 NTT Corp. All Rights Reserved. 13
並列マルチステージビルド
l 各ステージが並列に実⾏されることで旧`docker build`より⾼速化されている
l 旧`docker build`ではシーケンシャルな実⾏だった
stage C
FROM image AS stage-a
RUN build a
FROM image AS stage-b
RUN build b
FROM scratch
COPY --from=stage-a a /
COPY --from=stage-b b /
stage A stage B
Copyright(c)2022 NTT Corp. All Rights Reserved. 14
Dockerfileの便利構⽂
l type=bind: context中のディレクトリや他のステージなどからマウント可能
RUN --mount
l type=cache: コンパイラなどで使うキャッシュをビルド間で共有できる
l type=secret: 秘密鍵などsecretをイメージに書き込むことなく使⽤可能
l type=ssh: SSH agent経由でSSH keyにアクセスできる
RUN --mount=type=cache,target=/root/.cache/go-build go build …
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials aws s3 cp s3://… …
RUN --mount=type=ssh ssh –q –T git@gitlab.com
docker/dockerfile:1.2
https://github.com/moby/buildkit/blob/v0.10.3/frontend/dockerfile/docs/syntax.md
Copyright(c)2022 NTT Corp. All Rights Reserved. 15
Dockerfileの便利構⽂
l RUN、COPY命令の引数にエスケープ⽂字無しに複数⾏にわたる命令を書ける
l shebangやset命令が使える
heredoc
FROM ubuntu
RUN <<EOT
set -eu -o pipefail
mkdir -p /foo/bar
echo hello > /foo/bar/hello
EOT
FROM python
RUN <<EOT
#!/usr/bin/env python
print(“hello world”)
EOT
docker/dockerfile:1.4
FROM ubuntu
COPY <<EOT /foo
foo
bar
EOT
https://github.com/moby/buildkit/blob/v0.10.3/frontend/dockerfile/docs/syntax.md
Copyright(c)2022 NTT Corp. All Rights Reserved. 16
Dockerfileの便利構⽂
l キャッシュミスがしにくくなるよう最適化が施された
l --link=falseと異なり、COPY先のsymlinkが辿られないという違いに注意
COPY --link docker/dockerfile:1.4
https://github.com/moby/buildkit/blob/v0.10.3/frontend/dockerfile/docs/syntax.md
FROM ubuntu:22.04 AS dev
RUN echo foo > /foo
FROM busybox:1.34
COPY --link --from=dev /foo /
FROM ubuntu:22.04 AS dev
RUN echo foo > /foo
FROM alpine:3.16
COPY --link --from=dev /foo /
キャッシュを使いまわせる
Copyright(c)2022 NTT Corp. All Rights Reserved. 17
マルチプラットフォームイメージ
l ⼀つのイメージに複数のプラットフォーム向けのイメージを詰め込める
l ランタイムは⾃分が稼働するホストのプラットフォームに合うものを選んでpullする
l Docker Buildxでビルド可能[1]: https://medium.com/nttlabs/buildx-multiarch-2c6c2df00ca2
• QEMU使⽤︓簡単(Dockerfileに変更不要)だがパフォーマンスペナルティあり
• Dockerfile内でクロスコンパイラ等使⽤︓早い。Dockerfileに変更が必要
• ターゲットアーキテクチャのマシンを⽤意してSSH経由でビルド︓早い。マシンを別
途⽤意する必要がある
docker buildx build –t my/image –push ¥
--platfom linux/amd64,linux/arm64 .
docker run my/image
Dockerfile
amd64⽤イメージ
arm⽤イメージ
・・・
amd64マシン
armマシン
マルチプラットフォー
ム対応イメージ
pull
pull
[1] Akihiro Suda. “Preparation toward running Docker on ARM Mac: Building multi-arch images with Docker BuildX”. https://medium.com/nttlabs/buildx-multiarch-2c6c2df00ca2
Copyright(c)2022 NTT Corp. All Rights Reserved. 18
リモートキャッシュ
l ビルド結果はBuildKitを実⾏しているホスト上だけでなく、レジストリなどリモートへの
キャッシュ保持が可能
l Kubernetesでの分散ビルドやCIジョブなど、ノード間でキャッシュを共有するのに使える
l レジストリ以外にもGitHub ActionsやS3へのキャッシュ格納もexperimentalにサポート
local registry
inline
BuildKit
cache
ローカルなディレクトリ
にキャッシュ保持
キャッシュ込みのイメー
ジをレジストリにpush
BuildKit
image
+ cache
BuildKit
image cache
イメージとキャッシュを
別々にレジストリにpush
Copyright(c)2022 NTT Corp. All Rights Reserved. 19
LLB︓ビルド定義の中間表現
LLB is to Dockerfile what LLVM IR is to C.
https://github.com/moby/buildkit#exploring-llb
l LLBにさえ変換できれば、任意の⾔語で記述したビルドをBulidKitで実⾏可能
l ビルド⼿順を定義したDAGを表現するデータ構造(protocol buffers)
FROM busybox AS foo
RUN echo foo > /foo
FROM alpine AS bar
RUN echo bar > /bar
FROM scratch
COPY --from=foo /foo /
COPY --from=bar /bar /
LLB
Dockerfile
Copyright(c)2022 NTT Corp. All Rights Reserved. 20
さまざまなBuildKit対応⾔語(⼀部)
Earthly (Earthfile): https://github.com/earthly/earthly
l Earthly TechnologiesによるCI/CDフレームワーク
l MakefileとDockerfileを合わせたような記法でCI/CDのロジックが書ける
Dagger: https://github.com/dagger/dagger
l DaggerによるCI/CDフレームワーク
l cue⾔語でCI/CDロジックが書ける
buildkit-nix: https://github.com/AkihiroSuda/buildkit-nix
l Akihiro Sudaさん(mobyメンテナ, BuildKitメンテナ)が開発
l Nix derivationをDockerfileとして⽤い、イメージをビルドする
対応⾔語のリスト︓https://github.com/moby/buildkit#exploring-llb
• 2022/8/18時点で11個リストされている
• YAMLでビルドを記述するものや、RustやPythonなど特定⾔語のアプリケーションのビル
ドに使えるものなどいろいろある
Copyright(c)2022 NTT Corp. All Rights Reserved. 21
BuildKitの概要
1.
⽬次
3. BuildKitの中⾝の概要
4. BuildKit v0.10からの機能と
これからのBuildKit
2. BuildKitのさまざまな機能
Copyright(c)2022 NTT Corp. All Rights Reserved. 22
BuildKitの構成︓クライアントサーバ
l ⼤局的に⾒ればクライアント・サーバ
• クライアントライブラリが提供されている
• サーバ側はbuildkitdというデーモンプロセス
l サーバはクライアントにgRPC API提供
• ビルド、ビルド結果の出⼒、キャッシュ操作、個
別コンテナ実⾏などが可能
l クライアントとサーバは同⼀ホスト上でなくてもいい
クライアント
サーバ
(buildkitd)
gRPC API
Copyright(c)2022 NTT Corp. All Rights Reserved.
クライアント
23
BuildKitクライアント
l クライアントライブラリを使いサーバにビルドを指⽰
• ビルド定義⾔語の設定
• ビルド結果出⼒先の指定
• キャッシュのインポート・エクスポート先
l BuildKitのAPIは双⽅向
• clientもソースファイル・ビルドコンテキスト・レ
ジストリ認証情報などを提供するgRPC APIを持つ
• buildkitdはビルド中必要に応じてクライアントにそ
れらをリクエスト
サーバ
(buildkitd)
gRPC API経由で
ビルド指⽰
gRPC
client
コンテキストや
credsを都度要求
セッショ
ンサーバ
Copyright(c)2022 NTT Corp. All Rights Reserved. 24
BuildKitクライアントツールの例
l buildctl https://github.com/moby/buildkit
• BuildKitプロジェクトで開発されるCLI
• ビルドやキャッシュ管理などBuildKit APIに⾁薄するひ
ととおりの機能が使える
l Docker Buildx https://github.com/docker/buildx
• Dockerによって開発されるBuildKit向けビルダCLI
• `docker build`にはないBuildKitの機能(リモートキャッ
シュ、multi-platform、Kubernetesでの分散ビルド, etc)
が利⽤可能
サーバ
(buildkitd)
クライアント
gRPC client・session
Copyright(c)2022 NTT Corp. All Rights Reserved. 25
BuildKitサーバ
l ビルドに関するほとんどのことが⾏われる
• ビルド定義のパース
• ビルド、キャッシュ
• ビルド結果のエクスポート, etc…
l gRPC経由で操作⽤のControl APIを公開
• ローカルのunixソケット経由
• リモートのクライアントへの公開も可能
l ビルド定義⾔語をLLBに変換するコンポーネントがプラ
ガブル
• BuildKitにパッチを当てることなく任意の⾔語のサ
ポートが可能
クライアント
サーバ
(buildkitd)
gRPC API
Copyright(c)2022 NTT Corp. All Rights Reserved. 26
BuildKitサーバを構成する主要なコンポーネント
l frontend
• ソース⾔語のパースやLLBへの変換
• プラグインとして拡張可能
l solver
• LLBを実⾏する
• 並列実⾏やキャッシュの利⽤によりビルドを⾼速化
l worker
• コンテナやキャッシュ、snapshot、レイヤコンテンツ、
ビルド結果のエクスポートなどを管理
• runcベースの実装とcontainerdベースの実装がある
• CNI pluginも利⽤可能
クライアント
gRPC API
frontend
solver
worker
サーバ(buildkitd)
Copyright(c)2022 NTT Corp. All Rights Reserved. 27
BuildKit frontendによる任意のビルド⾔語の定義
l ソース⾔語をLLBに変換するコンポーネント
l コンテナとして実装し、BuildKitにプラグイン可能
l フロントエンドコンテナにはstdioを通じてGateway APIと
よばれるgRPC APIが提供される
• このAPI経由でビルドコンテキストを取得
• LLBを作成しその実⾏をこのAPI経由でBuildKitに指⽰
クライアント
gRPC API
frontend
Gateway API提供
(stdio経由)
l Gateway APIはクライアント向けAPIとしても提供される
l クライアントから⾒ると、buildkitd操作⽤API(Control
API)とGateway APIの2つが⾒える
l クライアントにフロントエンド的機能を実装可能
補⾜
サーバ(buildkitd)
コンテナ
Copyright(c)2022 NTT Corp. All Rights Reserved. 28
2種類のフロントエンド
gateway.v0
• コンテナ化された任意のフロントエンドを実⾏
dockerfile.v0
• Dockerfileフロントエンド実装
• BuildKitにビルトインされている
• 構⽂で指定されたフロントエンドをgateway.v0経由で実⾏可能
# syntax=docker/dockerfile:1
• 任意バージョンのdockerfile⽤フロントエンドを使⽤可能。
• BuildKit本体のアップグレードなしにフロントエンドだけ更新できる
• e.g. 最新のDockerfile構⽂を試したり、バグ修正を受け取ったり
# syntax=ghcr.io/akihirosuda/buildkit-nix:v0.0.2
※ イメージ名にダイジェストまで指定することでバージョンの固定もできる
• Nix derivationをDockerfileとして使える
例
# syntax=イメージ名
Copyright(c)2022 NTT Corp. All Rights Reserved. 29
BuildKitの概要
1.
⽬次
3. BuildKitの中⾝の概要
4. BuildKit v0.10からの機能と
これからのBuildKit
2. BuildKitのさまざまな機能
Copyright(c)2022 NTT Corp. All Rights Reserved. 30
BuildKit v0.10/dockerfile v1.4の主な機能
l MergeOpとDiffOp (`COPY --link`命令のサポート)
• MergeOp: 複数の独⽴のファイルシステムをマージする
• キャッシュミスがしにくくなるよう最適化が施された`COPY --link`命令に使われる
• DiffOp: 2つのファイルシステムの差分を求める
l eStargzイメージの作成
• eStargz: イメージの⾼速pull(lazy pulling)を可能にするイメージフォーマット
• イメージのpull完了を待たずにコンテナ起動が可能
• ベースイメージやremote cacheをeStargzにフォーマット可能
• FROM命令のpull完了を待たずに後続のRUN命令などを実⾏可能
$ docker buildx build ¥
-o type=registry,name=ktokunaga/hello:esgz,oci-mediatypes=true,compression=estargz .
Copyright(c)2022 NTT Corp. All Rights Reserved. 31
BuildKit v0.10/dockerfile v1.4の主な機能
l イメージレイヤの圧縮フォーマットとしてzstdがサポート
• Zstandard/zstd: facebookが提案する⾼速な圧縮フォーマット
• https://github.com/facebook/zstd
• OCI Image Specificationでもzstdがイメージレイヤとして定義されている(未リリース)
• https://github.com/opencontainers/image-spec/pull/788
• containerd(>=1.5.0)やPodmanなどのランタイムでもzstdの実⾏がサポートされている
• Dockerにもv22.06でサポートが⼊る予定: https://github.com/moby/moby/pull/41759
Copyright(c)2022 NTT Corp. All Rights Reserved. 32
これからのBuildKitに向けた議論
l FROMのイメージやADDにおけるgit repositoryのバージョンを固定する機能(pinning)
• https://github.com/moby/buildkit/pull/2943
• https://github.com/moby/buildkit/issues/2794
l イメージのレイヤにセットされるtimestampの固定
• https://github.com/moby/buildkit/pull/2918
l Dockerfileのコメントから直接Usageドキュメントを作成する機能
• https://github.com/moby/buildkit/pull/2841
l SBoM⽣成のサポート
• https://github.com/moby/buildkit/issues/2773
Copyright(c)2022 NTT Corp. All Rights Reserved. 33
これからのBuildKitに向けた議論
l Dockerfile⽤の対話的デバッガ https://github.com/ktock/buildg
• breakpointや命令ごとに実際にコンテナを⽴ち上げて中⾝を⾒たりできる
• gdb⾵の対話的CLIや、IDE(VS Code, Neovim, Emacs, …)上のGUIも使える
• 将来的にはbuildxにも統合されるはず
• https://github.com/docker/buildx/issues/1104
Copyright(c)2022 NTT Corp. All Rights Reserved. 34
まとめ
BuildKitの4つの側⾯
機能
仕組み
最近とこれからのBuildKit
• docker build(要`DOCKER_BUILDKIT=1`)
• 汎⽤Dockerfileビルダ
• Kubernetesでのビルド
• 任意のビルド記述⾔語サポート
• 並列マルチステージビルド
• RUN –mountやCOPY –link、heredocなどDockerfile便利構⽂
• マルチプラットフォームイメージのビルド
• リモートキャッシュ
• 任意のビルド定義⾔語の利⽤
• クライアントサーバ
• 任意のfrontendをコンテナとしてプラグイン可能
• MergeOp/DiffOp, eStargz, zstdなど
• サプライチェーンやDockerfileドキュメント⽣成、デバッガなどの議論がある
• Repo: https://github.com/moby/buildkit
• Slack: #buildkit on Docker Community Slack