如果containerd不再使用某种资源,它会把它删除回收。客户端在整个周期内会确保创建的资源在使用中或者具有租约,否则就会被考虑智能地删除。go客户端内置了准确跟踪和租赁资源的行为。不过租约的生命周期是库使用者来负责。containerd守护程序具有严格的资源管理能力来回收无用的资源。
租约是一种containerd中由客户端创建的一种被用来引用其他资源如快照和内容的资源。
租约可以配置过期时间,一旦操作完成后会被客户端删除。虽然某个资源现在看起来没有被使用,但租约会告知containerd守护程序它在客户端完成操作后的某个时间被用到。
使用租约的最佳方式是当上下文被创建后马上把它添加进去。正常情况下它的寿命和上下文的生命周期相同。
ctx, done, err := client.WithLease(ctx)
if err != nil {
return err
}
defer done(ctx)
这会创建租赁,该租约将会延迟删除并具有默认24小时内到期(如果该过程在延期之前死亡)。对于大多数用例,这已经足够了,不需要再做其他考量。但是,当然也支持再复杂点的使用场景。
如果程序或租约的预期寿命较长,则可直接使用租约管理器,而不必使用非常简单的 client.WithLease
,而是直接使用租约管理器。这也允许在租约上设置自定义标签或操作其资源。使用client.LeasesService()
可获得一个租约管理器可用于创建、列出和删除租约,以及管理该租约的租赁的引用资源。
manager := client.LeasesService()
// 此租约永不过期
// 使用 `leases.WithExpiration` 使其过期
// 使用 `leases.WithLabels` 应用任何标签
l, err := manager.Create(ctx, leases.WithRandomID())
if err != nil {
return err
}
// 更新当前上下文以添加租约
ctx = leases.WithLease(ctx, l.ID)
// 做点什么,租约将被使用...
// 随时删除租约,或跟踪租约以便稍后删除
if err := ls.Delete(ctx, l); err != nil {
return err
}
租约不是 API 中的明确字段(当然,租约服务),而是任何 API 服务都可以使用的可选字段。租约可以使用 gRPC header在任何 gRPC 服务端点上设置。设置
gRPC 头信息 containerd-lease
设置为租赁标识符,API服务将在该租期上下文中运行。
要管理租期的创建和删除,请使用租期 gRPC 服务。
垃圾回收通过两种不同方式定义资源之间的关系即通过特定类型的资源属性和资源标签。特定类型的属性不需要用户管理,因为它们是资源自然结构的一部分(例如,容器的快照、快照的父节点、镜像的目标节点、资源的父节点等)。但是,资源可能具有不是由containerd而是通过客户端来定义的关系。例如,一个 OCI镜像有一个清单,其中引用了配置文件和层 tars。这些资源以通用 blob 的形式存储在containerd
中。了解这些 blob 之间的关系,并使用内容资源上的标签来设置它们。
资源标签还可用于提示垃圾回收器其他属性,如过期、对象是否应在没有任何操作的情况下保留等,或限制引用的内容。
支持的垃圾回收标签有:
标签键 | 标签值 | 支持的资源 | 描述 |
---|---|---|---|
containerd.io/gc.root |
nonempty | Content, Snapshots | 保留此对象及其引用的任何内容。(客户端可将其设置为 rfc3339 时间戳,以表明该值的设置时间,但垃圾回收器不会解析该值) |
containerd.io/gc.ref.snapshot. |
|
Content, Snapshots | 资源引用快照器 的给定快照
|
containerd.io/gc.ref.content |
digest | Content, Snapshots, Images, Containers | 资源引用给定的内容 Blob |
containerd.io/gc.ref.content. |
digest | Content, Snapshots, Images, Containers | 资源使用 标签键引用给定的内容 Blob |
containerd.io/gc.expire |
timestamp formatted as rfc3339 | Leases | 租约何时过期。过期后,垃圾回收器将删除租约。 |
containerd.io/gc.flat |
nonempty | Leases | 忽略租用资源的标签引用。这只适用于源于租用的引用,如果租用资源在其他地方被引用,则将使用其标签引用。 |
垃圾回收器 (gc) 是在后台程序中调度的,根据一系列可配置的因素运行。默认情况下,垃圾回收器将会尝试在 98% 的提前计算的锁定时间内保持数据库未锁定状态。另外,默认情况下,如果没有删除或每 100 次写入数据库后,垃圾回收器不会进行调度。
垃圾回收调度程序会将数据库锁定的时间视为暂停时间。当资源被删除时,例如清理快照可能会很慢。调度程序只会在整个垃圾回收完成后才进行调度,但会使用平均暂停时间来确定下一次运行尝试的时间。
垃圾收集可通过 containerd
守护进程的配置文件进行配置,通常位于 /etc/containerd/config.toml
。该配置在 scheduler
插件下。
配置 | 默认值 | 描述 |
---|---|---|
pause_threshold |
0.02 | 表示根据平均暂停时间调度 gc 的最大时间量。最大值为 0.5(50%),以防止过度调度。 |
deletion_threshold |
0 | 立即触发 gc 的删除次数阈值。0 表示删除次数不会触发 gc,但删除次数将确保下一次计划的 gc 运行。 |
mutation_threshold |
100 | 在给定数据库突变次数后运行 gc 的阈值。注意,任何执行删除的突变都会导致运行 gc,这种情况下会处理更罕见的事件,如标签引用删除。 |
schedule_delay |
“0ms” | 触发事件与运行 gc 之间的延迟。当突变可能迅速爆发时,可以使用非零值。 |
startup_delay |
“100ms” | 守护进程启动后运行初始垃圾回收之前的延迟时间。它应在其他启动进程完成后运行,在此延迟之前不能安排任何垃圾回收。 |
默认配置表示如下:
version = 2
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
pause_threshold = 0.02
deletion_threshold = 0
mutation_threshold = 100
schedule_delay = "0ms"
startup_delay = "100ms"
除了通过调度程序进行垃圾回收外,客户端还可以在删除资源时请求垃圾回收。在这种情况下垃圾收集将被立即调度(或在 schedule_delay
配置为非零时,在 schedule_delay
之后)。在垃圾收集完成之前,服务不会返回。目前支持删除镜像和租约。使用 images.SynchronousDelete()
用于 images.Store
的删除和
leases.SynchronousDelete
用于 leases.Manager
的删除。