可以通过将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
文件:
- "dependencies":
- BOOT-INF/lib/library1.jar
- BOOT-INF/lib/library2.jar
- "spring-boot-loader":
- org/springframework/boot/loader/JarLauncher.class
- org/springframework/boot/loader/jar/JarEntry.class
- "snapshot-dependencies":
- BOOT-INF/lib/library3-SNAPSHOT.jar
- "application":
- META-INF/MANIFEST.MF
- BOOT-INF/classes/a/b/C.class
此分层旨在根据应用程序构建之间更改的可能性来分离代码。库代码不太可能在内部版本之间进行更改,因此将其放置在自己的层中,以允许工具重新使用缓存中的层。应用程序代码更可能在内部版本之间进行更改,因此将其隔离在单独的层中。
对于Maven,请参阅分层包装罐部分以获取有关在jar中添加层索引的更多详细信息。对于Gradle,请参阅Gradle插件文档的包装分层jar部分。
31.1.2 编写Dockerfile
创建包含图层索引文件的spring-boot-jarmode-layertools
jar时,该jar将作为依赖项添加到jar中。将此jar放在类路径上后,您可以在特殊模式下启动应用程序,该模式允许引导程序代码运行与应用程序完全不同的内容,例如提取层的内容。
该layertools 模式不能与包含启动脚本的完全可执行的Spring Boot存档一起使用。构建旨在与一起使用的jar文件时,请禁用启动脚本配置layertools 。 |
|
---|---|
您可以通过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中。这是使用的Dockerfile的示例jarmode
。
FROM adoptopenjdk:11-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM adoptopenjdk:11-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
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。你可以使用一些组合unzip
和mv
事物向右移动层,但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与Maven和Gradle一起使用。