所有者和依赖项
在 Kubernetes 中,有些 对象 是其他对象的属主。例如,一个 ReplicaSet 是一组 Pods 的属主。这些属主对象是其属主的附属对象。
属主与一些资源也使用的 标签和选择器 机制不同。例如,考虑一个创建 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
,或者检测到集群范围的附属对象其 ownerReference
引用了一个命名空间范围的类型,则会报告一个原因字段为 OwnerRefInvalidNamespace
、involvedObject
字段为无效附属对象的警告事件。你可以通过运行 kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace
来检查此类事件。
属主与 Finalizers
当你告诉 Kubernetes 删除一个资源时,API 服务器允许管理控制器处理该资源的任何 finalizer 规则。Finalizers 可以防止意外删除集群正常运行可能仍然需要的资源。例如,如果你尝试删除一个仍被 Pod 使用的 PersistentVolume,删除不会立即发生,因为该 PersistentVolume
上有 kubernetes.io/pv-protection
finalizer。相反,该 卷 会一直处于 Terminating
状态,直到 Kubernetes 清除该 finalizer,这只会在该 PersistentVolume
不再绑定到 Pod 之后发生。
当你使用 前台或孤儿级联删除 时,Kubernetes 也会向属主资源添加 finalizers。在前台删除中,它添加 foreground
finalizer,以便控制器必须先删除同样具有 ownerReferences.blockOwnerDeletion=true
的附属资源,然后才能删除属主。如果你指定孤儿删除策略,Kubernetes 会添加 orphan
finalizer,以便控制器在删除属主对象后忽略附属资源。
接下来
- 了解更多关于 Kubernetes Finalizers 的信息。
- 了解关于 垃圾收集 的信息。
- 阅读 对象元数据 的 API 参考。