如果containerd不再使用某种资源,它会把它删除回收。客户端在整个周期内会确保创建的资源在使用中或者具有租约,否则就会被考虑智能地删除。go客户端内置了准确跟踪和租赁资源的行为。不过租约的生命周期是库使用者来负责。containerd守护程序具有严格的资源管理能力来回收无用的资源。
什么是租约?
租约是一种containerd中由客户端创建的一种被用来引用其他资源如快照和内容的资源。 租约可以配置过期时间,一旦操作完成后会被客户端删除。虽然某个资源现在看起来没有被使用,但租约会告知containerd守护程序它在客户端完成操作后的某个时间被用到。
如何使用租约
使用go客户端
使用租约的最佳方式是当上下文被创建后马上把它添加进去。正常情况下它的寿命和上下文的生命周期相同。
.go
ctx, done, err := client.WithLease(ctx)
if err != nil {
return err
}
defer done(ctx)
这会创建租赁,该租约将会延迟删除并具有默认24小时内到期(如果该过程在延期之前死亡)。对于大多数用例,这已经足够了,不需要再做其他考量。但是,当然也支持再复杂点的使用场景。
如果程序或租约的预期寿命较长,则可直接使用租约管理器,而不必使用非常简单的 client.WithLease
,而是直接使用租约管理器。 这也允许在租约上设置自定义标签或操作其资源。 使用client.LeasesService()
可获得一个租约管理器 可用于创建、列出和删除租约,以及管理该租约的 租赁的引用资源。
.go
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
}
使用 gRPC
租约不是 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.<snapshotter> |
<identifier> |
Content, Snapshots | 资源引用快照器 <snapshotter> 的给定快照 <identifier> |
containerd.io/gc.ref.content |
digest | Content, Snapshots, Images, Containers | 资源引用给定的内容 Blob |
containerd.io/gc.ref.content.<user defined> |
digest | Content, Snapshots, Images, Containers | 资源使用 <user defined> 标签键引用给定的内容 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" | 守护进程启动后运行初始垃圾回收之前的延迟时间。它应在其他启动进程完成后运行,在此延迟之前不能安排任何垃圾回收。 |
默认配置表示如下:
.toml
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
的 删除。