使用 Spring Boot 2.3 创建高效的 Docker 镜像

工程 | Madhura Bhave | 2020年8月14日 | ...

这是关于使用 Spring Boot 2.3 创建 Docker 镜像的原始博客文章的更新。在 Spring Boot 2.3 的第一个里程碑版本和 GA 版本之间,与镜像创建相关的一些内容发生了变化。

Spring Boot 2.3 引入了两个新功能来帮助改进镜像创建技术:分层 Jar 和构建包支持。

分层 Jar

随着我们开始添加对自定义层的支持,分层 Jar 功能发生了很大的变化。虽然表达 Jar 应该为镜像创建而分割成的层的需求是显而易见的,但更改 Jar 的格式以实现这一点似乎不再必要。Spring Boot 2.3 包含了使用 layers.idx 文件分层 Jar 的支持。层索引文件提供了一个层列表以及 Jar 中应该包含在这些层中的部分。层按应添加到 Docker/OCI 镜像的顺序写入。

默认情况下,定义以下层

  • dependencies 用于版本不包含 SNAPSHOT 的任何依赖项。
  • spring-boot-loader 用于 Jar 加载器类。
  • snapshot-dependencies 用于版本包含 SNAPSHOT 的任何依赖项。
  • application 用于应用程序类和资源。

相应的 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/"

层的顺序很重要,因为它决定了应用程序的一部分发生更改时,先前层被缓存的可能性。默认顺序是 dependenciesspring-boot-loadersnapshot-dependenciesapplication。内容更改的可能性越小,应该越早添加,然后是更改可能性更大的层。

要在 Spring Boot 2.3 中使用此功能,必须显式启用分层功能。以下示例演示了如何使用 Maven 插件启用分层功能

  <project>
    <build>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <version>{gradle-project-version}</version>
          <configuration>
            <layers>
              <enabled>true</enabled>
            </layers>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </project>

注意:在最新的 Spring Boot 2.4 快照中,分层功能已默认启用

创建包含 layers.idx 文件的 Jar 后,可以使用 layertools jarmode 使用这些层来制作 Dockerfile。有关如何在 Dockerfile 中使用 jarmode 的详细信息,请参阅之前的博客文章

云原生构建包支持

通过 Spring Boot Maven 和 Gradle 插件对云原生构建包的支持自上次博客文章以来没有变化,相关详细信息可以在此处找到。

自定义层

虽然我们认为我们提供的开箱即用的层适用于大多数 Spring Boot 应用程序,但可能需要根据应用程序的需求对其进行调整。例如,您可能有一些组织范围内的依赖项,其更改频率与常规依赖项不同。这可能需要将这些依赖项拆分到一个单独的层中。可以使用 Maven 和 Gradle 插件自定义 layers.idx 文件。以下示例演示了如何使用 Maven 插件中的单独 layers.xml 文件来实现此目的

<layers xmlns="http://www.springframework.org/schema/boot/layers"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
              https://www.springframework.org/schema/boot/layers/layers-{spring-boot-xsd-version}.xsd">
    <application>
      <into layer="spring-boot-loader">
        <include>org/springframework/boot/loader/**</include>
      </into>
      <into layer="application" />
    </application>
    <dependencies>
      <into layer="snapshot-dependencies">
        <include>*:*:*SNAPSHOT</include>
      </into>
      <into layer="company-dependencies">
        <include>com.acme:*</include>
      </into>
      <into layer="dependencies"/>
    </dependencies>
    <layerOrder>
      <layer>dependencies</layer>
      <layer>spring-boot-loader</layer>
      <layer>snapshot-dependencies</layer>
      <layer>company-dependencies</layer>
      <layer>application</layer>
    </layerOrder>
</layers>

上面的配置创建了一个额外的 company-dependencies 层,其中包含所有具有 com.acme groupId 的库。

Paketo Spring Boot 构建包也已更新以支持 layers.idx 文件,因此应用于它的任何自定义都将反映在构建包创建的镜像中。

有关如何使用分层和构建包集成来创建优化后的 Docker 镜像的更多详细信息,您可以查看MavenGradle插件的参考文档。

获取 Spring 时事通讯

通过 Spring 时事通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部