Springboot 的 maven项目利用 maven插件构建 docker 镜像(免 DockerFile编写)
Springboot 的 maven项目利用 maven插件构建 docker 镜像(免 DockerFile编写)
本小节目的是springboot 项目 maven 插件构建容器
实验步骤:
1. 本地创建springboot项目,写业务逻辑代码
2.提交代码到远程 git仓库
3.在 linux 环境拉取远程 git 仓库代码,构建镜像
4.把构建完成的镜像推送私有 harbor 镜像仓库
- 参考官网知识
- Packaging OCI Images
The plugin can create an OCI image from a jar or war file using Cloud Native Buildpacks (CNB). Images can be built on the command-line using the build-image goal. This makes sure that the package lifecycle has run before the image is created.
For security reasons, images build and run as non-root users. See the CNB specification for more details.
The easiest way to get started is to invoke mvn spring-boot:build-image on a project. It is possible to automate the creation of an image whenever the package phase is invoked, as shown in the following example:......
Use build-image-no-fork when binding the goal to the package lifecycle. This goal is similar to build-image but does not fork the lifecycle to make sure package has run. In the rest of this section, build-image is used to refer to either the build-image or build-image-no-fork goals.
While the buildpack runs from an executable archive, it is not necessary to execute the repackage goal first as the executable archive is created automatically if necessary. When the build-image repackages the application, it applies the same settings as the repackage goal would, that is dependencies can be excluded using one of the exclude options. The spring-boot-devtools and spring-boot-docker-compose modules are automatically excluded by default (you can control this using the excludeDevtools and excludeDockerCompose properties).
创建项目
- 创建一个 springboot项目,maven管理,本次选择版本 2.7.11
#添加web,写一个经典的 hello world请求响应
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
#添加actuator,内部含有 pod 健康检查探针
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 添加 maven 插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.11</version>
<configuration>
<image>
<name>test/${project.artifactId}</name>
</image>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
完整的 pom.xml 文件
点击查看代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ant.com</groupId>
<artifactId>testk8s</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testk8s</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<!-- 打包构建-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.11</version>
<configuration>
<image>
<name>test/${project.artifactId}</name>
</image>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- 配置阿里云 maven仓库-->
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
项目推送到 git 仓库
#初始化
git init
#没有私库就推送到 github
git remote add origin git@192.168.10.190:server/testk8s.git
#后先就是创建本地分支
git pull origin dev
git commit -m "init"
git push
构建镜像(centOS)
- 准备 maven,maven版本 3.2.5+
sudo yum install maven-3.3.0
#若没有镜像,安装最新版本
sudo yum install maven
#官网手动下载安装包,解压
tar -zxvf apache-maven-3.9.4-bin.tar.gz
#替换低版本链接
sudo mv apache-maven-3.9.4 apache-maven
mkdir /usr/share/maven
mv apache-maven /usr/share/maven/
sudo ln -sfn /usr/share/maven/apache-maven/bin/mvn /usr/bin/mvn
mvn --version
- 准备 git,拉取远程仓库代码
#安装 git
yum install git
#拉取代码
git clone git@192.168.10.190:server/testk8s.git
cd testk8s/
git pull origin/dev:dev
- 开始构建镜像
mvn clean package spring-boot:build-image
第一次构建要花好长好长时间,反正这一步我花了一个小时,有精度条,甚至第一次有可能失败,失败后再试一次,第二次时间时间就短
第一次失败信息
点击查看代码
[INFO] [creator] unable to download https://github.com/bell-sw/Liberica/releases/download/8u372+7/bellsoft-jre8u372+7-linux-amd64.tar.gz
[INFO] [creator] unable to request https://github.com/bell-sw/Liberica/releases/download/8u372+7/bellsoft-jre8u372+7-linux-amd64.tar.gz
[INFO] [creator] Get "https://objects.githubusercontent.com/github-production-release-asset-2e65be/115621629/a26c3c5b-da95-4275-b072-9fc9dadb3e1d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230920%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230920T084204Z&X-Amz-Expires=300&X-Amz-Signature=f04d238723d3df35d74a1691028e25d7dd65c89265bce40d8a5c61a18344f43e&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=115621629&response-content-disposition=attachment%3B%20filename%3Dbellsoft-jre8u372%2B7-linux-amd64.tar.gz&response-content-type=application%2Foctet-stream": dial tcp: lookup objects.githubusercontent.com: i/o timeout
[INFO] [creator] ERROR: failed to build: exit status 1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:42 h
[INFO] Finished at: 2023-09-20T16:42:10+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.7.10:build-image (default) on project k8s: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.7.10:build-image failed: Builder lifecycle 'creator' failed with status code 51 -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
点击查看代码
[INFO] [creator] Writing env.launch/BPL_JVM_THREAD_COUNT.default
[INFO] [creator] 4 application slices
[INFO] [creator] Image labels:
[INFO] [creator] org.opencontainers.image.title
[INFO] [creator] org.opencontainers.image.version
[INFO] [creator] org.springframework.boot.version
[INFO] [creator] ===> EXPORTING
[INFO] [creator] Adding layer 'paketo-buildpacks/ca-certificates:helper'
[INFO] [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:helper'
[INFO] [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
[INFO] [creator] Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
[INFO] [creator] Adding layer 'paketo-buildpacks/executable-jar:classpath'
[INFO] [creator] Adding layer 'paketo-buildpacks/spring-boot:helper'
[INFO] [creator] Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[INFO] [creator] Adding layer 'paketo-buildpacks/spring-boot:web-application-type'
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:launch.sbom'
[INFO] [creator] Adding 5/5 app layer(s)
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:launcher'
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:config'
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:process-types'
[INFO] [creator] Adding label 'io.buildpacks.lifecycle.metadata'
[INFO] [creator] Adding label 'io.buildpacks.build.metadata'
[INFO] [creator] Adding label 'io.buildpacks.project.metadata'
[INFO] [creator] Adding label 'org.opencontainers.image.title'
[INFO] [creator] Adding label 'org.opencontainers.image.version'
[INFO] [creator] Adding label 'org.springframework.boot.version'
[INFO] [creator] Setting default process type 'web'
[INFO] [creator] Saving docker.io/library/k8s:0.0.1-SNAPSHOT...
[INFO] [creator] *** Images (0918fc41de57):
[INFO] [creator] docker.io/library/k8s:0.0.1-SNAPSHOT
[INFO] [creator] Adding cache layer 'paketo-buildpacks/syft:syft'
[INFO] [creator] Adding cache layer 'buildpacksio/lifecycle:cache.sbom'
[INFO]
[INFO] Successfully built image 'docker.io/library/k8s:0.0.1-SNAPSHOT'
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:09 min
[INFO] Finished at: 2023-09-20T16:52:37+08:00
[INFO] ------------------------------------------------------------------------
- 查看构建镜像结果
[root@localhost testk8s]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
paketobuildpacks/run base-cnb f2e5000af0cb 2 months ago 87.1MB
paketobuildpacks/builder base 050ed48532b2 43 years ago 1.31GB
testk8s 0.0.1-SNAPSHOT 0918fc41de57 43 years ago 229MB
可以看到我们已经构建出镜像testk8s ,这个名字及时项目的artifactId
- 把镜像推送到 harbor 私库
#登录 harbor
[root@localhost testk8s]# docker login http://192.168.10.109:30002
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
#给需要推送的镜像 tag 标签,先需要在 harbor 创建项目,这里是 test
[root@localhost testk8s]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
paketobuildpacks/run base-cnb f2e5000af0cb 2 months ago 87.1MB
paketobuildpacks/builder base 050ed48532b2 43 years ago 1.31GB
k8s 0.0.1-SNAPSHOT 0918fc41de57 43 years ago 229MB
[root@localhost testk8s]# docker tag k8s:0.0.1-SNAPSHOT 192.168.10.109:30002/test/test:0.0.1-SNAPSHOT
#推送到harbor
[root@localhost testk8s]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
paketobuildpacks/run base-cnb f2e5000af0cb 2 months ago 87.1MB
192.168.10.109:30002/test/test 0.0.1-SNAPSHOT 0918fc41de57 43 years ago 229MB
k8s 0.0.1-SNAPSHOT 0918fc41de57 43 years ago 229MB
paketobuildpacks/builder base 050ed48532b2 43 years ago 1.31GB
[root@localhost testk8s]# docker push 192.168.10.109:30002/test/test:0.0.1-SNAPSHOT
可以登录 harbor 查看
总结
1.通过maven 的构建日志我们可以看到,springboot 项目构建build-image过程也是采用了高效的分层技术
2.插件支持定义环境变量、自定义镜像名、镜像自动推送等参数信息