所有者和从属
在 Kubernetes 中,一些对象是其他对象的“所有者”(owner)。例如,一个ReplicaSet 是一组 Pod 的所有者。这些被拥有的对象是其所有者的“从属”(dependent)。
所有权不同于某些资源也使用的标签和选择器机制。例如,考虑一个创建 EndpointSlice
对象的 Service。Service 使用标签来允许控制平面确定哪些 EndpointSlice
对象用于该 Service。除了标签之外,每个代表 Service 管理的 EndpointSlice
都有一个所有者引用。所有者引用有助于 Kubernetes 的不同部分避免干扰它们不控制的对象。
对象规范中的所有者引用
从属对象有一个 metadata.ownerReferences
字段,它引用了其所有者对象。一个有效的所有者引用包括对象名称和与从属对象在同一命名空间中的UID。Kubernetes 会自动为 ReplicaSets、DaemonSets、Deployments、Jobs、CronJobs 和 ReplicationControllers 等其他对象的从属对象设置此字段的值。你也可以通过手动更改此字段的值来配置这些关系。但是,通常你不需要这样做,可以允许 Kubernetes 自动管理这些关系。
从属对象还有一个 ownerReferences.blockOwnerDeletion
字段,它接受一个布尔值,并控制特定的从属是否可以阻止垃圾回收删除其所有者对象。如果控制器(例如,Deployment 控制器)设置 metadata.ownerReferences
字段的值,Kubernetes 会自动将此字段设置为 true
。你也可以手动设置 blockOwnerDeletion
字段的值来控制哪些从属阻止垃圾回收。
Kubernetes 准入控制器根据所有者的删除权限控制用户更改从属资源此字段的访问权限。此控制可防止未经授权的用户延迟所有者对象的删除。
注意
跨命名空间所有者引用是故意不允许的。命名空间的从属可以指定集群作用域或命名空间的所有者。命名空间的所有者**必须**与从属位于同一个命名空间中。如果不是,则所有者引用被视为不存在,一旦所有所有者都被验证不存在,从属将受到删除的影响。
集群作用域的从属只能指定集群作用域的所有者。在 v1.20+ 中,如果集群作用域的从属指定命名空间类型作为所有者,则它被视为具有无法解析的所有者引用,并且无法被垃圾回收。
在 v1.20+ 中,如果垃圾收集器检测到无效的跨命名空间 ownerReference
,或者集群作用域的从属引用了命名空间类型的所有者,则会报告一个警告事件,其原因为 OwnerRefInvalidNamespace
,并且 involvedObject
为无效从属。你可以通过运行 kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace
来检查此类事件。
所有权和终结器
当你告诉 Kubernetes 删除一个资源时,API 服务器允许管理控制器处理该资源的任何终结器规则。终结器可以防止你的集群可能仍然需要正常运行的资源被意外删除。例如,如果你尝试删除一个 Pod 仍在使用的PersistentVolume,删除不会立即发生,因为该 PersistentVolume
上有 kubernetes.io/pv-protection
终结器。相反,卷会保持在 Terminating
状态,直到 Kubernetes 清除终结器,这只会在 PersistentVolume
不再绑定到 Pod 之后发生。
当你使用前台或孤儿级联删除时,Kubernetes 还会为所有者资源添加终结器。在前台删除中,它会添加 foreground
终结器,以便控制器必须先删除也具有 ownerReferences.blockOwnerDeletion=true
的从属资源,然后才能删除所有者。如果你指定孤儿删除策略,Kubernetes 会添加 orphan
终结器,以便控制器在删除所有者对象后忽略从属资源。
下一步
- 了解更多关于Kubernetes 终结器。
- 了解垃圾回收。
- 阅读对象元数据的 API 参考。