终结器
终结器(Finalizers)是命名空间键,它们告诉 Kubernetes 等待满足特定条件后,再完全删除标记为删除的资源。终结器会提醒控制器清理被删除对象所拥有的资源。
当你告知 Kubernetes 删除一个指定了终结器的对象时,处理删除请求的 Kubernetes API 会通过设置 .metadata.deletionTimestamp
字段来标记对象待删除,并返回 202
状态码(HTTP "Accepted")。目标对象会保持在终止状态,直到控制平面或其他组件执行完由终结器定义的操作。这些操作完成后,控制器会从目标对象中移除相应的终结器。当 metadata.finalizers
字段为空时,Kubernetes 认为删除完成并删除该对象。
你可以使用终结器来控制资源的垃圾回收。例如,你可以定义一个终结器来在控制器删除目标资源之前清理相关的资源或基础设施。
你可以使用终结器来控制垃圾回收对象的过程,通过提醒控制器在删除目标资源之前执行特定的清理任务。
终结器通常不指定要执行的代码。相反,它们通常是特定资源上的键列表,类似于注解(annotations)。Kubernetes 会自动指定一些终结器,但你也可以指定自己的终结器。
终结器的工作原理
当你使用清单文件创建一个资源时,可以在 metadata.finalizers
字段中指定终结器。当你尝试删除该资源时,处理删除请求的 API 服务器会注意到 finalizers
字段中的值并执行以下操作:
- 修改对象以添加
metadata.deletionTimestamp
字段,并用你开始删除时的时间填充该字段。 - 阻止删除该对象,直到其
metadata.finalizers
字段中的所有项都被移除。 - 返回
202
状态码(HTTP "Accepted")。
管理该终结器的控制器会注意到对象的更新,特别是设置了 metadata.deletionTimestamp
字段,这表明已请求删除该对象。然后,控制器会尝试满足为该资源指定的终结器的要求。每次满足一个终结器条件时,控制器就会从资源的 finalizers
字段中移除该键。当 finalizers
字段清空时,设置了 deletionTimestamp
字段的对象会被自动删除。你还可以使用终结器来阻止非托管资源的删除。
一个常见的终结器例子是 kubernetes.io/pv-protection
,它阻止意外删除 PersistentVolume
对象。当一个 PersistentVolume
对象正在被 Pod 使用时,Kubernetes 会添加 pv-protection
终结器。如果你尝试删除该 PersistentVolume
,它会进入 Terminating
状态,但控制器无法删除它,因为终结器存在。当 Pod 停止使用该 PersistentVolume
时,Kubernetes 会清除 pv-protection
终结器,然后控制器会删除该卷。
注意
当你
DELETE
一个对象时,Kubernetes 会为该对象添加删除时间戳,然后立即开始限制对该对象(现处于待删除状态)的.metadata.finalizers
字段的更改。你可以移除现有的终结器(从finalizers
列表中删除一个条目),但不能添加新的终结器。一旦对象的deletionTimestamp
设置后,你也无法修改它。删除请求发出后,你无法恢复此对象。唯一的方法是删除它,然后创建一个新的相似对象。
所有者引用、标签和终结器
像标签一样,所有者引用(owner references)描述了 Kubernetes 中对象之间的关系,但用途不同。当控制器管理 Pods 等对象时,它使用标签来跟踪相关对象组的变化。例如,当一个Job创建一个或多个 Pod 时,Job 控制器会给这些 Pod 打上标签,并跟踪集群中任何带有相同标签的 Pod 的变化。
Job 控制器还会给这些 Pod 添加*所有者引用*,指向创建这些 Pod 的 Job。如果你在这些 Pod 正在运行时删除 Job,Kubernetes 会使用所有者引用(而不是标签)来确定集群中哪些 Pod 需要清理。
Kubernetes 在识别到目标删除资源上的所有者引用时,也会处理终结器。
在某些情况下,终结器会阻止依赖对象的删除,这可能导致目标所有者对象保留的时间比预期更长,而未能完全删除。在这种情况下,你应该检查目标所有者及其依赖对象上的终结器和所有者引用,以排除故障原因。
注意
如果对象卡在删除状态,避免手动删除终结器以让删除继续。终结器被添加到资源通常是有原因的,因此强制删除它们可能会导致集群出现问题。只有在理解了终结器的作用并通过其他方式(例如,手动清理某些依赖对象)完成了其目的后,才应该这样做。下一步
- 阅读 Kubernetes 博客上的文章:使用终结器控制删除。