构建垃圾回收

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

确切的算法和配置策略的方式略有不同,具体取决于您使用的构建器类型。有关更多详细信息,请参阅配置

配置

注意

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

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

Docker 守护进程配置文件

如果您使用的是默认的 `docker` 驱动程序,GC 在 `daemon.json` 配置文件中配置,或者如果您使用 Docker Desktop,则在 **设置 > 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 应用于缓存的磁盘空间阈值:

选项描述默认值
reservedSpace(保留空间)BuildKit 允许为缓存分配的最小磁盘空间量。低于此阈值的使用量在垃圾回收期间不会被回收。总磁盘空间的 10% 或 10GB(以较低者为准)
maxUsedSpace(最大已用空间)BuildKit 允许使用的最大磁盘空间量。超出此阈值的使用量将在垃圾回收期间被回收。总磁盘空间的 60% 或 100GB(以较低者为准)
minFreeSpace(最小可用空间)必须保留的可用磁盘空间量。20GB

您可以将这些选项设置为字节数、单位字符串(例如,`512MB`),或总磁盘大小的百分比。更改这些选项会影响 BuildKit worker 使用的默认 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` 在定义构建缓存大小下限方面具有最高优先级。如果 `maxUsedSpace` 或 `minFreeSpace` 会定义较低的值,则最小缓存大小永远不会低于 `reservedSpace`。

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

您还可以定义完全自定义的 GC 策略。自定义策略还允许您定义过滤器,让您能够精确指定给定策略可以清除的缓存条目类型。

BuildKit 中的自定义 GC 策略

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

要定义自定义 GC 策略,请在 `buildkitd.toml` 中使用 `[[worker.oci.gcpolicy]]` 配置块。每个策略定义将用于该策略的阈值。如果您使用自定义策略,则 `reservedSpace`、`maxUsedSpace` 和 `minFreeSpace` 的全局值将不适用。

这是一个示例配置:

# 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"

除了 `reservedSpace`、`maxUsedSpace` 和 `minFreeSpace` 阈值之外,在定义 GC 策略时,您还有两个额外的配置选项:

  • `all`:默认情况下,BuildKit 会将某些缓存记录排除在 GC 期间的清除之外。将此选项设置为 `true` 将允许清除任何缓存记录。
  • `filters`:过滤器允许您指定 GC 策略允许清除的特定类型的缓存记录。
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.