高效容器镜像
将 Spring Boot uber jar 打包为 Docker 镜像非常容易。 但如果直接将 uber jar 拷贝并运行在 Docker 镜像中,会有一些缺点。 在容器化环境下,未解包的 uber jar 运行总有一定的开销,这种开销可能会被感知到。 另一个问题是,如果将应用代码和所有依赖都放在 Docker 镜像的同一层,这并不理想。 通常你会比升级 Spring Boot 版本更频繁地重新编译代码,因此最好将内容进一步分离。 如果你将 jar 文件放在应用类之前的层,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
这种分层旨在根据应用构建间的变更概率分离代码。 库代码在构建间变更较少,因此单独分层以便工具复用缓存。 应用代码更易变更,因此单独隔离在一层。
Spring Boot 也支持 war 文件分层,只需添加 layers.idx
。
Maven 用户请参见 分层 jar 或 war 打包章节 了解如何向归档添加分层索引。 Gradle 用户请参见 Gradle 插件文档中的分层 jar 或 war 打包章节。