由于 ownerReferences 指向 kubernetes 中不同命名空间中的资源,pod 被终止

pod getting terminated because of ownerReferences pointing to resource in different namespace in kubernetes

从 kubernetes 1.20 开始,ownerReferences 以及 K8s 执行 GC 的方式发生了变化。 基本上,如果 x 命名空间中的资源在 y 命名空间中启动 pod/job 并且子级具有 ownerReferences 引用 x 中的父资源,K8s 会终止子级pod/job.

Reference:

  • Resolves non-deterministic behavior of the garbage collection controller when ownerReferences with incorrect data are encountered. Events with a reason of OwnerRefInvalidNamespace are recorded when namespace mismatches between child and owner objects are detected. The kubectl-check-ownerreferences tool can be run prior to upgrading to locate existing objects with invalid ownerReferences.
    • A namespaced object with an ownerReference referencing a uid of a namespaced kind which does not exist in the same namespace is now consistently treated as though that owner does not exist, and the child object is deleted.
    • A cluster-scoped object with an ownerReference referencing a uid of a namespaced kind is now consistently treated as though that owner is not resolvable, and the child object is ignored by the garbage collector. (#92743, @liggitt) [SIG API Machinery, Apps and Testing]

如果我们删除 ownerReferences,资源将不会被垃圾回收。有没有办法处理这种情况,即;如何使 ownerReferences 在多个命名空间中工作或让 job/pod 在完成后自行清理?谢谢。

根据 修复 GC uid 竞争和处理冲突的 ownerReferences #92743

namespaces are intended to be independent of each other, so cross-namespace references have not been permitted in things like ownerReferences, secret/configmap volume references, etc.

additionally, granting permissions to namespace a is not generally intended to provide visibility or ability to interact with objects from namespace b (or cause system controllers to interact with objects from namespace b).

Update GC cross-namespace note #25091

Cross-namespace owner references are disallowed by design.

因此,使用 ownerReferences 进行跨命名空间的垃圾收集是不可能的 by desing


但是,您可以使用标签模拟多命名空间 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,owner=my,region=europe
default       pod/hello-pod          1/1     Terminating   0          54d    app=hello,owner=my,region=europe
default       pod/ohayo-pod          1/1     Running       0          54d    app=ohayo,owner=my,region=pacific
kube-system   pod/kube-proxy-2wpz2   1/1     Running       2          299d   controller-revision-hash=5cf956ffcf,k8s-app=kube-proxy,owner=my,pod-template-generation=1
kube-system   pod/kube-proxy-cpqxt   1/1     Running       3          299d   controller-revision-hash=5cf956ffcf,k8s-app=kube-proxy,owner=my,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 脚本根据标签删除其控制器对象不存在的所有对象。它还可以 运行 在配置了正确服务帐户的集群中。


没有直接的内置选项来实现您想要的。您应该将 所有者引用的 对象保存在同一个命名空间中。