Spring Boot 2.3からのCloud Native Buildpacks
を試してみました。
プロジェクトの作成
Spring Initializrを使って、Spring Boot
のバージョンを2.3以降にしてプロジェクトを生成します。
※お試しプロジェクトでは、Dependenciesに Spring Web
と Spring Boot Actuator
を選択してGradleプロジェクトとしています。
Gradleのタスク一覧から、イメージ作成用のタスク(bootBuildImage
)が追加されていることが確認できます。
./gradlew tasks --group build > Task :tasks ------------------------------------------------------------ Tasks runnable from root project ------------------------------------------------------------ Build tasks ----------- assemble - Assembles the outputs of this project. bootBuildImage - Builds an OCI image of the application using the output of the bootJar task bootJar - Assembles an executable jar archive containing the main classes and their dependencies. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. classes - Assembles main classes. clean - Deletes the build directory. jar - Assembles a jar archive containing the main classes. testClasses - Assembles test classes.
タスクの詳細を確認してみると、オプションでイメージ名を指定できることがわかりますね。
./gradlew help --task bootBuildImage > Task :help Detailed task information for bootBuildImage Path :bootBuildImage Type BootBuildImage (org.springframework.boot.gradle.tasks.bundling.BootBuildImage) Options --builder The name of the builder image to use --imageName The name of the image to generate Description Builds an OCI image of the application using the output of the bootJar task Group build
イメージを作って動かしてみる
bootBuildImage
タスクを使うとさくっとイメージを作れます。
./gradlew bootBuildImage ✘ 126 > Task :bootBuildImage Building image 'docker.io/library/buildpack-example:0.0.1-SNAPSHOT' > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' .................................................. > Pulled builder image 'gcr.io/paketo-buildpacks/builder@sha256:21a7235c03dbdfcc330e03183a85e0a36b4c0eee6904529e2376502e5e4a84a5' > Pulling run image 'gcr.io/paketo-buildpacks/run:base-cnb' .................................................. > Pulled run image 'gcr.io/paketo-buildpacks/run@sha256:fb49a85ddb10a93f194cc407b34d5c352def37693c23be5b9f9a9859e7526b78' > Executing lifecycle version v0.8.1 > Using build cache volume 'pack-cache-3949d5df2001.build' > Running creator [creator] ===> DETECTING [creator] 5 of 16 buildpacks participating [creator] paketo-buildpacks/bellsoft-liberica 2.10.0 [creator] paketo-buildpacks/executable-jar 2.0.1 [creator] paketo-buildpacks/apache-tomcat 1.3.3 [creator] paketo-buildpacks/dist-zip 1.3.7 [creator] paketo-buildpacks/spring-boot 2.2.1 [creator] ===> ANALYZING [creator] Previous image with name "docker.io/library/buildpack-example:0.0.1-SNAPSHOT" not found [creator] ===> RESTORING [creator] ===> BUILDING [creator] [creator] Paketo BellSoft Liberica Buildpack 2.10.0 [creator] https://github.com/paketo-buildpacks/bellsoft-liberica [creator] Build Configuration: [creator] $BP_JVM_VERSION 11.* the Java version [creator] Launch Configuration: [creator] $BPL_JVM_HEAD_ROOM 0 the headroom in memory calculation [creator] $BPL_JVM_LOADED_CLASS_COUNT 35% of classes the number of loaded classes in memory calculation [creator] $BPL_JVM_THREAD_COUNT 250 the number of threads in memory calculation [creator] BellSoft Liberica JRE 11.0.8: Contributing to layer [creator] Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.8+10/bellsoft-jre11.0.8+10-linux-amd64.tar.gz [creator] Verifying checksum [creator] Expanding to /layers/paketo-buildpacks_bellsoft-liberica/jre [creator] Writing env.launch/JAVA_HOME.override [creator] Writing env.launch/MALLOC_ARENA_MAX.override [creator] Writing profile.d/active-processor-count.sh [creator] Memory Calculator 4.1.0: Contributing to layer [creator] Downloading from https://github.com/cloudfoundry/java-buildpack-memory-calculator/releases/download/v4.1.0/memory-calculator-4.1.0.tgz [creator] Verifying checksum [creator] Expanding to /layers/paketo-buildpacks_bellsoft-liberica/memory-calculator [creator] Writing profile.d/memory-calculator.sh [creator] Class Counter: Contributing to layer [creator] Copying to /layers/paketo-buildpacks_bellsoft-liberica/class-counter [creator] JVMKill Agent 1.16.0: Contributing to layer [creator] Downloading from https://github.com/cloudfoundry/jvmkill/releases/download/v1.16.0.RELEASE/jvmkill-1.16.0-RELEASE.so [creator] Verifying checksum [creator] Copying to /layers/paketo-buildpacks_bellsoft-liberica/jvmkill [creator] Writing env.launch/JAVA_OPTS.append [creator] Link-Local DNS: Contributing to layer [creator] Copying to /layers/paketo-buildpacks_bellsoft-liberica/link-local-dns [creator] Writing profile.d/link-local-dns.sh [creator] Java Security Properties: Contributing to layer [creator] Writing env.launch/JAVA_OPTS.append [creator] Writing env.launch/JAVA_SECURITY_PROPERTIES.override [creator] Security Providers Configurer: Contributing to layer [creator] Copying to /layers/paketo-buildpacks_bellsoft-liberica/security-providers-configurer [creator] Writing profile.d/security-providers-classpath.sh [creator] Writing profile.d/security-providers-configurer.sh [creator] OpenSSL Certificate Loader: Contributing to layer [creator] Copying to /layers/paketo-buildpacks_bellsoft-liberica/openssl-security-provider [creator] Writing profile.d/openssl-certificate-loader.sh [creator] [creator] Paketo Executable JAR Buildpack 2.0.1 [creator] https://github.com/paketo-buildpacks/executable-jar [creator] Writing env.launch/CLASSPATH [creator] Process types: [creator] executable-jar: java -cp "${CLASSPATH}" ${JAVA_OPTS} org.springframework.boot.loader.JarLauncher [creator] task: java -cp "${CLASSPATH}" ${JAVA_OPTS} org.springframework.boot.loader.JarLauncher [creator] web: java -cp "${CLASSPATH}" ${JAVA_OPTS} org.springframework.boot.loader.JarLauncher [creator] [creator] Paketo Spring Boot Buildpack 2.2.1 [creator] https://github.com/paketo-buildpacks/spring-boot [creator] Build Configuration: [creator] $BP_BOOT_NATIVE_IMAGE the build to create a native image (requires GraalVM) [creator] $BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS the arguments to pass to the native-image command [creator] Launch Configuration: [creator] $BPL_SPRING_CLOUD_BINDINGS_ENABLED whether to auto-configure Spring Boot environment properties from bindings [creator] Web Application Type: Contributing to layer [creator] Servlet web application detected [creator] Writing env.launch/BPL_JVM_THREAD_COUNT.default [creator] Spring Cloud Bindings 1.4.0: Contributing to layer [creator] Downloading from https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.4.0/spring-cloud-bindings-1.4.0.jar [creator] Verifying checksum [creator] Copying to /layers/paketo-buildpacks_spring-boot/spring-cloud-bindings [creator] Writing profile.d/spring-cloud-bindings.sh [creator] Image labels: [creator] org.springframework.boot.spring-configuration-metadata.json [creator] org.springframework.boot.version [creator] ===> EXPORTING [creator] Adding layer 'launcher' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:class-counter' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:jre' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:jvmkill' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:link-local-dns' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:memory-calculator' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:openssl-security-provider' [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:security-providers-configurer' [creator] Adding layer 'paketo-buildpacks/executable-jar:class-path' [creator] Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings' [creator] Adding layer 'paketo-buildpacks/spring-boot:web-application-type' [creator] Adding 1/1 app layer(s) [creator] Adding layer 'config' [creator] *** Images (ab7b253dc430): [creator] docker.io/library/buildpack-example:0.0.1-SNAPSHOT Successfully built image 'docker.io/library/buildpack-example:0.0.1-SNAPSHOT'
コンテナー起動後、actuator/env
で確認するとJava11でアプリケーションが実行されているのが確認できますね。
curl http://localhost:8080/actuator/env # 省略 { "value": "11.0.8+10-LTS" }
Javaのバージョンは、GradleのtargetCompatibility
と連動しているっぽく、以下のようにJava14を指定すると自動的に起動時に使用するバージョンが変わるようです。
java { targetCompatibility = JavaVersion.VERSION_14 }
上の状態でイメージ作成後に確認してみると想定通りJava14で起動されていました。
curl http://localhost:8080/actuator/env # 省略 { "value": "14.0.2+13" }
起動時のオプションを変更してみる
コンテナ起動時に、JAVA_OPTS
環境変数を設定することで起動時のJVMオプションを変更できるようです。
例えば、下のようにコンテナを起動するとhoge
システムプロパティにfuga
が設定されます。
docker run -p "8080:8080" -e JAVA_OPTS="-Dhoge=fuga" 76747f99e0c7
起動後、actuator/env
を叩くことで想定通りシステムプロパティが設定されていることが確認できます。
curl http://localhost:8080/actuator/env { "activeProfiles": [], "propertySources": [ { "name": "server.ports", "properties": { "local.server.port": { "value": 8080 } } }, { "name": "servletContextInitParams", "properties": {} }, { "name": "systemProperties", "properties": { "hoge": { "value": "fuga" } } ] }
イメージ名を指定してビルドしてみる
bootBuildImage
タスクのimageName
オプションを指定することで、イメージ名を変更できます。
リモートリポジトリの名前に合わせる場合なんかに使うとよさげですかね。
./gradlew bootBuildImage --imageName siosio/sample:1.0.0
例えば、GitHub ActionsからECRにビルドしたイメージをpushする場合なんかは、こんな感じでいけるかなと思います。
steps: - uses: actions/checkout@v2 - name: Cache Gradle packages uses: actions/cache@v1 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - name: setup java uses: actions/setup-java@v1 with: java-version: 11 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: build image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }} run: | IMAGE_TAG=$(echo ${{ github.ref }} | sed 's/refs\/heads\///g' | sed 's/\//-/g') ./gradlew bootBuildImage --imageName $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG