使用 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 和 buildpack 支持。

分层 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 Jar 模式使用这些层来制作 Dockerfile。有关如何在 Dockerfile 中使用 Jar 模式的详细信息,请参阅之前的博文

云原生 Buildpacks 支持

通过 Spring Boot Maven 和 Gradle 插件对云原生 Buildpacks 的支持自上一篇博文以来没有改变,相关详细信息可以在这里找到。

自定义层

虽然我们认为开箱即用的层适用于大多数 Spring Boot 应用程序,但可能需要根据应用程序的需求进行调整。例如,您可能有一些组织范围的依赖项,它们以与常规依赖项不同的节奏进行更改。这可能需要将这些依赖项拆分为一个单独的层。layers.idx 文件可以使用 Maven 和 Gradle 插件进行自定义。以下示例显示了如何使用带有 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 层,其中包含所有 groupId 为 com.acme 的库。

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

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

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

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

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

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

查看所有