Copyright©2018 NTT Corp. All Rights Reserved.
NTT ソフトウェアイノベーションセンタ
須田 瑛大
BuildKitによる
高速でセキュアなイメージビルド
Container SIG (2018/10/24)
https://slideshare.net/AkihiroSuda
2
Copyright©2018 NTT Corp. All Rights Reserved.
• コンテナ関連OSSのメンテナ(いわゆるコミッタ)を務めている
• Docker Moby メンテナ (2016年11月~)
• 2017年4月,OSSプロジェクトとしてのDockerはMobyに名前が変わった
• 商用製品としてのDockerはMobyをベースとして開発されている
• Moby BuildKitメンテナ (2017年夏 プロジェクト発足時~)
• 次世代 `docker build`
• CNCF containerdメンテナ (2017年9月~)
• Kubernetesなどで利用できる次世代コンテナランタイム
: ≒ :
RHEL Fedora
自己紹介
3
Copyright©2018 NTT Corp. All Rights Reserved.
• Dockerfileのキャッシュが効きにくい
• DockerfileのN行目を書き換えると,N+1行目以降のキャッシュは破棄される
• ユーザはDockerfileの命令の順序に気をつける必要がある
• コンパイラやパッケージマネージャのキャッシュが保存されない
• ~/.m2 (Maven), ~/.cache/go-build (Go), /var/cache/apt (apt) など
• ビルドコンテキストの転送に時間がかかる
• ソースを1行編集しただけでも,ソース全体をtar ballとしてデーモンに送信する必要
がある
従来の`docker build`に対する不満: パフォーマンス
FROM debian
EXPOSE 80
RUN apt update && apt install –y HEAVY-PACKAGES
EXPOSEを書き換えるだけでRUNのキャッシュが効かなくなる
4
Copyright©2018 NTT Corp. All Rights Reserved.
• 並列実行できるはずの命令を,並列実行してくれない
従来の`docker build`に対する不満: パフォーマンス
FROM golang AS stage0
...
RUN go build –o /foo ...
FROM clang AS stage1
...
RUN clang –o /bar ...
FROM debian AS stage2
COPY --from=stage0 /foo /usr/local/bin/foo
COPY --from=stage1 /bar /usr/local/bin/bar
0
2
1
各ステージの依存性は
DAGとして表現できる
5
Copyright©2018 NTT Corp. All Rights Reserved.
• 並列実行できるはずの命令を,並列実行してくれない
従来の`docker build`に対する不満: パフォーマンス
FROM golang AS stage0
...
RUN go build –o /foo ...
FROM clang AS stage1
...
RUN clang –o /bar ...
FROM debian AS stage2
COPY --from=stage0 /foo /usr/local/bin/foo
COPY --from=stage1 /bar /usr/local/bin/bar
0
2
1
0
1
2
シーケンシャルにしか
実行してくれない
6
Copyright©2018 NTT Corp. All Rights Reserved.
• プライベートなGitやS3などへのアクセスが困難
• `COPY`命令で鍵を置くのは危ない
• ステージを分けるか `--squash` しないと鍵が漏れる
• 環境変数を使うのも危ない
従来の`docker build`に対する不満: セキュリティ
FROM ...
COPY id_rsa ~/.ssh
RUN git clone ssh://...
RUN rm –f ~/.ssh/id_rsa
rmしてもレイヤの
tarからは消えない
7
Copyright©2018 NTT Corp. All Rights Reserved.
• DAG構造を備える中間言語であるLLBを用いる
• Protocol Buffers形式
• 依存性を正確に表現できるので,キャッシュがよく効く
• 命令を並列実行できる
• LLBは主にDockerfileからコンパイルされる
• Dockerfile以外の言語からのコンパイルも可能 (Heroku, CFのBuildpacksなど)
• 他にも,コンテキストの差分転送などの最適化有り
BuildKit: 次世代 `docker build`
コンパイル
Dockerfile
LLB DAG
Buildpacksなど
docker-image://alpine
Image
git://foo/bar
docker-image://gcc
Run("apk add ..")Run("make")
3命令を同時に実行できる
2
8
Copyright©2018 NTT Corp. All Rights Reserved.
• DAG構造はマルチステージDockerfileを用いて簡単に記述できる
BuildKit: 次世代 `docker build`
FROM golang AS stage0
...
RUN go build –o /foo ...
FROM clang AS stage1
...
RUN clang –o /bar ...
FROM debian AS stage2
COPY --from=stage0 /foo /usr/local/bin/foo
COPY --from=stage1 /bar /usr/local/bin/bar
0
2
1
9
Copyright©2018 NTT Corp. All Rights Reserved.
• Docker v18.06以降には,BuildKitが組み込まれている
• コマンドラインは従来の `docker build` と同じ
• クライアント側で `export DOCKER_BUILDKIT=1` すると有効になる
• Docker v18.06では,加えて Docker daemonをexperimentalモードで起動する必要
がある (Docker v18.09以降では不要)
BuildKitの使い方
v18.09は10月中にはリリースされるはず..
10
Copyright©2018 NTT Corp. All Rights Reserved.
• DAGはマルチステージDockerfileを用いて記述できる
BuildKit: 次世代 `docker build`
FROM golang AS stage0
...
RUN go build –o /foo ...
FROM clang AS stage1
...
RUN clang –o /bar ...
FROM debian AS stage2
COPY --from=stage0 /foo /usr/local/bin/foo
COPY --from=stage1 /bar /usr/local/bin/bar
0
2
1
https://t.co/aUKqQCVmXa より引用
11
Copyright©2018 NTT Corp. All Rights Reserved.
https://t.co/aUKqQCVmXa より引用
12
Copyright©2018 NTT Corp. All Rights Reserved.
https://t.co/aUKqQCVmXa より引用
13
Copyright©2018 NTT Corp. All Rights Reserved.
https://t.co/aUKqQCVmXa より引用
14
Copyright©2018 NTT Corp. All Rights Reserved.
• Dockerfileの最初の行に `# syntax = ${FRONTEND_IMAGE}` を指定する
と,非標準の命令を利用できる
• `${FRONTEND_IMAGE}` には,DockerfileをLLBに変換するプログラムを含んだコンテ
ナイメージを指定する (つまり,新しい命令や構文を自作できる!)
• 例: `RUN –-mount=type=cache`
• コンパイラやパッケージマネージャのキャッシュディレクトリを保持できる
• 将来的には,`# syntax = ...` を指定しなくても標準で利用できるようになるものと
思われる
新しいDockerfile構文: `RUN –-mount=type=cache`
# syntax = tonistiigi/dockerfile:runmount20181002
...
RUN --mount=type=cache,target=/root/.cache go build ...
https://github.com/moby/buildkit/pull/442 https://github.com/moby/buildkit/pull/455
15
Copyright©2018 NTT Corp. All Rights Reserved.
https://t.co/aUKqQCVmXa より引用
Docker v18.03比で30倍以上高速!
16
Copyright©2018 NTT Corp. All Rights Reserved.
• S3やSSHの鍵を,`RUN`コンテナ内に安全にマウントできる
• マウントされるだけなので,出力イメージ内には残らない
• Docker v18.09から利用可能
新しいDockerfile構文: `RUN –-mount=type=secret`
# syntax = tonistiigi/dockerfile:secrets20181002
...
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials 
aws s3 cp s3://... ...
$ docker build –-secret id=aws,src=~/.aws/credentials ...
https://github.com/moby/buildkit/pull/567
17
Copyright©2018 NTT Corp. All Rights Reserved.
• Heroku・Cloud FoundryのBuildpacksも,`docker build`から直接ビ
ルドできる
• やはりLLBに変換されて実行される
Dockerfile以外の言語
# syntax = tonistiigi/pack
---
applications:
- name: myapp
memory: 128MB
disk_quota: 256MB
random-route: true
buildpack: python_buildpack
command: python hello.py
$ docker build –f manifest.yml ...
https://github.com/tonistiigi/buildkit-pack
18
Copyright©2018 NTT Corp. All Rights Reserved.
• Dockerfileの各ステージを並列実行できる
• コンパイラやパッケージマネージャのキャッシュを使える
• AWSやSSHなどの鍵を安全に扱える
• Dockerfile以外の言語も使える (Buildpacksなど)
• 最新のDockerなら,`export DOCKER_BUILDKIT=1`するだけですぐに使える
まとめ
従来より30倍以上
速くなることも

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

  • 1.
    Copyright©2018 NTT Corp.All Rights Reserved. NTT ソフトウェアイノベーションセンタ 須田 瑛大 BuildKitによる 高速でセキュアなイメージビルド Container SIG (2018/10/24) https://slideshare.net/AkihiroSuda
  • 2.
    2 Copyright©2018 NTT Corp.All Rights Reserved. • コンテナ関連OSSのメンテナ(いわゆるコミッタ)を務めている • Docker Moby メンテナ (2016年11月~) • 2017年4月,OSSプロジェクトとしてのDockerはMobyに名前が変わった • 商用製品としてのDockerはMobyをベースとして開発されている • Moby BuildKitメンテナ (2017年夏 プロジェクト発足時~) • 次世代 `docker build` • CNCF containerdメンテナ (2017年9月~) • Kubernetesなどで利用できる次世代コンテナランタイム : ≒ : RHEL Fedora 自己紹介
  • 3.
    3 Copyright©2018 NTT Corp.All Rights Reserved. • Dockerfileのキャッシュが効きにくい • DockerfileのN行目を書き換えると,N+1行目以降のキャッシュは破棄される • ユーザはDockerfileの命令の順序に気をつける必要がある • コンパイラやパッケージマネージャのキャッシュが保存されない • ~/.m2 (Maven), ~/.cache/go-build (Go), /var/cache/apt (apt) など • ビルドコンテキストの転送に時間がかかる • ソースを1行編集しただけでも,ソース全体をtar ballとしてデーモンに送信する必要 がある 従来の`docker build`に対する不満: パフォーマンス FROM debian EXPOSE 80 RUN apt update && apt install –y HEAVY-PACKAGES EXPOSEを書き換えるだけでRUNのキャッシュが効かなくなる
  • 4.
    4 Copyright©2018 NTT Corp.All Rights Reserved. • 並列実行できるはずの命令を,並列実行してくれない 従来の`docker build`に対する不満: パフォーマンス FROM golang AS stage0 ... RUN go build –o /foo ... FROM clang AS stage1 ... RUN clang –o /bar ... FROM debian AS stage2 COPY --from=stage0 /foo /usr/local/bin/foo COPY --from=stage1 /bar /usr/local/bin/bar 0 2 1 各ステージの依存性は DAGとして表現できる
  • 5.
    5 Copyright©2018 NTT Corp.All Rights Reserved. • 並列実行できるはずの命令を,並列実行してくれない 従来の`docker build`に対する不満: パフォーマンス FROM golang AS stage0 ... RUN go build –o /foo ... FROM clang AS stage1 ... RUN clang –o /bar ... FROM debian AS stage2 COPY --from=stage0 /foo /usr/local/bin/foo COPY --from=stage1 /bar /usr/local/bin/bar 0 2 1 0 1 2 シーケンシャルにしか 実行してくれない
  • 6.
    6 Copyright©2018 NTT Corp.All Rights Reserved. • プライベートなGitやS3などへのアクセスが困難 • `COPY`命令で鍵を置くのは危ない • ステージを分けるか `--squash` しないと鍵が漏れる • 環境変数を使うのも危ない 従来の`docker build`に対する不満: セキュリティ FROM ... COPY id_rsa ~/.ssh RUN git clone ssh://... RUN rm –f ~/.ssh/id_rsa rmしてもレイヤの tarからは消えない
  • 7.
    7 Copyright©2018 NTT Corp.All Rights Reserved. • DAG構造を備える中間言語であるLLBを用いる • Protocol Buffers形式 • 依存性を正確に表現できるので,キャッシュがよく効く • 命令を並列実行できる • LLBは主にDockerfileからコンパイルされる • Dockerfile以外の言語からのコンパイルも可能 (Heroku, CFのBuildpacksなど) • 他にも,コンテキストの差分転送などの最適化有り BuildKit: 次世代 `docker build` コンパイル Dockerfile LLB DAG Buildpacksなど docker-image://alpine Image git://foo/bar docker-image://gcc Run("apk add ..")Run("make") 3命令を同時に実行できる 2
  • 8.
    8 Copyright©2018 NTT Corp.All Rights Reserved. • DAG構造はマルチステージDockerfileを用いて簡単に記述できる BuildKit: 次世代 `docker build` FROM golang AS stage0 ... RUN go build –o /foo ... FROM clang AS stage1 ... RUN clang –o /bar ... FROM debian AS stage2 COPY --from=stage0 /foo /usr/local/bin/foo COPY --from=stage1 /bar /usr/local/bin/bar 0 2 1
  • 9.
    9 Copyright©2018 NTT Corp.All Rights Reserved. • Docker v18.06以降には,BuildKitが組み込まれている • コマンドラインは従来の `docker build` と同じ • クライアント側で `export DOCKER_BUILDKIT=1` すると有効になる • Docker v18.06では,加えて Docker daemonをexperimentalモードで起動する必要 がある (Docker v18.09以降では不要) BuildKitの使い方 v18.09は10月中にはリリースされるはず..
  • 10.
    10 Copyright©2018 NTT Corp.All Rights Reserved. • DAGはマルチステージDockerfileを用いて記述できる BuildKit: 次世代 `docker build` FROM golang AS stage0 ... RUN go build –o /foo ... FROM clang AS stage1 ... RUN clang –o /bar ... FROM debian AS stage2 COPY --from=stage0 /foo /usr/local/bin/foo COPY --from=stage1 /bar /usr/local/bin/bar 0 2 1 https://t.co/aUKqQCVmXa より引用
  • 11.
    11 Copyright©2018 NTT Corp.All Rights Reserved. https://t.co/aUKqQCVmXa より引用
  • 12.
    12 Copyright©2018 NTT Corp.All Rights Reserved. https://t.co/aUKqQCVmXa より引用
  • 13.
    13 Copyright©2018 NTT Corp.All Rights Reserved. https://t.co/aUKqQCVmXa より引用
  • 14.
    14 Copyright©2018 NTT Corp.All Rights Reserved. • Dockerfileの最初の行に `# syntax = ${FRONTEND_IMAGE}` を指定する と,非標準の命令を利用できる • `${FRONTEND_IMAGE}` には,DockerfileをLLBに変換するプログラムを含んだコンテ ナイメージを指定する (つまり,新しい命令や構文を自作できる!) • 例: `RUN –-mount=type=cache` • コンパイラやパッケージマネージャのキャッシュディレクトリを保持できる • 将来的には,`# syntax = ...` を指定しなくても標準で利用できるようになるものと 思われる 新しいDockerfile構文: `RUN –-mount=type=cache` # syntax = tonistiigi/dockerfile:runmount20181002 ... RUN --mount=type=cache,target=/root/.cache go build ... https://github.com/moby/buildkit/pull/442 https://github.com/moby/buildkit/pull/455
  • 15.
    15 Copyright©2018 NTT Corp.All Rights Reserved. https://t.co/aUKqQCVmXa より引用 Docker v18.03比で30倍以上高速!
  • 16.
    16 Copyright©2018 NTT Corp.All Rights Reserved. • S3やSSHの鍵を,`RUN`コンテナ内に安全にマウントできる • マウントされるだけなので,出力イメージ内には残らない • Docker v18.09から利用可能 新しいDockerfile構文: `RUN –-mount=type=secret` # syntax = tonistiigi/dockerfile:secrets20181002 ... RUN --mount=type=secret,id=aws,target=/root/.aws/credentials aws s3 cp s3://... ... $ docker build –-secret id=aws,src=~/.aws/credentials ... https://github.com/moby/buildkit/pull/567
  • 17.
    17 Copyright©2018 NTT Corp.All Rights Reserved. • Heroku・Cloud FoundryのBuildpacksも,`docker build`から直接ビ ルドできる • やはりLLBに変換されて実行される Dockerfile以外の言語 # syntax = tonistiigi/pack --- applications: - name: myapp memory: 128MB disk_quota: 256MB random-route: true buildpack: python_buildpack command: python hello.py $ docker build –f manifest.yml ... https://github.com/tonistiigi/buildkit-pack
  • 18.
    18 Copyright©2018 NTT Corp.All Rights Reserved. • Dockerfileの各ステージを並列実行できる • コンパイラやパッケージマネージャのキャッシュを使える • AWSやSSHなどの鍵を安全に扱える • Dockerfile以外の言語も使える (Buildpacksなど) • 最新のDockerなら,`export DOCKER_BUILDKIT=1`するだけですぐに使える まとめ 従来より30倍以上 速くなることも

Editor's Notes

  • #2 https://containersig.connpass.com/event/101214/ 5分