電通総研 テックブログ

電通総研が運営する技術ブログ

Cloud Native Buildpacksの主要なBuilderを調べてみた

こんにちは、XI本部クラウドイノベーションセンターの柴田です。

本記事では Cloud Native Buildpacks の主要なBuilderの調査を行います。

Cloud Native Buildpacksとは

Cloud Native Buildpacks は、HerokuとPivotalによってCNCFのincubating projectの1つとして2018年に発足しました。Herokuが開発していたBuildpacksというツールをベースにしています。

1

Cloud Native Buildpacksは簡単に言うと「Dockerfileを書かずにコンテナイメージを生成してくれるツール」です。アプリケーションの構成(プログラミング言語やビルドツールなど)を自動的に検知し、それに適したビルドプロセスを自動的に選択して、アプリケーションのコンテナイメージをビルドします。これにより、アプリケーション開発者がDockerfileのベストプラクティスを学習したり、Dockerfileを実際に記述したりする必要がなくなります。

Cloud Native Buildpacksの主要な要素にはBuildpack、Stack、Builderの3つがあります。

  • Buildpack :特定の構成(プログラミング言語やビルドツールなど)のアプリケーションに対するビルドプロセスです。具体的には DetectBuild という2つのプロセスから構成されます。
    • Detect :ビルド対象のアプリケーションがBuildpackの対象構成に該当するか判定するロジックです。
    • Build :Detectが該当すると判定した場合、実際にアプリケーションのコンテナイメージをビルドするプロセスです。
  • Stack :Buildpackが使用するコンテナイメージです。マルチステージビルドを前提としており、 Build imageRun image という2つのイメージから構成されます。
    • Build image :アプリケーションのビルドに使用するコンテナイメージです。
    • Run image :アプリケーションの実行に使用するコンテナイメージです。
  • Builder :「Stack」と「Buildpackの集合」の組み合わせです。

2

主要な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 Google 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 Google 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-cnbbase-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:v1GitHubリポジトリ 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.taichiShodoで執筆されました


  1. 図は https://buildpacks.io/ のものを引用しています。

  2. 直接のベースイメージではなく「ベースイメージのベースイメージ」のようにいくつか遡った先で使用されているベースイメージです。他の表についても同様です。

  3. dpkg -l コマンドで出力されたパッケージの数です。他の表についても同様です。

  4. dpkg コマンドがインストールされておらず dpkg -l コマンドでパッケージ数を確認できなかったため不明としています。

  5. 図は https://buildpacks.io/docs/concepts/components/builder/ のものを引用しています。

  6. 全て2022年1月30日時点の情報です。

  7. 2021年12月30日から2022年1月30日までのコミット数です。