SpringBoot 2.3.x の 「OCI images using Cloud Native Buildpacks」を試してみた
背景
TwitterでSpringBoot2.3.xでは Cloud Native Buildpacks によって jib プラグインを使わずに DockerfileレスでDockerイメージをビルド出来ると教えていただきました。
ご存知かもしれませんが、Spring Boot 2.3からはCloud Native Buildpackを使ってデフォルトのままコマンド一発でDockerイメージが作れるようになったので、ぜひお試しください。(そして詳しい部分を僕に教えてほしいですw
— Ryo Shindo (@shindo_ryo) 2020年6月21日
な、なんだってーー!!
ということで、試さないかもと言っておきながら、早速試してみました。
環境
Java
- Librca JDK 11.0.7
- Spring Boot 2.3.1.RELEASE
- Gradle 6.5
- Jib Gradle Plugin 2.4.0 (比較用)
- Docker Desktop for Mac 2.3.0.3 (45519)
- docker-ce 19.03.8
ざっくりとしたまとめ
評価項目 | Cloud Native Buildpacks | Jib Gradle Plugin |
---|---|---|
手軽さ | ○ | △ |
スピード | × | ○ |
機能性 | |
|
イメージサイズ | △ | ○ |
シンプルさ | × | ○ |
詳細
手軽さ
jib と比べた場合、spring-boot-gradle-plugin(Maven の場合は spring-boot-maven-plugin)のみで完結するため、わざわざjib pluginのようなサードパーティ製プラグインを導入せずに使える。 とはいえ、jib plugin の導入自体も難しいものではないため、Dockerfileを書かずにコンテナー化するための敷居が下がった程度と言えよう。
スピード
きちんと時間計測はしていないが、jib pluginでビルドした方がビルド時間は短い。
機能性
Twitterでご指摘いただきました。とても有益な情報をありがとうございます!
こんにちは。確かにjibの方がビルドは速いしあとはDocker Daemonなしでビルドできるってメリットがありますね。
— Toshiaki Maki (@making) 2020年6月22日
CNBもjibにはないメリットがあるのでよかったら↓の資料か動画をチェックしてみてもらいたいです。資料から省きましたがベースイメージの差し替えもできます。https://t.co/xBfF5WpXpC
Memory Calculator、Link-Local DNS、JVMKill Agent (個人的には特に前者2つ)はとても魅力的。 jib でやるには、事前にベースイメージとして、これらをインストールしたものを使うほか無いだろう。
生成するDockerイメージ名を変更出来る程度で、Dockerfileの
ベースイメージの変更は、おそらくbuilderのrun imageを差し替えることになる。
ただ、そうすると自前でbuilderを用意しないとならなさそう(Dockerfile3つとTOMLでいけるだろうけど)なので、jibよりはハードルが高そう。
(何となくだが、AWS CodeBuildのbuildspec.ymlとビルド環境として指定するイメージがひとまとめになったものがbuilderというイメージ。高機能故に少し複雑)FROM
で指定するような内容は設定できそうに無い。(jibなら出来る)
イメージのタイムスタンプをDockerの形式(?)に合わせることができなさそう(jibなら出来る)
Spring Boot Gradle Plugin Reference Guide
イメージサイズ
同じアプリをビルドして docker images
で表示されるサイズを比較してみた。
Cloud Native Buildpacks でビルドした場合417MB。 jibでビルドした場合(jib.from.imageをデフォルトから変更しない場合です)366MB。
→ Memory Calculator、Link-Local DNS、JVMKill Agent が入っていること、layer数が多いことを考えると、左程の差ではなさそう。(ベースイメージのサイズが支配的になるお話。jibで mcr.microsoft.com/java/jdk:11-zulu-alpine
を指定したら600MB超えたから充分、許容範囲内だろう。それでもデカいというならGraalVM使うしかない気がする)
シンプルさ
Cloud Native Buildpacks はとても高機能だが、その反面、jibほどシンプルでは無い(Builder/Stack/Run Imageが存在するので、それを理解しないとどのようにすればベースイメージを変えられるのか?がわからないなど)。 ということで、シンプルさはjibにあると思う。(シンプルが必ずしも良いとは言わないし、高機能も同じく。この辺はGo言語とRustのどちらの方がいいのか?という不毛な議論と同じようなお話だろう。手軽さ・使い勝手が大事なのだと思うんだけど…)
結論
現状では jib plugin を使用した方が ベースイメージ(DockerfileのFROMに指定するイメージ)を指定できたり、 タイムスタンプ形式の変更、外部ファイルの追加、 ビルドスピードといった面で優位である。
しかしながら、Memory Calculator、Link-Local DNS、JVMKill Agent といったミドルウェアの存在を考えると、Cloud Native Buildpacks の方が運用していく上で欲しいものが最初から付いてくるので良い。
また、毎回、[start.spring.io:title] で作ったプロジェクトに jib plugin を導入する手間を考えると、自動生成されたプロジェクトに設定済みのプラグインだけで完結するというのは嬉しい限り。
run image (ベースイメージ) を build.gradle で指定出来るようになってくれると嬉しいかも。(今はjibと比べるとちょっと敷居高い)
検証コード
jib
Cloud Native Buildpacks
Remove jib by poad · Pull Request #34 · poad/examples · GitHub
おまけ
ビルドコマンド (Gradle)
jib
./gradlew jibDockerBuild
Cloud Native Buildpacks
./gradlew bootBuildImage