构建垃圾回收
虽然 docker builder prune 或 docker buildx prune 命令会立即运行,但垃圾回收 (GC) 会定期运行并遵循有序的清除策略列表。当缓存大小变得太大或缓存过期时,BuildKit 守护进程会清除构建缓存。
对于大多数用户来说,默认的 GC 行为已足够,无需任何干预。高级用户,特别是那些处理大规模构建、自管理构建器或受限存储环境的用户,可能会受益于自定义这些设置,以更好地适应其工作流程需求。以下部分将解释 GC 的工作原理,并提供通过自定义配置调整其行为的指导。
垃圾回收策略
GC 策略定义了一组规则,用于确定如何管理和清理构建缓存。这些策略包括何时删除缓存条目的标准,例如缓存的年龄、使用的空间量以及要清除的缓存记录类型。
每个 GC 策略都会按顺序评估,从最具体的标准开始,如果之前的策略未能释放足够的缓存,则会继续执行更广泛的规则。这使得 BuildKit 能够优先处理缓存条目,在保留最有价值的缓存的同时,确保系统保持性能和可用性。
例如,假设您有以下 GC 策略:
- 查找过去 48 小时内未使用的“陈旧”缓存记录,并删除记录,直到“陈旧”缓存最多剩下 5GB。
- 如果构建缓存大小超过 10GB,请删除记录,直到总缓存大小不超过 10GB。
第一条规则更具体,优先处理陈旧缓存记录,并为价值较低的缓存类型设置较低的限制。第二条规则施加了适用于任何类型缓存记录的更高硬限制。有了这些策略,如果您有 11GB 的构建缓存,其中:
- 其中 7GB 是“陈旧”缓存
- 4GB 是其他更有价值的缓存
GC 清理将删除 5GB 的陈旧缓存作为第一个策略的一部分,剩余 6GB,这意味着第二个策略不需要清除更多缓存。
默认 GC 策略(大致)为:
- 如果缓存已超过 48 小时未使用,则删除可以轻松重新生成的缓存,例如来自本地目录或远程 Git 存储库的构建上下文以及缓存挂载。
- 删除 60 天以上未在构建中使用的缓存。
- 删除超出构建缓存大小限制的非共享缓存。非共享缓存记录是指未被其他资源(通常是作为镜像层)使用的层 blob。
- 删除超出构建缓存大小限制的任何构建缓存。
确切的算法和配置策略的方式略有不同,具体取决于您使用的构建器类型。有关更多详细信息,请参阅配置。
配置
注意如果您对默认的垃圾回收行为感到满意,并且不需要微调其设置,则可以跳过此部分。默认配置适用于大多数用例,无需额外设置。
根据您使用的构建驱动程序类型,您将使用不同的配置文件来更改构建器的 GC 设置:
- 如果您使用 Docker Engine 的默认构建器(`docker` 驱动程序),请使用Docker 守护进程配置文件。
- 如果您使用自定义构建器,请使用BuildKit 配置文件。
Docker 守护进程配置文件
如果您使用的是默认的 `docker` 驱动程序,GC 在 `daemon.json` 配置文件中配置,或者如果您使用 Docker Desktop,则在 **设置 > Docker Engine** 中配置。
以下代码片段显示了 Docker Desktop 用户 `docker` 驱动程序的默认构建器配置:
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
}
}`defaultKeepStorage` 选项配置构建缓存的大小限制,这会影响 GC 策略。 `docker` 驱动程序的默认策略工作方式如下:
- 如果瞬时、未使用的构建缓存超过 `defaultKeepStorage` 的 13.8% 或至少 512MB 并且已超过 48 小时,则将其删除。
- 删除 60 天以上未使用的构建缓存。
- 删除超出 `defaultKeepStorage` 限制的非共享构建缓存。
- 删除超出 `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 配置,包含以下策略:
- 如果构建缓存超过 50GB,则删除超过 1440 小时(即 60 天)未使用的缓存条目。
- 如果构建缓存超过 50GB,则删除非共享缓存条目。
- 如果构建缓存超过 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 策略允许清除的特定类型的缓存记录。