以下のブログにしたがってBuildpacksとJibを試してみるメモ。
サンプルアプリケーション
サンプルリポジトリをクローンする。
git clone https://github.com/jamesward/comparing-docker-methods.git cd comparing-docker-methods
ローカルにインストールされているJavaとMavenを確認する。Corretto 8がインストールされているが、MavenはOpenJDK 17を使っている。
$ java -version openjdk version "1.8.0_312" OpenJDK Runtime Environment Corretto-8.312.07.1 (build 1.8.0_312-b07) OpenJDK 64-Bit Server VM Corretto-8.312.07.1 (build 25.312-b07, mixed mode) $ mvn -version Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537) Maven home: /usr/local/Cellar/maven/3.8.4/libexec Java version: 17.0.1, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/17.0.1/libexec/openjdk.jdk/Contents/Home Default locale: ja_JP, platform encoding: UTF-8 OS name: "mac os x", version: "11.6.1", arch: "x86_64", family: "mac"
Maven Wrapperが入っていなかったので入れる。
mvn -N io.takari:maven:0.7.7:wrapper
アプリケーションを実行する。
./mvnw compile exec:java
アプリケーションにアクセスする。
$ curl localhost:8080 hello, world%
Buildpacks
packコマンドをインストールする。
brew install buildpacks/tap/pack
どのビルダーが使えるのかはサジェストしてくれる。
$ pack builder suggest Suggested builders: Google: gcr.io/buildpacks/builder:v1 Ubuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Python Heroku: heroku/buildpacks:18 Base builder for Heroku-18 stack, based on ubuntu:18.04 base image Heroku: heroku/buildpacks:20 Base builder for Heroku-20 stack, based on ubuntu:20.04 base image Paketo Buildpacks: paketobuildpacks/builder:base Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, Ruby, NGINX and Procfile Paketo Buildpacks: paketobuildpacks/builder:full Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, PHP, Ruby, Apache HTTPD, NGINX and Procfile Paketo Buildpacks: paketobuildpacks/builder:tiny Tiny base image (bionic build image, distroless-like run image) with buildpacks for Java, Java Native Image and Go Tip: Learn more about a specific builder with: pack builder inspect <builder-image>
イメージを全部消す。
docker images -aq | xargs docker rmi -f
イメージをビルドする。
$ pack build --builder=gcr.io/buildpacks/builder:v1 comparing-docker-methods:buildpacks v1: Pulling from buildpacks/builder ... Digest: sha256:ae9956349502a7d9b340651ddc536e80821c254c77c16f30742216322b3eff87 Status: Downloaded newer image for gcr.io/buildpacks/builder:v1 v1: Pulling from buildpacks/gcp/run ... Digest: sha256:3f45378eae3d66d960c6e09ea86739aa568744638f90e40b35b26c254d2f3c27 Status: Downloaded newer image for gcr.io/buildpacks/gcp/run:v1 ===> DETECTING 4 of 5 buildpacks participating google.java.runtime 0.9.1 google.java.maven 0.9.0 google.java.entrypoint 0.9.0 google.utils.label 0.0.1 ===> ANALYZING Previous image with name "comparing-docker-methods:buildpacks" not found Restoring metadata for "google.java.maven:m2" from cache ===> RESTORING Restoring data for "google.java.maven:m2" from cache ===> BUILDING === Java - Runtime (google.java.runtime@0.9.1) === Using latest Java 11 runtime version. You can specify a different version with GOOGLE_RUNTIME_VERSION: https://github.com/GoogleCloudPlatform/buildpacks#configuration -------------------------------------------------------------------------------- Running "curl --fail --show-error --silent --location https://api.adoptopenjdk.net/v3/assets/feature_releases/11/ga?architecture=x64&heap_size=normal&image_type=jdk&jvm_impl=hotspot&os=linux&page=0&page_size=1&project=jdk&sort_order=DESC&vendor=adoptopenjdk" [ { "binaries": [ { "architecture": "x64", "download_count": 166661, "heap_size": "normal", "image_type": "jdk", "jvm_impl": "hotspot", "os": "linux", "package": { "checksum": "3b1c0c34be4c894e64135a454f2d5aaa4bd10aea04ec2fa0c0efe6bb26528e30", "checksum_link": "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.13%2B8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.13_8.tar.gz.sha256.txt", "download_count": 166661, "link": "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.13%2B8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.13_8.tar.gz", "metadata_link": "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.13%2B8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.13_8.tar.gz.json", "name": "OpenJDK11U-jdk_x64_linux_hotspot_11.0.13_8.tar.gz", "size": 192958006 }, "project": "jdk", "scm_ref": "jdk-11.0.13+8_adopt", "updated_at": "2021-10-21T21:55:42Z" } ], "download_count": 508086, "id": "MDc6UmVsZWFzZTUxODI0ODA2.DrSSnWfQGA0+fw==", "release_link": "https://github.com/adoptium/temurin11-binaries/releases/tag/jdk-11.0.13%2B8", "release_name": "jdk-11.0.13+8", "release_type": "ga", "source": { "link": "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.13%2B8/OpenJDK11U-sources_11.0.13_8.tar.gz", "name": "OpenJDK11U-sources_11.0.13_8.tar.gz", "size": 123491655 }, "timestamp": "2021-10-21T21:55:18Z", "updated_at": "2021-11-15T16:03:02Z", "vendor": "eclipse", "version_data": { "build": 8, "major": 11, "minor": 0, "openjdk_version": "11.0.13+8", "security": 13, "semver": "11.0.13+8" } } ]Done "curl --fail --show-error --silent --location https://api.ado..." (850.3602ms) Installing Java v11.0.13+8 -------------------------------------------------------------------------------- Running "bash -c curl --fail --show-error --silent --location --retry 3 https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.13%2B8/OpenJDK11U-jdk_x64_linux_hotspot_11.0.13_8.tar.gz | tar xz --directory /layers/google.java.runtime/java --strip-components=1" Done "bash -c curl --fail --show-error --silent --location --retry..." (18.2298941s) === Java - Maven (google.java.maven@0.9.0) === -------------------------------------------------------------------------------- Running "./mvnw clean package --batch-mode -DskipTests -Dhttp.keepAlive=false --quiet" Done "./mvnw clean package --batch-mode -DskipTests -Dhttp.keepAli..." (6.8467339s) === Java - Entrypoint (google.java.entrypoint@0.9.0) === WARNING: Launch layer is setting default=true, but that is not supported until API version 0.6. This setting will be ignored. Warning: Warning: default processes aren't supported in this buildpack api version. Overriding the default value to false for the following processes: [web] === Utils - Label Image (google.utils.label@0.0.1) === ===> EXPORTING Adding layer 'google.java.runtime:java' Adding 1/1 app layer(s) Adding layer 'launcher' Adding layer 'config' Adding layer 'process-types' Adding label 'io.buildpacks.lifecycle.metadata' Adding label 'io.buildpacks.build.metadata' Adding label 'io.buildpacks.project.metadata' Setting default process type 'web' Saving comparing-docker-methods:buildpacks... *** Images (d9a7fa05282b): comparing-docker-methods:buildpacks Reusing cache layer 'google.java.runtime:java' Reusing cache layer 'google.java.maven:m2' Successfully built image comparing-docker-methods:buildpacks
イメージを確認する。作成日付がおかしい。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE gcr.io/buildpacks/builder v1 0be9c8be1372 34 hours ago 626MB gcr.io/buildpacks/gcp/run v1 e9c0a00a124f 34 hours ago 120MB comparing-docker-methods buildpacks d9a7fa05282b 41 years ago 444MB
イメージを実行する。
docker run -it -ePORT=8080 -p8080:8080 comparing-docker-methods:buildpacks
アクセス確認する。
$ curl localhost:8080 hello, world%
diveでイメージを見てみる。
dive comparing-docker-methods:buildpacks
ビルド時のメッセージと比較して見ると以下だと思われる。
サイズ | 中身 |
---|---|
(上の5レイヤー) | gcr.io/buildpacks/gcp/run:v1 |
321 MB | Adding layer 'google.java.runtime:java' |
177 kB | Adding 1/1 app layer(s) |
2.5 MB | Adding layer 'launcher' |
675 B | Adding layer 'config' |
0 B | Adding layer 'process-types' |
メッセージからすると、Buildpacksもレイヤリングしてくれそう。
Jib
pom.xmlに以下を追加する。
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>2.6.0</version> </plugin>
イメージを全部消す。
docker images -aq | xargs docker rmi -f
コンテナイメージをビルドしてローカルに保存する。
$ ./mvnw compile jib:dockerBuild -Dimage=comparing-docker-methods:jib [INFO] Scanning for projects... [INFO] [INFO] ---------------------< com.google:sample-java-mvn >--------------------- [INFO] Building sample-java-mvn 0.1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ sample-java-mvn --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /Users/sotosugi/workspace/2021/aisac/buildpacks/comparing-docker-methods/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ sample-java-mvn --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- jib-maven-plugin:2.6.0:dockerBuild (default-cli) @ sample-java-mvn --- [INFO] [INFO] Containerizing application to Docker daemon as comparing-docker-methods:jib... [WARNING] Base image 'gcr.io/distroless/java:8' does not use a specific image digest - build may not be reproducible [INFO] Using base image with digest: sha256:34c3598d83f0dba27820323044ebe79e63ad4f137b405676da75a3905a408adf [INFO] [INFO] Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, com.google.WebApp] [INFO] [INFO] Built image to Docker daemon as comparing-docker-methods:jib [INFO] Executing tasks: [INFO] [==============================] 100.0% complete [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.371 s [INFO] Finished at: 2021-11-26T16:24:06+09:00 [INFO] ------------------------------------------------------------------------
イメージを確認する。メッセージにでているが、ベースイメージがgcr.io/distroless/java:8
なのでサイズが小さい。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE comparing-docker-methods jib 625395395d3e 51 years ago 130MB
diveで見てみると、最後の前のレイヤーでディレクトリが作られ、最後のレイヤーでjarが置かれているように見える。
Dockerfile
Dockerfileを作成する。このadoptopenjdk/openjdk8のイメージはUbuntuベースのイメージのようだ。
FROM adoptopenjdk/openjdk8 as builder WORKDIR /app COPY . /app RUN ./mvnw compile jar:jar FROM adoptopenjdk/openjdk8:jre COPY --from=builder /app/target/*.jar /server.jar CMD ["java", "-jar", "/server.jar"]
イメージを全部消す。
docker images -aq | xargs docker rmi -f
ビルドする。
docker build -t comparing-docker-methods:dockerfile .
確認する。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE comparing-docker-methods dockerfile 42980788df0c 46 seconds ago 224MB
GraalVMを使う方法は省略。
まとめ
packとjibでビルドし直し、またベースイメージもpullして、関連したイメージを全部まとめて一覧表示する。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE comparing-docker-methods dockerfile 42980788df0c 17 minutes ago 224MB gcr.io/buildpacks/builder v1 0be9c8be1372 35 hours ago 626MB gcr.io/buildpacks/gcp/run v1 e9c0a00a124f 35 hours ago 120MB adoptopenjdk/openjdk8 jre 4e41c2a5a301 40 hours ago 224MB adoptopenjdk/openjdk8 latest f5be1fb5cc77 40 hours ago 320MB comparing-docker-methods buildpacks fb4cfe8a43ed 41 years ago 444MB comparing-docker-methods jib 625395395d3e 51 years ago 130MB gcr.io/distroless/java 8 b762aad6c014 51 years ago 130MB