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

参考文档#

  1. Creating Efficient Docker Images with Spring Boot 2.3
  2. Spring Boot使用Docker分层打包
  3. docker-maven-plugin
SpringBoot 原生镜像分层
https://www.jianyun.run/posts/springboot-native-image-layering/
作者
唐长老日志
发布于
2023-09-19
许可协议
CC BY-NC-SA 4.0