Spring Boot对容器镜像(Container Images)的支持

https://docs.spring.io/spring-boot/docs/3.2.0/reference/htmlsingle/#container-images

Spring Boot应用程序可以通过Dockerfile进行容器化,或者使用Cloud Native Buildpacks创建优化的、与Docker兼容的容器镜像,你可以在任何地方运行这些镜像。

高效的容器镜像

将Spring Boot的uber jar(指一个包含项目所有依赖的单一jar文)打包为Docker镜像非常容易。但是,在Docker镜像中复制并运行uber jar存在多种缺点。在不解压的情况下运行uber jar总是会产生一定的开销,在容器化环境中,这可能会很明显。另一个问题是,将应用程序的代码及其所有依赖项放在Docker镜像的一个层中不是最佳选择。由于你可能经常重新编译代码,而升级使用的Spring Boot版本的频率较低,因此通常最好将事物分开一些。如果将jar文件放在应用程序类之前的层中,Docker通常只需要更改最底层的层,并可以从其缓存中获取其它层。

Docker镜像分层

为了使创建优化的Docker镜像变得更加简单,Spring Boot支持向jar文件添加一个分层索引文件。这个文件提供了层的列表以及应该包含在这些层中的jar的部分。索引中层的列表是基于应该将层添加到Docker/OCI镜像的顺序进行排序的。开箱即用,支持以下层:

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

以下是一个layers.idx文件的示例:

- "dependencies":
  - BOOT-INF/lib/library1.jar
  - BOOT-INF/lib/library2.jar
- "spring-boot-loader":
  - org/springframework/boot/loader/launch/JarLauncher.class
  - ... <other classes>
- "snapshot-dependencies":
  - BOOT-INF/lib/library3-SNAPSHOT.jar
- "application":
  - META-INF/MANIFEST.MF
  - BOOT-INF/classes/a/b/C.class

这种分层设计旨在根据代码在应用程序构建之间更改的可能性来分离代码。库代码在构建之间不太可能更改,因此它被放置在自己的层中,以允许工具从缓存中重用这些层。应用程序代码在构建之间更有可能更改,因此它被隔离在单独的层中。

layers.idx的帮助下,Spring Boot还支持对war文件进行分层。

Dockerfile

尽管在Dockerfile中只需几行就可以将Spring Boot的uber jar转换为docker镜像,但将使用分层功能来创建一个优化的docker镜像。当你创建一个包含分层索引文件的jar时,spring-boot-jarmode-layertools jar将作为你的jar的依赖项被添加。当此jar在类路径上时,你可以以特殊模式启动你的应用程序,这允许引导代码运行与你的应用程序完全不同的内容,例如,提取各层的内容。

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

这是你可以使用带有layertools jar模式的jar来启动应用程序的方式:

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

这将会产生以下输出:

Usage:
  java -Djarmode=layertools -jar my-app.jar

Available commands:
  list     List layers from the jar that can be extracted
  extract  Extracts layers from the jar for image creation
  help     Help about any command

extract 命令可用于轻松将应用程序拆分为多个层,以便将其添加到dockerfile中。下面是一个使用jarmode的Dockerfile示例:
在这里插入图片描述

假设上述Dockerfile位于当前目录中,你可以使用docker build .命令来构建你的Docker镜像,或者可以选择性地指定你的应用程序jar文件的路径,如下例所示:

$ docker build --build-arg JAR_FILE=path/to/myapp.jar .

这是一个多阶段的Dockerfile。构建阶段提取了稍后所需的目录。每个COPY命令都与通过jarmode提取的层相关。

当然,Dockerfile也可以在不使用jarmode的情况下编写。你可以使用unzipmv的某种组合将东西移到正确的层,但jarmode简化了这一过程。

Cloud Native Buildpacks(云原生构建包)

Dockerfile只是构建Docker镜像的一种方式。另一种构建Docker镜像的方式是直接通过Maven或Gradle插件使用构建包(buildpacks)。如果你曾经使用过Cloud Foundry或Heroku等应用程序平台,那么你可能已经使用过构建包。构建包是平台的一部分,它负责将你的应用程序转换为平台可以实际运行的程序。例如,Cloud Foundry的Java构建包会注意到你正在推送一个.jar文件,并自动添加相关的JRE。

通过Cloud Native Buildpacks,你可以创建与Docker兼容的镜像,可以在任何地方运行。Spring Boot直接为Maven和Gradle提供了构建包支持。这意味着你只需输入一个命令,就可以快速将合理的镜像推送到本地运行的Docker守护程序。

注意:Paketo Spring Boot构建包支持layers.idx文件,因此对该文件进行的任何自定义都将在构建包创建的镜像中反映出来。

注意:为了实现可重复构建和容器镜像缓存,构建包可以操作应用程序资源的元数据(如文件的“最后修改”信息)。你应该确保你的应用程序在运行时不会依赖这些元数据。Spring Boot在提供静态资源时可以使用这些信息,但这可以通过spring.web.resources.cache.use-last-modified来禁用。

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值