Finalizers
带有 Finalizers 的对象删除流程如下:
- 对带有 Finalizer 的对象的第一个删除请求会为其
metadata.deletionTimestamp
设置一个值(标记要删除的对象),但不会真的删除对象。并且 API 服务会禁止对象被删除,直到其metadata.finalizers
字段为空。返回 202 状态码。 - 此时控制平面会通过轮询对该对象的更新请求来执行它们所要处理的所有 Finalizer。
metadata.deletionGracePeriodSeconds
的取值控制对更新的轮询周期。 - 当所有 Finalizer 都被执行过,资源被删除。每执行完一个就从
finalizers
中移除一个,直到finalizers
为空,之后其宿主资源才会被真正的删除。
一个常见的 Finalizer 的例子是
kubernetes.io/pv-protection
, 它用来防止意外删除PersistentVolume
对象。 当一个PersistentVolume
对象被 Pod 使用时, Kubernetes 会添加pv-protection
Finalizer。 如果你试图删除PersistentVolume
,它将进入Terminating
状态, 但是控制器因为该 Finalizer 存在而无法删除该资源。 当 Pod 停止使用PersistentVolume
时, Kubernetes 清除pv-protection
Finalizer,控制器就会删除该卷。
属主与附属
属主(Owner)和附属(Dependent)用于描述 Kubernetes 对象之间的关系。
属主引用
附属对象有一个 metadata.ownerReferences
字段,用于引用其属主对象。一个有效的属主引用, 包含与附属对象同在一个命名空间下的对象名称和一个 UID。Kubernetes 自动为一些对象的附属资源设置属主引用的值, 这些对象包含 ReplicaSet、DaemonSet、Deployment、Job、CronJob、ReplicationController 等。
附属对象还有一个 ownerReferences.blockOwnerDeletion
字段,该字段使用布尔值, 用于控制特定的附属对象是否可以阻止垃圾收集删除其属主对象。
k8s 不允许跨越命名空间指定属主。
属主关系与 Finalizer
在前台删除中,会添加 foreground
Finalizer,这样控制器必须在删除了拥有 ownerReferences.blockOwnerDeletion=true
的附属资源后,才能删除属主对象。 如果你指定了孤立删除策略,Kubernetes 会添加 orphan
Finalizer, 这样控制器在删除属主对象后,会忽略附属资源。