Software development of explosion! -夢の破片(カケラ)たちの日々-

ソフトウェア開発を中心としたコンピューター関連のネタを扱ったブログです

Software development is passion and explosion!

SpringBoot 2.3.x の 「OCI images using Cloud Native Buildpacks」を試してみた

背景

TwitterでSpringBoot2.3.xでは Cloud Native Buildpacks によって jib プラグインを使わずに DockerfileレスでDockerイメージをビルド出来ると教えていただきました。

な、なんだってーー!!

ということで、試さないかもと言っておきながら、早速試してみました。

環境

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でご指摘いただきました。とても有益な情報をありがとうございます!

Memory Calculator、Link-Local DNS、JVMKill Agent (個人的には特に前者2つ)はとても魅力的。 jib でやるには、事前にベースイメージとして、これらをインストールしたものを使うほか無いだろう。

生成するDockerイメージ名を変更出来る程度で、Dockerfileの FROM で指定するような内容は設定できそうに無い。(jibなら出来る) ベースイメージの変更は、おそらくbuilderのrun imageを差し替えることになる。 ただ、そうすると自前でbuilderを用意しないとならなさそう(Dockerfile3つとTOMLでいけるだろうけど)なので、jibよりはハードルが高そう。 (何となくだが、AWS CodeBuildのbuildspec.ymlとビルド環境として指定するイメージがひとまとめになったものがbuilderというイメージ。高機能故に少し複雑)

イメージのタイムスタンプを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

examples/java-example/morphological-analyis/kuromoji at 54e1698f705884a5a47a4c642a9cf67b7526f64d · poad/examples · GitHub

Cloud Native Buildpacks

Remove jib by poad · Pull Request #34 · poad/examples · GitHub

おまけ

ビルドコマンド (Gradle)

jib

./gradlew jibDockerBuild

Cloud Native Buildpacks

./gradlew bootBuildImage