高效容器图像
很容易地将 Spring Boot 的 uber jar 打包为 Docker 镜像。 然而,直接复制并运行 Docker 镜像中的 uber jar 存在多种缺点。 在不拆箱的情况下运行Uber Jar时,总会有一定的开销,在容器化环境中这会很明显。 另一个问题是,把应用的代码及其所有依赖放在 Docker 镜像的同一层并不是最优选择。 由于你可能比升级 Spring Boot 版本的频率更频繁地重新编译代码,通常更划分一些会更好。 如果你在应用类之前的层放jar文件,Docker通常只需修改最底层,就能从缓存中获取其他文件。
Docker镜像分层
为了简化创建优化的 Docker 镜像,Spring Boot 支持在 jar 中添加图层索引文件。 它列出了层数以及罐子中应包含的部分。 索引中的图层列表根据添加图层到Docker/OCI镜像的顺序排列。 开箱即用时,支持以下层:
-
依赖(适用于常规发布依赖) -
Spring Boot加载器(对于以下所有内容org/springframework/boot/loader) -
快照依赖关系(针对快照依赖) -
应用(用于应用类和资源)
以下展示了一个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 还支持通过layers.idx.
关于Maven,请参见包装分层罐或战争部分,了解更多关于如何为档案添加图层索引的细节。 关于 Gradle,请参见 Gradle 插件文档中的分层罐子或战争包装部分。