可以通过将Spring Boot应用程序打包到Docker映像中,或使用Buildpacks创建可以在任何地方运行的Docker兼容的容器映像,来对它们进行容器化

31.1 构建Docker映像

通过将仅几行添加到可用于构建映像的Dockerfile中,可以将典型的Spring Boot胖子罐转换为Docker映像。但是,像在docker映像中一样,复制和运行胖子罐还有很多弊端。在不打开包装的情况下运行胖罐时,总会有一定的开销,在容器化环境中,这很明显。另一个问题是,将应用程序的代码及其所有依赖项放在Docker映像的一层是次优的。由于重新编译代码的频率可能比升级所用Spring Boot的版本的频率高,因此最好分开一些东西。如果将jar文件放在应用程序类之前的层中,则Docker通常只需要更改最底层即可从其缓存中拾取其他文件。

31.1.1 分层Docker映像

为了更轻松地创建可以使用dockerfile构建的优化的Docker映像,Spring Boot支持在jar中添加一个层索引文件。它提供了层的列表以及应包含在其中的罐子的各个部分。索引中的层列表是根据应将层添加到Docker / OCI映像的顺序来排序的。现成的,支持以下层:

  • dependencies (对于常规发布的依赖项)
  • spring-boot-loader(适用于org/springframework/boot/loader
  • snapshot-dependencies (对于快照依赖性)
  • application (用于应用程序类和资源)

以下显示了一个示例 layers.idx文件:

  1. - "dependencies":
  2. - BOOT-INF/lib/library1.jar
  3. - BOOT-INF/lib/library2.jar
  4. - "spring-boot-loader":
  5. - org/springframework/boot/loader/JarLauncher.class
  6. - org/springframework/boot/loader/jar/JarEntry.class
  7. - "snapshot-dependencies":
  8. - BOOT-INF/lib/library3-SNAPSHOT.jar
  9. - "application":
  10. - META-INF/MANIFEST.MF
  11. - BOOT-INF/classes/a/b/C.class

此分层旨在根据应用程序构建之间更改的可能性来分离代码。库代码不太可能在内部版本之间进行更改,因此将其放置在自己的层中,以允许工具重新使用缓存中的层。应用程序代码更可能在内部版本之间进行更改,因此将其隔离在单独的层中。
对于Maven,请参阅分层包装罐部分以获取有关在jar中添加层索引的更多详细信息。对于Gradle,请参阅Gradle插件文档的包装分层jar部分

31.1.2 编写Dockerfile

创建包含图层索引文件的spring-boot-jarmode-layertoolsjar时,该jar将作为依赖项添加到jar中。将此jar放在类路径上后,您可以在特殊模式下启动应用程序,该模式允许引导程序代码运行与应用程序完全不同的内容,例如提取层的内容。

layertools模式不能与包含启动脚本的完全可执行的Spring Boot存档一起使用。构建旨在与一起使用的jar文件时,请禁用启动脚本配置layertools

您可以通过layertoolsjar模式启动jar:

  1. $ java -Djarmode=layertools -jar my-app.jar

这将提供以下输出:

  1. Usage:
  2. java -Djarmode=layertools -jar my-app.jar
  3. Available commands:
  4. list List layers from the jar that can be extracted
  5. extract Extracts layers from the jar for image creation
  6. help Help about any command

extract命令可用于轻松地将应用程序拆分为多个层,以添加到dockerfile中。这是使用的Dockerfile的示例jarmode

  1. FROM adoptopenjdk:11-jre-hotspot as builder
  2. WORKDIR application
  3. ARG JAR_FILE=target/*.jar
  4. COPY ${JAR_FILE} application.jar
  5. RUN java -Djarmode=layertools -jar application.jar extract
  6. FROM adoptopenjdk:11-jre-hotspot
  7. WORKDIR application
  8. COPY --from=builder application/dependencies/ ./
  9. COPY --from=builder application/spring-boot-loader/ ./
  10. COPY --from=builder application/snapshot-dependencies/ ./
  11. COPY --from=builder application/application/ ./
  12. ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

假设以上 Dockerfile内容位于当前目录中,则可以使用构建docker映像,也可以docker build .选择指定应用程序jar的路径,如以下示例所示:
docker build —build-arg JAR_FILE =路径/到/myapp.jar。
这是一个多阶段的dockerfile。构建器阶段提取以后需要的目录。每一个COPY命令都与jarmode提取的层有关。
当然,无需使用jarmode即可编写Dockerfile。你可以使用一些组合unzipmv事物向右移动层,但jarmode简化了。

31.2 构建包

Dockerfiles只是构建Docker镜像的一种方式。构建docker映像的另一种方法是直接从您的Maven或Gradle插件中使用buildpacks。如果您曾经使用过Cloud Foundry或Heroku等应用程序平台,那么您可能已经使用过buildpack。Buildpacks是平台的一部分,可接收您的应用程序并将其转换为平台可以实际运行的内容。例如,Cloud Foundry的Java buildpack将注意到您正在推送.jar文件并自动添加相关的JRE。
借助Cloud Native Buildpacks,您可以创建可在任何地方运行的Docker兼容映像。Spring Boot直接支持Maven和Gradle的buildpack。这意味着您只需键入一个命令,即可将明智的映像快速地导入本地运行的Docker守护程序。
请参阅各个插件文档,以了解如何将buildpacks与MavenGradle一起使用。