终结器

Finalizer 是命名空间键,它告诉 Kubernetes 在完全删除标记为删除的资源之前,等待满足特定条件。Finalizer 通知控制器清理被删除对象拥有的资源。

当你告诉 Kubernetes 删除一个为其指定了 finalizer 的对象时,Kubernetes API 通过填充 .metadata.deletionTimestamp 来标记该对象为待删除,并返回 202 状态码(HTTP“已接受”)。目标对象在控制平面或其他组件执行 finalizer 定义的操作时保持在终止状态。这些操作完成后,控制器会从目标对象中删除相关的 finalizer。当 metadata.finalizers 字段为空时,Kubernetes 认为删除已完成并删除该对象。

你可以使用 finalizer 来控制资源的垃圾收集。例如,你可以定义一个 finalizer,以便在控制器删除目标资源之前清理相关的资源或基础设施。

你可以使用 finalizer 来控制垃圾收集对象,方式是通知控制器在删除目标资源之前执行特定的清理任务。

Finalizer 通常不指定要执行的代码。相反,它们通常是特定资源上类似于注解的键列表。Kubernetes 会自动指定一些 finalizer,但你也可以指定自己的 finalizer。

Finalizer 的工作原理

当你使用清单文件创建资源时,你可以在 metadata.finalizers 字段中指定 finalizer。当你尝试删除资源时,处理删除请求的 API 服务器会注意到 finalizers 字段中的值,并执行以下操作:

  • 修改对象,添加一个 metadata.deletionTimestamp 字段,其中包含你开始删除的时间。
  • 阻止删除该对象,直到其 metadata.finalizers 字段中的所有项都被移除。
  • 返回 202 状态码(HTTP“已接受”)。

管理该 finalizer 的控制器会注意到对对象的更新,其中设置了 metadata.deletionTimestamp,表明已请求删除该对象。然后,控制器会尝试满足为该资源指定的 finalizer 的要求。每次满足一个 finalizer 条件时,控制器都会从资源的 finalizers 字段中删除该键。当 finalizers 字段为空时,具有 deletionTimestamp 字段设置的对象会自动删除。你还可以使用 finalizer 来阻止删除非托管资源。

一个常见的 finalizer 示例是 kubernetes.io/pv-protection,它可以防止意外删除 PersistentVolume 对象。当一个 PersistentVolume 对象被 Pod 使用时,Kubernetes 会添加 pv-protection finalizer。如果你尝试删除 PersistentVolume,它会进入 Terminating 状态,但控制器无法删除它,因为 finalizer 存在。当 Pod 停止使用 PersistentVolume 时,Kubernetes 会清除 pv-protection finalizer,然后控制器会删除该卷。

所有者引用、标签和 finalizer

标签一样,所有者引用描述了 Kubernetes 中对象之间的关系,但用途不同。当一个控制器管理诸如 Pod 之类的对象时,它会使用标签来跟踪相关对象组的更改。例如,当Job 创建一个或多个 Pod 时,Job 控制器会将标签应用于这些 Pod,并跟踪集群中具有相同标签的任何 Pod 的更改。

Job 控制器还会将所有者引用添加到这些 Pod,指向创建 Pod 的 Job。如果在这些 Pod 运行时删除 Job,Kubernetes 会使用所有者引用(而不是标签)来确定集群中哪些 Pod 需要清理。

当 Kubernetes 识别出要删除的资源上的所有者引用时,也会处理 finalizer。

在某些情况下,finalizer 可能会阻止删除依赖对象,这可能会导致目标所有者对象在未被完全删除的情况下保留的时间比预期的长。在这些情况下,你应该检查目标所有者对象和依赖对象上的 finalizer 和所有者引用,以找出原因。

下一步

上次修改时间:2023 年 8 月 14 日上午 11:26 PST:更新 Finalizer 信息 (5f8e3d7e2c)