首页 > 解决方案 > 为什么 paketobuildpacks/run image download 每次

问题描述

这是一个springboot gradle项目。我的构建命令是

pack build test_boot \
--builder paketobuildpacks/builder:base \
--env BP_JVM_VERSION=8

像这样的消息:

base: Pulling from paketobuildpacks/builder
Digest: sha256:0ea77b1be8d415639a36cc476c515bb492bf2a35274da4686caddbd897059b44
Status: Image is up to date for paketobuildpacks/builder:base
base-cnb: Pulling from paketobuildpacks/run
Digest: sha256:3bdefd40188e93e4aba93978440816f9b86d03a1a7b58e6c6c854bcb88df8ace
Status: Image is up to date for paketobuildpacks/run:base-cnb
===> DETECTING
8 of 18 buildpacks participating
paketo-buildpacks/ca-certificates       2.3.2
paketo-buildpacks/bellsoft-liberica     8.2.0
paketo-buildpacks/gradle                5.4.0
paketo-buildpacks/executable-jar        5.1.2
paketo-buildpacks/apache-tomcat         5.6.1
paketo-buildpacks/dist-zip              4.1.2
paketo-buildpacks/spring-boot           4.4.2
paketo-buildpacks/environment-variables 3.1.1

我发现它 paketobuildpacks/run每次都下载并且我的 CPU 运行很高。它也每次都下载gradle。

Downloading https://services.gradle.org/distributions/gradle-6.8.3-all.zip
...............................................................................................................................................

Welcome to Gradle 6.8.3!

这使得部署过程非常缓慢,我该怎么办?

标签: dockerbuildpack

解决方案


base: Pulling from paketobuildpacks/builder
Digest: sha256:0ea77b1be8d415639a36cc476c515bb492bf2a35274da4686caddbd897059b44
Status: Image is up to date for paketobuildpacks/builder:base
base-cnb: Pulling from paketobuildpacks/run
Digest: sha256:3bdefd40188e93e4aba93978440816f9b86d03a1a7b58e6c6c854bcb88df8ace
Status: Image is up to date for paketobuildpacks/run:base-cnb

这实际上不是下载。它正在检查它是否有最新的,这是默认行为。您可以使用--pull-policy标志来控制它pack build。它默认为always,但也可以设置为neverif-not-present

如果我连续进行大量构建,我更喜欢if-not-present,因为我已经知道我有最新的图像,这将跳过检查最新版本的速度稍微快一点。

我不使用--never,虽然它会达到相同的结果,但我觉得这有点烦人,因为如果我更改我正在使用的构建包并添加一个我没有在本地下载的新包,那么构建会失败,直到我可以记得切换标志或拉下丢失的图像。

在任何一种情况下,您都需要记住您正在设置此标志,而不是在您构建生产映像时使用它,您始终希望确保您拥有最新的基础映像。

它也每次都下载gradle。

这通常不应该发生。根据提供的信息,很难说是什么导致了这种情况,但这里是应该发生的事情的细分。

  1. 当你构建你的应用程序时,gradle buildpack 将执行 gradle 包装器(因为你有一个 Spring Boot 应用程序并且它默认使用包装器)。这就是你看到的输出。包装器正在运行,并且包装器通常应该每个版本只安装一次 gradle。

  2. 当你pack build第一次时,gradle buildpack 会执行 gradle wrapper,它会下载并安装 gradle。这应该会导致 gradle 位存储在缓存以供将来运行的层上。

  3. 安装 gradle 后,gradle buildpack 将构建您的应用程序并生成一个可执行的 JAR(因为它是一个 Spring Boot 应用程序)。这就是 gradle buildpack 的结束。

  4. 但这不是构建的结束。可执行的 JAR 和 Spring Boot 构建包然后运行并执行它们的任务。

  5. 当所有构建包成功完成后,生命周期将导出所有层(包括缓存层)。此时,您应该有一个可以运行的图像。

  6. 如果您pack build再次使用相同的图像名称,pack 将进行一些分析并定位您之前运行的图像和缓存层。它将恢复这些,当 gradle buildpack 运行 gradle 包装器时,包装器将看到以前构建的文件,并且不应下载任何新文件。

可能会意外重新下载的潜在原因:

  1. 第一次构建没有完成。如前所述,缓存层在完整pack build完成之前不会保存。如果初始构建的任何部分失败,则不会保存缓存的层,并且运行后续构建将重新下载 gradle。这是 buildpacks 的一个已知限制,在我写这篇文章时正在处理中。

  2. 更改图像名称。如果您pack build使用不同的图像名称执行后续操作,那基本上就像进行新构建一样。缓存图像层的范围是图像,这取决于您设置的图像名称。更改名称(例如,如果您的图像名称中有提交哈希或日期)将导致缓存性能不佳。

  3. Gradle 的版本发生了变化,因此包装器合法地需要安装新版本的 Gradle(听起来不是这样)。

  4. 可能还有其他事情。如果您使用运行初始输出的完整输出pack build以及pack build不缓存下载的后续输出更新您的帖子,这将有助于确定更多关于正在发生的事情。


推荐阅读