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 appARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} app.jarRUN java -Djarmode=layertools -jar app.jar extract && rm app.jar
FROM openjdk:8ENV TZ=Asia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneENV 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/