构建垃圾收集

虽然 docker builder prunedocker buildx prune 命令会立即运行,但垃圾收集 (GC) 会定期运行,并遵循有序的修剪策略列表。BuildKit 守护进程会在缓存大小过大或缓存过期时清除构建缓存。

对于大多数用户,默认的 GC 行为已足够,无需任何干预。高级用户,尤其是那些进行大规模构建、自管理构建器或存储空间受限环境的用户,可能会受益于自定义这些设置,以更好地配合其工作流需求。以下章节解释了 GC 如何工作,并提供了通过自定义配置调整其行为的指导。

垃圾收集策略

GC 策略定义了一组规则,用于确定如何管理和清理构建缓存。这些策略包括何时移除缓存条目的标准,例如缓存的年龄、使用的空间量以及要修剪的缓存记录类型。

每个 GC 策略按顺序评估,从最具体的标准开始,如果先前的策略没有释放足够的缓存,则继续执行更广泛的规则。这让 BuildKit 能够优先处理缓存条目,保留最有价值的缓存,同时确保系统保持性能和可用性。

例如,假设您有以下 GC 策略:

  1. 查找在过去 48 小时内未使用的“陈旧”缓存记录,并删除记录直到剩余的“陈旧”缓存不超过 5GB。
  2. 如果构建缓存大小超过 10GB,删除记录直到总缓存大小不超过 10GB。

第一个规则更具体,优先处理陈旧缓存记录并为价值较低的缓存类型设置较低限制。第二个规则强制执行适用于任何类型缓存记录的较高硬限制。有了这些策略,如果您有 11GB 的构建缓存,其中

  • 7GB 是“陈旧”缓存
  • 4GB 是其他更有价值的缓存

GC 清扫将根据第一条策略删除 5GB 的陈旧缓存,剩余 6GB,这意味着第二条策略不需要清除更多缓存。

默认的 GC 策略大致如下:

  1. 如果缓存(例如来自本地目录或远程 Git 仓库的构建上下文,以及缓存挂载)超过 48 小时未使用,则将其删除,因为这些缓存可以轻松重新生成。
  2. 删除在构建中超过 60 天未使用的缓存。
  3. 删除超出构建缓存大小限制的非共享缓存。非共享缓存记录指的是未被其他资源(通常是镜像层)使用的层 blob。
  4. 删除超出构建缓存大小限制的任何构建缓存。

精确的算法和配置策略的方法因您使用的构建器类型而略有不同。有关详细信息,请参阅配置

配置

注意

如果您对默认的垃圾收集行为感到满意,并且不需要微调其设置,可以跳过本节。默认配置适用于大多数用例,无需额外设置。

根据您使用的构建驱动类型,您将使用不同的配置文件来更改构建器的 GC 设置:

Docker 守护进程配置文件

如果您使用默认的 docker 驱动,GC 在 daemon.json 配置文件中配置;如果您使用 Docker Desktop,则在 Settings > Docker Engine 中配置。

以下片段显示了 Docker Desktop 用户使用 docker 驱动时的默认构建器配置:

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  }
}

defaultKeepStorage 选项配置了构建缓存的大小限制,这会影响 GC 策略。docker 驱动的默认策略工作方式如下:

  1. 如果超出 defaultKeepStorage 的 13.8%(或至少 512MB),则移除超过 48 小时未使用的临时构建缓存。
  2. 移除超过 60 天未使用的构建缓存。
  3. 移除超出 defaultKeepStorage 限制的非共享构建缓存。
  4. 移除超出 defaultKeepStorage 限制的任何构建缓存。

考虑到 Docker Desktop 的 defaultKeepStorage 默认值为 20GB,默认 GC 策略解析为:

{
  "builder": {
    "gc": {
      "enabled": true,
      "policy": [
        {
          "keepStorage": "2.764GB",
          "filter": [
            "unused-for=48h",
            "type==source.local,type==exec.cachemount,type==source.git.checkout"
          ]
        },
        { "keepStorage": "20GB", "filter": ["unused-for=1440h"] },
        { "keepStorage": "20GB" },
        { "keepStorage": "20GB", "all": true }
      ]
    }
  }
}

调整 docker 驱动的构建缓存配置最简单的方法是调整 defaultKeepStorage 选项:

  • 如果您觉得 GC 过于激进,请增加限制。
  • 如果您需要保留空间,请减少限制。

如果您需要更多的控制,可以直接定义自己的 GC 策略。以下示例定义了一个更保守的 GC 配置,包含以下策略:

  1. 如果构建缓存超过 50GB,则移除超过 1440 小时(即 60 天)未使用的缓存条目。
  2. 如果构建缓存超过 50GB,则移除非共享缓存条目。
  3. 如果构建缓存超过 100GB,则移除任何缓存条目。
{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "50GB",
      "policy": [
        { "keepStorage": "0", "filter": ["unused-for=1440h"] },
        { "keepStorage": "0" },
        { "keepStorage": "100GB", "all": true }
      ]
    }
  }
}

