问题描述
从 kubernetes 1.20 开始,ownerReferences
以及 K8s 执行 GC 的方式发生了变化。
基本上,如果 x
命名空间中的资源在 y
命名空间中启动一个 pod/job,子节点具有 ownerReferences
引用 x
中的父资源,K8s 将终止子 pod/工作。
- 解决了在遇到包含不正确数据的 ownerReferences 时垃圾收集控制器的非确定性行为。当检测到子对象和所有者对象之间的命名空间不匹配时,记录具有 OwnerRefInvalidNamespace 原因的事件。可以在升级之前运行 kubectl-check-ownerreferences 工具以定位具有无效 ownerReferences 的现有对象。
如果我们移除 ownerReferences
,资源将不会被垃圾回收。有没有办法处理这种情况,即;如何让 ownerReferences
在多个命名空间中工作或让作业/pod 在完成后自行清理?谢谢。
解决方法
根据Fix GC uid races and handling of conflicting ownerReferences #92743
命名空间旨在相互独立,因此在 ownerReferences、secret/configmap 卷引用等中不允许跨命名空间引用。
此外,授予命名空间 a 的权限通常不是为了提供可见性或与命名空间 b 中的对象交互的能力(或导致系统控制器与命名空间 b 中的对象交互)。
和 Update GC cross-namespace note #25091
设计不允许跨命名空间所有者引用。
因此,使用 ownerReferences
进行跨命名空间的垃圾收集是不可能的通过设计。
但是,您可以使用标签模拟多命名空间 GC。您只需要在某个对象创建子对象时配置这些标签即可。
或者,您可以删除命名空间以对该命名空间中的所有对象进行 GC,但这可能不是最佳解决方案。
编辑
$ kubectl label pods owner=my -l region=europe
$ kubectl label pods owner=my -l region=pacific
$ kubectl label svc owner=my -l svc=europe
$ kubectl label svc owner=my -l svc=pacific
$ kubectl label pod kube-proxy-2wpz2 owner=my -n kube-system
$ kubectl label pod kube-proxy-cpqxt owner=my -n kube-system
$ kubectl get pods,svc -l owner=my --show-labels --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE LABELS
default pod/aloha-pod 1/1 Running 0 54d app=aloha,owner=my,region=pacific
default pod/ciao-pod 1/1 Running 0 54d app=ciao,region=europe
default pod/hello-pod 1/1 Terminating 0 54d app=hello,region=europe
default pod/ohayo-pod 1/1 Running 0 54d app=ohayo,region=pacific
kube-system pod/kube-proxy-2wpz2 1/1 Running 2 299d controller-revision-hash=5cf956ffcf,k8s-app=kube-proxy,pod-template-generation=1
kube-system pod/kube-proxy-cpqxt 1/1 Running 3 299d controller-revision-hash=5cf956ffcf,pod-template-generation=1
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
default service/europe ClusterIP 10.109.5.102 <none> 80/TCP 54d owner=my,svc=europe
default service/pacific ClusterIP 10.99.255.196 <none> 80/TCP 54d owner=my,svc=pacific
$ kubectl delete pod,svc -l owner=my --dry-run --all-namespaces
pod "aloha-pod" deleted (dry run)
pod "ciao-pod" deleted (dry run)
pod "hello-pod" deleted (dry run)
pod "ohayo-pod" deleted (dry run)
pod "kube-proxy-2wpz2" deleted (dry run)
pod "kube-proxy-cpqxt" deleted (dry run)
service "europe" deleted (dry run)
service "pacific" deleted (dry run)
或者,可能有一个 bash 脚本根据标签删除其控制器对象不存在的所有对象。它也可以在配置了适当服务帐户的集群内运行。
没有简单的内置选项来实现您想要的。您应该将所有者引用对象保留在同一命名空间中。