跳到主要内容
版本:3.5.10

高效的容器镜像

QWen Max 中英对照 Efficient Container Images

将 Spring Boot 的 uber jar 轻松打包为 Docker 镜像是完全可行的。然而,直接将 uber jar 复制到 Docker 镜像中并原样运行存在一些缺点。在不进行解包的情况下运行 uber jar 总会带来一定程度的开销,在容器化环境中这种开销可能尤为明显。另一个问题是,将应用程序代码及其所有依赖项放在 Docker 镜像的同一层中并非最优做法。由于你重新编译代码的频率通常高于升级所使用的 Spring Boot 版本的频率,因此将这些内容进一步分离通常是更好的选择。如果你将 jar 文件放在应用程序类所在的层之前,Docker 通常只需更改最底层,而可以从缓存中复用其他层。

分层 Docker 镜像

为了更轻松地创建优化的 Docker 镜像,Spring Boot 支持在 JAR 文件中添加一个层索引文件(layer index file)。该文件提供了一个层列表,以及 JAR 中应包含在各层中的部分。索引中的层列表按照这些层应被添加到 Docker/OCI 镜像中的顺序进行排序。开箱即用(out-of-the-box),以下层受到支持:

  • 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 还借助 layers.idx 文件支持 war 文件的分层。

对于 Maven,有关在归档文件中添加层索引的更多详情,请参阅 分层打包 JAR 或 WAR 文件部分。对于 Gradle,请参阅 Gradle 插件文档中的 分层打包 JAR 或 WAR 文件部分