缓存存储后端

为了确保快速构建,BuildKit 自动将其构建结果缓存到自己的内部缓存中。此外,BuildKit 还支持将构建缓存导出到外部位置,以便在未来的构建中可以导入。

在CI/CD构建环境中,外部缓存几乎变得必不可少。这样的环境通常在运行之间几乎没有持久性,但仍然尽可能保持镜像构建的运行时间尽可能低是非常重要的。

默认的 docker 驱动程序支持 inlinelocalregistrygha 缓存后端,但前提是你已经启用了 containerd 镜像存储。 其他缓存后端需要你选择不同的 驱动程序

警告

如果您在构建过程中使用秘密或凭证,请确保使用专用的 --secret 选项 来操作它们。 手动使用 COPYARG 管理秘密可能会导致凭证泄露。

后端

Buildx 支持以下缓存存储后端:

  • inline: 将构建缓存嵌入到镜像中。

    内联缓存被推送到与主输出结果相同的位置。 这仅适用于 image exporter

  • registry: 将构建缓存嵌入到一个单独的镜像中,并推送到与主输出分离的专用位置。

  • local: 将构建缓存写入文件系统上的本地目录。

  • gha: 将构建缓存上传到 GitHub Actions 缓存 (测试版).

  • s3: 将构建缓存上传到一个 AWS S3 存储桶(未发布)。

  • azblob: 将构建缓存上传到 Azure Blob Storage (未发布)。

命令语法

要使用任何缓存后端,首先需要在构建时使用 --cache-to 选项 将缓存导出到您选择的存储后端。然后,使用 --cache-from 选项 将缓存从存储后端导入到当前构建中。与本地 BuildKit 缓存(始终启用)不同,所有缓存存储后端都必须显式导出和显式导入。

示例 buildx 命令使用 registry 后端,使用导入和导出缓存:

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>[,parameters...] \
  --cache-from type=registry,ref=<registry>/<cache-image>[,parameters...] .

警告

作为一般规则,每个缓存都会写入某个位置。如果没有覆盖先前缓存的数据,则不能两次写入同一位置。如果您想维护多个作用域的缓存(例如,每个Git分支的缓存),请确保为导出的缓存使用不同的位置。

多个缓存

BuildKit 目前仅支持 单个缓存导出器。但你可以从任意数量的远程缓存中导入。例如,常见的模式是同时使用当前分支和主分支的缓存。以下示例展示了如何使用注册表缓存后端从多个位置导入缓存:

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>:<branch> \
  --cache-from type=registry,ref=<registry>/<cache-image>:<branch> \
  --cache-from type=registry,ref=<registry>/<cache-image>:main .

配置选项

本节描述了生成缓存导出时可用的一些配置选项。这里描述的选项至少适用于两种或更多后端类型。此外,不同的后端类型也支持特定的参数。有关适用于哪些配置参数的更多信息,请参阅每种后端类型的详细页面。

这里描述的常见参数有:

缓存模式

在生成缓存输出时,--cache-to 参数接受一个 mode 选项,用于定义在导出的缓存中包含哪些层。除了 inline 缓存外,所有缓存后端都支持此功能。

模式可以设置为以下两种选项之一:mode=minmode=max。例如,使用注册表后端以mode=max构建缓存:

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,mode=max \
  --cache-from type=registry,ref=<registry>/<cache-image> .

此选项仅在导出缓存时设置,使用--cache-to。当导入缓存(--cache-from)时,相关参数会自动检测。

min缓存模式(默认)中,只有导出到结果图像中的图层会被缓存,而在max缓存模式中,所有图层都会被缓存,包括中间步骤的图层。

虽然min缓存通常较小(这可以加快导入/导出时间,并减少存储成本),但max缓存更有可能获得更多的缓存命中。根据构建的复杂性和位置,您应该尝试这两个参数,以找到最适合您的结果。

缓存压缩

缓存压缩选项与 导出器压缩选项相同。这是 由localregistry缓存后端支持的。

例如,使用zstd压缩来压缩registry缓存:

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,compression=zstd \
  --cache-from type=registry,ref=<registry>/<cache-image> .

OCI 媒体类型

缓存OCI选项与 导出器OCI选项相同。这些选项由 localregistry 缓存后端支持。

例如,要导出OCI媒体类型缓存,请使用oci-mediatypes属性:

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,oci-mediatypes=true \
  --cache-from type=registry,ref=<registry>/<cache-image> .

此属性仅在带有--cache-to标志时才有意义。当获取缓存时,BuildKit 将自动检测要使用的正确媒体类型。

默认情况下,OCI 媒体类型会为缓存镜像生成一个镜像索引。 一些 OCI 注册表,如 Amazon ECR,不支持镜像索引媒体类型:application/vnd.oci.image.index.v1+json。如果您将缓存镜像导出到 ECR 或任何其他不支持镜像索引的注册表,请将 image-manifest 参数设置为 true,以生成单个镜像清单而不是缓存镜像的镜像索引:

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,oci-mediatypes=true,image-manifest=true \
  --cache-from type=registry,ref=<registry>/<cache-image> .