构建垃圾收集
虽然 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 策略大致如下:
- 如果缓存(例如来自本地目录或远程 Git 仓库的构建上下文,以及缓存挂载)超过 48 小时未使用,则将其删除,因为这些缓存可以轻松重新生成。
- 删除在构建中超过 60 天未使用的缓存。
- 删除超出构建缓存大小限制的非共享缓存。非共享缓存记录指的是未被其他资源(通常是镜像层)使用的层 blob。
- 删除超出构建缓存大小限制的任何构建缓存。
精确的算法和配置策略的方法因您使用的构建器类型而略有不同。有关详细信息,请参阅配置。
配置
注意
如果您对默认的垃圾收集行为感到满意,并且不需要微调其设置,可以跳过本节。默认配置适用于大多数用例,无需额外设置。
根据您使用的构建驱动类型,您将使用不同的配置文件来更改构建器的 GC 设置:
- 如果您使用 Docker Engine 的默认构建器(
docker
驱动),请使用Docker 守护进程配置文件。 - 如果您使用自定义构建器,请使用BuildKit 配置文件。
Docker 守护进程配置文件
如果您使用默认的 docker
驱动,GC 在 daemon.json
配置文件中配置;如果您使用 Docker Desktop,则在 Settings > 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 工作器使用的默认 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 策略允许修剪的特定类型的缓存记录。