こんにちは、XI本部クラウドイノベーションセンターの柴田です。
本記事では Cloud Native Buildpacks の主要なBuilderの調査を行います。
Cloud Native Buildpacksとは
Cloud Native Buildpacks は、HerokuとPivotalによってCNCFのincubating projectの1つとして2018年に発足しました。Herokuが開発していたBuildpacksというツールをベースにしています。
Cloud Native Buildpacksは簡単に言うと「Dockerfileを書かずにコンテナイメージを生成してくれるツール」です。アプリケーションの構成(プログラミング言語やビルドツールなど)を自動的に検知し、それに適したビルドプロセスを自動的に選択して、アプリケーションのコンテナイメージをビルドします。これにより、アプリケーション開発者がDockerfileのベストプラクティスを学習したり、Dockerfileを実際に記述したりする必要がなくなります。
Cloud Native Buildpacksの主要な要素にはBuildpack、Stack、Builderの3つがあります。
- Buildpack :特定の構成(プログラミング言語やビルドツールなど)のアプリケーションに対するビルドプロセスです。具体的には Detect と Build という2つのプロセスから構成されます。
- Detect :ビルド対象のアプリケーションがBuildpackの対象構成に該当するか判定するロジックです。
- Build :Detectが該当すると判定した場合、実際にアプリケーションのコンテナイメージをビルドするプロセスです。
- Stack :Buildpackが使用するコンテナイメージです。マルチステージビルドを前提としており、 Build image と Run image という2つのイメージから構成されます。
- Build image :アプリケーションのビルドに使用するコンテナイメージです。
- Run image :アプリケーションの実行に使用するコンテナイメージです。
- Builder :「Stack」と「Buildpackの集合」の組み合わせです。
主要なBuilderの紹介3
Cloud Native Buildpacksは、コンテナイメージをビルドするための仕組みや、そのためのツールを提供します。一方で、実際にコンテナイメージのビルドを行うBuilderの実装は、Cloud Native Buildpacksから提供されていません。代わりにGoogleやHerokuなど3rd partyが実装したものを使用します。
pack builder suggest
コマンドを実行すると、推奨されているBuilderを確認できます。なお pack
はCloud Native Buildpacksによって提供されるCLIツールです。
Builder | 開発者 | 説明 |
---|---|---|
gcr.io/buildpacks/builder:v1 |
Ubuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Python | |
heroku/buildpacks:18 |
Heroku | Base builder for Heroku-18 stack, based on ubuntu:18.04 base image |
heroku/buildpacks:20 |
Heroku | Base builder for Heroku-20 stack, based on ubuntu:20.04 base image |
paketobuildpacks/builder:base |
Paketo Buildpacks | Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, Ruby, NGINX and Procfile |
paketobuildpacks/builder:full |
Paketo Buildpacks | Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, PHP, Ruby, Apache HTTPD, NGINX and Procfile |
paketobuildpacks/builder:tiny |
Paketo Buildpacks | Tiny base image (bionic build image, distroless-like run image) with buildpacks for Java, Java Native Image and Go |
それぞれ詳細を見ていきましょう。
gcr.io/buildpacks/builder
概要
Googleが開発しているBuilderです。
Builder | 開発者 | 説明 |
---|---|---|
gcr.io/buildpacks/builder:v1 |
Ubuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Python |
GitHubリポジトリ
Builder、Stack、Buildpackはすべて以下のGitHubリポジトリで管理されています。
Stack
Build imageとRun imageの概要は以下のとおりです。
Build image
gcr.io/buildpacks/builder:v1 |
|
---|---|
イメージ | gcr.io/buildpacks/gcp/build:v1 |
Dockerfile | build.Dockerfile |
ベースイメージ1 | gcr.io/gcp-runtimes/ubuntu_18_0_4 |
パッケージリスト | parent.Dockerfile#L24-L31 + build.Dockerfile#L24-L37 |
パッケージ数1 | 190 |
イメージサイズ | 482MB |
Run image
gcr.io/buildpacks/builder:v1 |
|
---|---|
イメージ | gcr.io/buildpacks/gcp/run:v1 |
Dockerfile | run.Dockerfile |
ベースイメージ | gcr.io/gcp-runtimes/ubuntu_18_0_4 |
パッケージリスト | parent.Dockerfile#L24-L31 |
パッケージ数 | 123 |
イメージサイズ | 120MB |
Buildpack
プログラミング言語やビルドツールのサポートは以下のとおりです。
gcr.io/buildpacks/builder:v1 |
|
---|---|
C++ | o |
.NET | o |
Java | o (AdoptOpenJDK + Maven/Gradle または GraalVM + Maven) |
Go | o |
Node.js | o (npm/Yarn) |
Python | o |
Ruby | x |
PHP | x |
heroku/buildpacks
概要
Heroku社が開発しているBuilderです。
Builder | 開発者 | 説明 |
---|---|---|
heroku/buildpacks:18 |
Heroku | Base builder for Heroku-18 stack, based on ubuntu:18.04 base image |
heroku/buildpacks:20 |
Heroku | Base builder for Heroku-20 stack, based on ubuntu:20.04 base image |
GitHubリポジトリ
Builder、Stack、Buildpackはそれぞれ以下のGitHubリポジトリで管理されています。
heroku/buildpacks:18 |
heroku/buildpacks:20 |
|
---|---|---|
Builder | https://github.com/heroku/pack-images | 同左 |
Stack | https://github.com/heroku/pack-images https://github.com/heroku/stack-images |
同左 |
Buildpack | https://github.com/heroku 配下の各リポジトリ | 同左 |
Stack
Build imageとRun imageの概要は以下のとおりです。
Build image
heroku/buildpacks:18 |
heroku/buildpacks:20 |
|
---|---|---|
イメージ | heroku/pack:18-build |
heroku/pack:20-build |
Dockerfile | Dockerfile.build | 同左 |
ベースイメージ | ubuntu:18.04 |
ubuntu:20.04 |
パッケージリスト | installed-packages.txt | installed-packages.txt |
パッケージ数 | 578 | 590 |
イメージサイズ | 1.19GB | 1.35GB |
Run image
heroku/buildpacks:18 |
heroku/buildpacks:20 |
|
---|---|---|
イメージ | heroku/pack:18 |
heroku/pack:20 |
Dockerfile | Dockerfile.run | 同左 |
ベースイメージ | ubuntu:18.04 |
ubuntu:20.04 |
パッケージリスト | installed-packages.txt | installed-packages.txt |
パッケージ数 | 354 | 354 |
イメージサイズ | 510MB | 566MB |
Buildpack
プログラミング言語やビルドツールのサポートは以下のとおりです。
heroku/buildpacks:18 |
heroku/buildpacks:20 |
|
---|---|---|
C++ | x | x |
.NET | x | x |
Java | o (OpenJDK + Maven/Gradle) | o (OpenJDK + Maven/Gradle) |
Go | o | o |
Node.js | o (npm/Yarn) | o (npm/Yarn) |
Python | o | o |
Ruby | o | o |
PHP | o | o |
paketobuildpacks/builder
概要
Paketo Buildpacks はBuildpackを開発するCloud FoundryのOSSプロジェクトの1つです。
以下はPaketo Buildpacksが開発しているBuilderです。
Builder | 開発者 | 説明 |
---|---|---|
paketobuildpacks/builder:base |
Paketo Buildpacks | Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, Ruby, NGINX and Procfile |
paketobuildpacks/builder:full |
Paketo Buildpacks | Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, PHP, Ruby, Apache HTTPD, NGINX and Procfile |
paketobuildpacks/builder:tiny |
Paketo Buildpacks | Tiny base image (bionic build image, distroless-like run image) with buildpacks for Java, Java Native Image and Go |
https://github.com/paketo-buildpacks/stacks をみると各BuilderのユースケースとStackについて以下のように書かれています。
Base (aka "bionic")
Ideal for: - .NET Core apps - Java apps and Go apps that require some C libraries - Node.js/Python/Ruby/etc. apps without many native extensions
Contains: - Build: ubuntu:bionic + openssl + CA certs + compilers + shell utilities - Run: ubuntu:bionic + openssl + CA certs
Full
Ideal for: - PHP/Node.js/Python/Ruby/etc. apps with many native extensions
Contains: - Build: ubuntu:bionic + many common C libraries and utilities - Run: ubuntu:bionic + many common libraries and utilities
Tiny
Ideal for: - Most Go apps - Java apps and Java GraalVM Native Images
Contains: - Build: ubuntu:bionic + openssl + CA certs + compilers + shell utilities - Run: distroless-like bionic + glibc + openssl + CA certs
GitHubリポジトリ
Builder、Stack、Buildpackはそれぞれ以下のGitHubリポジトリで管理されています。
paketobuildpacks/builder:base |
paketobuildpacks/builder:full |
paketobuildpacks/builder:tiny |
|
---|---|---|---|
Builder | https://github.com/paketo-buildpacks/base-builder | https://github.com/paketo-buildpacks/full-builder | https://github.com/paketo-buildpacks/tiny-builder |
Stack | https://github.com/paketo-buildpacks/stacks | 同左 | 同左 |
Buildpack | https://github.com/paketo-buildpacks 配下の各リポジトリ | 同左 | 同左 |
Stack
Build imageとRun imageの概要は以下のとおりです。
Build image
paketobuildpacks/builder:base |
paketobuildpacks/builder:full |
paketobuildpacks/builder:tiny |
|
---|---|---|---|
イメージ | paketobuildpacks/build:base-cnb |
paketobuildpacks/build:full-cnb |
paketobuildpacks/build:tiny-cnb ( base-cnb と同じ) |
Dockerfile | Dockerfile | 同左 | ( base-cnb と同じ) |
ベースイメージ | ubuntu:bionic |
同左 | ( base-cnb と同じ) |
パッケージリスト | build | build | ( base-cnb と同じ) |
パッケージ数 | 172 | 703 | ( base-cnb と同じ) |
イメージサイズ | 327MB | 1.02GB | ( base-cnb と同じ) |
Run image
paketobuildpacks/builder:base |
paketobuildpacks/builder:full |
paketobuildpacks/builder:tiny |
|
---|---|---|---|
イメージ | paketobuildpacks/run:base-cnb |
paketobuildpacks/run:full-cnb |
paketobuildpacks/run:tiny-cnb |
Dockerfile | Dockerfile | 同左 | Dockerfile |
ベースイメージ | ubuntu:bionic |
同左 | scratch |
パッケージリスト | run | run | packagelist |
パッケージ数 | 96 | 586 | 不明1 |
イメージサイズ | 88.9MB | 691MB | 17.4MB |
Buildpack
プログラミング言語やビルドツールのサポートは以下のとおりです。
nginxやHTTPDのコンテナイメージのビルドにも対応している点が特徴的ですね。
paketobuildpacks/builder:base |
paketobuildpacks/builder:full |
paketobuildpacks/builder:tiny |
|
---|---|---|---|
C++ | x | x | x |
.NET | o | o | x |
Java | o (Liberica JDK + Maven/Gradle) | o (Liberica JDK + Maven/Gradle) | o (Liberica JDK + Maven/Gradle) |
Go | o | o | o |
Node.js | o (npm/Yarn) | o (npm/Yarn) | x |
Python | o | o | x |
Ruby | o | o | x |
PHP | x | o | x |
nginx | o | o | x |
HTTPD | x | o | x |
各Builderを評価する
ここからは、前述した主要なBuilderをいくつかの観点で評価します。
なぜBuilderを評価するのか
前述したように、実際にコンテナイメージのビルドを行うのは、GoogleやHerokuなど3rd partyが実装したBuilderです。Builderによってビルドプロセスやベースとなるコンテナイメージに差異があるため、生成されるコンテナイメージの品質は使用したBuilderやBuildpackに大きく依存します。
よって本記事では、より品質の高いコンテナイメージを生成するために、前述した主要なBuilderの評価を行います。
評価の観点
以下の観点で各Builderを評価します。
なお、attack surfaceとは、攻撃を試みることができる対象範囲のことです。例えば、アプリケーションに不必要なパッケージやファイルがコンテナイメージに含まれていると、それらに脆弱性があった場合、攻撃されるリスクが高まります。そのため、コンテナイメージには必要なパッケージやファイルのみを含めるべきです。
プログラミング言語やビルドツールへの対応状況
Builderは自分たちが使用するプログラミング言語やビルドツールに対応しているものを選ぶ必要があります。
各Builderのプログラミング言語やビルドツールへの対応状況を改めてまとめます。
C++ | .NET | Java | Go | Node.js | Python | Ruby | PHP | nginx | HTTPD | |
---|---|---|---|---|---|---|---|---|---|---|
gcr.io/buildpacks/builder:v1 |
o | o | o (AdoptOpenJDK + Maven/Gradle または GraalVM + Maven) | o | o (npm/Yarn) | o | x | x | x | x |
heroku/buildpacks:18 |
x | x | o (OpenJDK + Maven/Gradle) | o | o (npm/Yarn) | o | o | o | x | x |
heroku/buildpacks:20 |
x | x | o (OpenJDK + Maven/Gradle) | o | o (npm/Yarn) | o | o | o | x | x |
paketobuildpacks/builder:base |
x | o | o (Liberica JDK + Maven/Gradle) | o | o (npm/Yarn) | o | o | x | o | x |
paketobuildpacks/builder:full |
x | o | o (Liberica JDK + Maven/Gradle) | o | o (npm/Yarn) | o | o | o | o | o |
paketobuildpacks/builder:tiny |
x | x | o (Liberica JDK + Maven/Gradle) | o | x | x | x | x | x | x |
どのBuilderもGoとJavaには対応しています。それ以外のプログラミング言語やビルドツールはBuilderによって対応有無が異なります。
生成されるコンテナイメージのattack surfaceの小ささ
生成されるコンテナイメージは、余計なファイルやパッケージを含んでおらず、attack surfaceは小さいほうが望ましいです。
各BuilderのRun imageの情報を改めてまとめます。
ベースイメージ | パッケージ数 | イメージサイズ | |
---|---|---|---|
gcr.io/buildpacks/builder:v1 |
gcr.io/gcp-runtimes/ubuntu_18_0_4 |
123 | 120MB |
heroku/buildpacks:18 |
ubuntu:18.04 |
354 | 510MB |
heroku/buildpacks:20 |
ubuntu:20.04 |
354 | 566MB |
paketobuildpacks/builder:base |
ubuntu:bionic |
96 | 88.9MB |
paketobuildpacks/builder:full |
ubuntu:bionic |
586 | 691MB |
paketobuildpacks/builder:tiny |
scratch |
不明 | 17.4MB |
Builder paketobuildpacks/builder:tiny
のRun imageは scratch
に必要なパッケージのみを追加する形で作成しており、イメージサイズが最も小さいです。具体的なパッケージ数は確認できていませんが最も少ないと推測されます。
それ以外のBuilderのRun imageは ubuntu:bionic
やそれに近いイメージをベースとしており、bashなどアプリケーションの実行に必須でないパッケージを含んでいます。
開発の活発さ
Builderは、開発が活発で、機能改善や脆弱性の修正が積極的に行われているものが望ましいです。
各Builderを管理しているGitHubリポジトリのStar数と直近1ヶ月のコミット数4を見てみましょう。
URL | Star数 | コミット数 | |
---|---|---|---|
gcr.io/buildpacks/builder:v1 |
https://github.com/GoogleCloudPlatform/buildpacks | 699 | 40 |
heroku/buildpacks:18 |
https://github.com/heroku/pack-images | 26 | 8 |
heroku/buildpacks:20 |
https://github.com/heroku/pack-images | 26 | 8 |
paketobuildpacks/builder:base |
https://github.com/paketo-buildpacks/base-builder | 13 | 20 |
paketobuildpacks/builder:full |
https://github.com/paketo-buildpacks/full-builder | 16 | 24 |
paketobuildpacks/builder:tiny |
https://github.com/paketo-buildpacks/tiny-builder | 13 | 15 |
HerokuとPaketo BuildpacksはBuilder・Stack・Buildpackを個別のリポジトリで管理していますが、Googleはそれらを1つのリポジトリで管理しています。そのため単純な比較は出来ませんが、どのBuilderも継続的に更新されていることがわかります。
また、Google CloudではBuildpacksによるコンテナイメージのビルドをサポートしています。
お知らせ: Google Cloud の Buildpacks でコンテナ イメージ作成が簡単に | Google Cloud Blog
このサポートが続く限り、Builder gcr.io/buildpacks/builder:v1
は、Google Cloud上で実行するのに適したコンテナイメージを生成できるよう、Googleによってメンテナンスされることが期待できます。
ベンダーニュートラル
Paketo Buildpacksはベンダーニュートラルを謳っています。 公式ドキュメント には以下のように記述されています。
The project has vendor-neutral governance through the Cloud Foundry Foundation
一方で、GoogleやHerokuのBuilderは、それぞれのベンダーのクラウドプラットフォーム上で実行するコンテナイメージの作成を主な対象としています。例えばBuilder gcr.io/buildpacks/builder:v1
のGitHubリポジトリ https://github.com/GoogleCloudPlatform/buildpacks には、Google Cloud向けである旨が以下のように記述されています。
This repository contains a set of builders and buildpacks designed to run on Google Cloud's container platforms: Cloud Run, GKE, Anthos, and Compute Engine running Container-Optimized OS. They are also used as the build system for App Engine and Cloud Functions.
ただし現時点ではこれらのBuilderを使ってベンダーに依存しないコンテナイメージを生成することも可能です。
考察
GoやJavaで記述されたアプリケーションであれば、Run imageのattack surfaceの小さい paketobuildpacks/builder:tiny
を使用するのがよいでしょう。それ以外のBuilderは、Run imageがbashなどアプリケーションの実行に必須でないパッケージを含んでいるため、仕事で使用するにはあまり適さないでしょう。
また、仕事で使用するコンテナイメージは十分な品質が求められます。そのため、既存のBuilderを使用する場合は、使用するRun imageの構成やBuildpackの実装を確認するのがよいでしょう。また、各Builderは積極的にメンテナンスされているため、確認は1回だけでなく継続的に行うのがよいでしょう。
ただ本記事の趣旨を否定するようですが、それを行うぐらいならば、自分たちのサービスに適したBuilderを自作して使用するほうがコンテナイメージの品質をより制御できてよいと私は考えています。もちろん、Builderを自作する分の手間はかかります。そのため、もし1つのアプリケーションでしかそのBuilderを使わないなら、Dockerfileを書いたほうが手間は少ないでしょう。一方で社内に同じプログラミング言語やビルドツールを使うプロジェクトが複数あるなら、Builderを自作して使用すると、それらのコンテナイメージの品質を横断的に保証できます。
本記事では説明しませんが、Builderを自作するのはそれほど難しくありません。詳しくは公式ドキュメントや Buildpacksのビルダーをスクラッチから作ってみる | フューチャー技術ブログ などを参照ください。
また、近年のソフトウェアは早いスピードで進化しています。今後、より高い品質のコンテナイメージを生成できるBuilderが登場し、それがデファクトスタンダードとなる可能性もあります。
今回調査しきれなかった点
生成されるコンテナイメージの品質は主にRun imageとBuildpackによって決まります。今回、Run imageについてはある程度調査できましたが、Builderに含まれる各Buildpackのビルドプロセスの詳細(実装やその品質など)までは調査できませんでした。これは今後の課題にしたいと思います。
おわりに
本記事では Cloud Native Buildpacks の主要なBuilderの調査を行いました。
Cloud Native Buildpacksはコンテナイメージのビルドプロセスを標準化・自動化してくれます。これにより、アプリケーション開発者はDockerfileを意識する必要がなくなり、アプリケーション開発に集中できます。これはとても価値のあることです。今後もCloud Native Buildpacksの進化に注目していきます。
執筆:@shibata.takao、レビュー:@sato.taichi (Shodoで執筆されました)
-
図は https://buildpacks.io/ のものを引用しています。↩
-
直接のベースイメージではなく「ベースイメージのベースイメージ」のようにいくつか遡った先で使用されているベースイメージです。他の表についても同様です。↩
-
dpkg -l
コマンドで出力されたパッケージの数です。他の表についても同様です。↩ -
dpkg
コマンドがインストールされておらずdpkg -l
コマンドでパッケージ数を確認できなかったため不明としています。↩ -
図は https://buildpacks.io/docs/concepts/components/builder/ のものを引用しています。↩
-
全て2022年1月30日時点の情報です。↩
-
2021年12月30日から2022年1月30日までのコミット数です。↩