使用 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 的支持。 layers index 文件提供了一个层列表以及 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 社区中所有即将举行的活动。

查看全部