终结器

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

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

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

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

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

Finalizer 的工作原理

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

  • 修改对象以添加一个 `metadata.deletionTimestamp` 字段,其中包含您开始删除的时间。
  • 阻止对象被移除,直到其 `metadata.finalizers` 字段中的所有条目都被移除。
  • 返回 `202` 状态码(HTTP "Accepted")。

管理该 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,然后控制器会删除该卷。

所有者引用、标签和终结器

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

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

当 Kubernetes 识别出目标删除资源上的所有者引用时,它还会处理终结器。

在某些情况下,终结器可能会阻止从属对象的删除,这可能导致目标所有者对象停留的时间比预期更长而未被完全删除。在这种情况下,您应该检查目标所有者和从属对象上的终结器和所有者引用,以排除故障。

下一步

上次修改时间:2025 年 4 月 27 日太平洋标准时间晚上 11:02:澄清自定义终结器名称必须是公开限定的终结器名称 (bbd9b90103)