让编译、推拉镜像进入秒级
SpringBoot提供分层能力,支持构建分层的镜像,分层自下向上分四层
- release版本依赖
- 快照版依赖
- spring loader
- 项目编译后文件
基于分层后的镜像,可以让编译、推拉镜像进入秒级,日常的编译后文件只有kb或者5M内大小
实践
1. springboot生成分层元信息
Springboot 2.4 版本及后layers默认打开
springboot插件的配置打开分层参数 layers=true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| <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内容示例:
1
2
3
4
5
6
7
8
9
10
11
| - "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,第一个镜像用于执行拆包,第二个构建启动镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # 分层构建, 加速增量构建
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平级。
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| <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>
|
然后就可以使用下面命令打包和构建镜像了
1
2
| # 编译jar包, 构建镜像和推送
mvn clean install docker:build docker:push
|
参考文档
- Creating Efficient Docker Images with Spring Boot 2.3
- Spring Boot使用Docker分层打包
- docker-maven-plugin