这里的策略 1 和 2 将 keepStorage 设置为 0,这意味着它们将回退到 defaultKeepStorage 定义的 50GB 默认限制。

BuildKit 配置文件

对于除 docker 之外的构建驱动,GC 是使用 buildkitd.toml 配置文件进行配置的。此文件使用以下高级配置选项来调整 BuildKit 应使用的磁盘空间阈值:

选项描述默认值
reservedSpaceBuildKit 允许为缓存分配的最小磁盘空间量。使用量低于此阈值将不会在垃圾收集中回收。总磁盘空间的 10% 或 10GB(取较低者)
maxUsedSpaceBuildKit 允许使用的最大磁盘空间量。使用量高于此阈值将在垃圾收集中回收。总磁盘空间的 60% 或 100GB(取较低者)
minFreeSpace必须保留的可用磁盘空间量。20GB

您可以将这些选项设置为字节数、单位字符串(例如,512MB)或总磁盘大小的百分比。更改这些选项会影响 BuildKit 工作器使用的默认 GC 策略。使用默认阈值,GC 策略解析如下:

# Global defaults
[worker.oci]
  gc = true
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"
  minFreeSpace = "20%"

# Policy 1
[[worker.oci.gcpolicy]]
  filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout" ]
  keepDuration = "48h"
  maxUsedSpace = "512MB"

# Policy 2
[[worker.oci.gcpolicy]]
  keepDuration = "1440h" # 60 days
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"

# Policy 3
[[worker.oci.gcpolicy]]
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"

# Policy 4
[[worker.oci.gcpolicy]]
  all = true
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"

实际操作中,这意味着:

  • 策略 1:如果构建缓存超过 512MB,BuildKit 将删除超过 48 小时未使用的本地构建上下文、远程 Git 上下文和缓存挂载的缓存记录。
  • 策略 2:如果磁盘使用量超过 100GB,将删除超过 60 天的非共享构建缓存,确保至少保留 10GB 磁盘空间用于缓存。
  • 策略 3:如果磁盘使用量超过 100GB,将删除任何非共享缓存,确保至少保留 10GB 磁盘空间用于缓存。
  • 策略 4:如果磁盘使用量超过 100GB,将删除所有缓存——包括共享和内部记录——确保至少保留 10GB 磁盘空间用于缓存。

reservedSpace 在定义构建缓存大小下限方面具有最高优先级。如果 maxUsedSpaceminFreeSpace 定义了一个较低的值,则最小缓存大小永远不会低于 reservedSpace

如果同时设置了 reservedSpacemaxUsedSpace,则 GC 清扫后缓存大小将介于这些阈值之间。例如,如果 reservedSpace 设置为 10GB,maxUsedSpace 设置为 20GB,则 GC 运行后的缓存量将小于 20GB,但至少为 10GB。

您还可以定义完全自定义的 GC 策略。自定义策略还允许您定义过滤器,以便精确指定给定策略允许修剪的缓存条目类型。

BuildKit 中的自定义 GC 策略

自定义 GC 策略允许您微调 BuildKit 如何管理其缓存,并根据缓存类型、持续时间或磁盘空间阈值等标准,完全控制缓存保留。如果您需要完全控制缓存阈值以及如何优先处理缓存记录,定义自定义 GC 策略是最佳选择。

要定义自定义 GC 策略,请在 buildkitd.toml 中使用 [[worker.oci.gcpolicy]] 配置块。每个策略都定义了该策略将使用的阈值。如果您使用自定义策略,全局的 reservedSpacemaxUsedSpaceminFreeSpace 值将不适用。

以下是一个示例配置:

# Custom GC Policy 1: Remove unused local contexts older than 24 hours
[[worker.oci.gcpolicy]]
  filters = ["type==source.local"]
  keepDuration = "24h"
  reservedSpace = "5GB"
  maxUsedSpace = "50GB"

# Custom GC Policy 2: Remove remote Git contexts older than 30 days
[[worker.oci.gcpolicy]]
  filters = ["type==source.git.checkout"]
  keepDuration = "720h"
  reservedSpace = "5GB"
  maxUsedSpace = "30GB"

# Custom GC Policy 3: Aggressively clean all cache if disk usage exceeds 90GB
[[worker.oci.gcpolicy]]
  all = true
  reservedSpace = "5GB"
  maxUsedSpace = "90GB"

除了 reservedSpacemaxUsedSpaceminFreeSpace 阈值之外,在定义 GC 策略时,您还有两个额外的配置选项:

  • all:默认情况下,BuildKit 会在 GC 期间排除一些缓存记录不被修剪。将此选项设置为 true 将允许修剪任何缓存记录。
  • filters:过滤器允许您指定 GC 策略允许修剪的特定类型的缓存记录。
页面选项