575 字
3 分钟
SpringBoot 原生镜像分层
让编译、推拉镜像进入秒级
SpringBoot提供分层能力,支持构建分层的镜像,分层自下向上分四层
- release版本依赖
- 快照版依赖
- spring loader
- 项目编译后文件 基于分层后的镜像,可以让编译、推拉镜像进入秒级,日常的编译后文件只有kb或者5M内大小
实践
1. springboot生成分层元信息
Springboot 2.4 版本及后layers默认打开
springboot插件的配置打开分层参数 layers=true
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.8.RELEASE</version>
<configuration>
<!-- 启用分层打包支持 -->
<layers>
<enabled>true</enabled>
</layers>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
开启分层后,springboot会在fat jar中生成layers.idx元信息 layers.idx内容示例:
- "dependencies":
- "BOOT-INF/lib/dependency1.jar"
- "BOOT-INF/lib/dependency2.jar"
- "spring-boot-loader":
- "org/"
- "snapshot-dependencies":
- "BOOT-INF/lib/dependency3-SNAPSHOT.jar"
- "BOOT-INF/lib/dependency4-SNAPSHOT.jar"
- "application":
- "BOOT-INF/classes/"
- "META-INF/"
2. 拆包和打镜像
spingboot提供了拆包的命令,把springboot fat jar 拆包到extract目录 示例命令 java -Djarmode=layertools -jar app.jar extract
执行后可以在extract中获得如下的目录
- dependencies release版本依赖
- snapshot-dependencies 快照版依赖
- spring-boot-loader
- application 项目编译后文件
简化打包的dockerfile,第一个镜像用于执行拆包,第二个构建启动镜像
# 分层构建, 加速增量构建
FROM openjdk:8 as builder
WORKDIR app
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
RUN java -Djarmode=layertools -jar app.jar extract && rm app.jar
FROM openjdk:8
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV JAVA_OPTS=" -server -Xmx1024m -Xms256m -Xmn512m -Xss256k"
WORKDIR app
COPY --from=builder /app/dependencies/ ./
COPY --from=builder /app/spring-boot-loader/ ./
COPY --from=builder /app/snapshot-dependencies/ ./
COPY --from=builder /app/application/ ./
EXPOSE 9081
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS org.springframework.boot.loader.JarLauncher"]
3. 集成mvn docker插件
请先配置好docker的私有仓库、推拉
在mvn中可以增加docker插件,可以简化镜像的构建。
- 配置
<dockerFileDir>${project.basedir}</dockerFileDir>
表示dockerfile文件在当前模块的根,和pom.xml平级。
示例
<properties>
<docker.plugin.version>0.43.4</docker.plugin.version>
<docker.registry>example.docker.com</docker.registry>
<docker.namespace>example-dev</docker.namespace>
</properties>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<!-- Docker Remote Api-->
<!-- 本机则可以注释掉, 如果没有监听2375端口 -->
<!-- <dockerHost>${docker.host}</dockerHost>-->
<!-- Docker 镜像私服-->
<registry>${docker.registry}</registry>
<images>
<image>
<name>${docker.registry}/${docker.namespace}/${project.name}:${project.version}</name>
<build>
<dockerFileDir>${project.basedir}</dockerFileDir>
</build>
</image>
</images>
</configuration>
<!-- build-image 把构建镜像绑定到了install流程,如果不需要可以把这块配置删除-->
<executions>
<execution>
<id>build-image</id>
<phase>install</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
然后就可以使用下面命令打包和构建镜像了
# 编译jar包, 构建镜像和推送
mvn clean install docker:build docker:push
参考文档
SpringBoot 原生镜像分层
https://www.jianyun.run/posts/springboot-native-image-layering/