1

从 kubernetes 1.20 开始ownerReferences,K8s 执行 GC 以及如何执行 GC 发生了变化。基本上,如果命名空间中的资源在x命名空间中启动了一个 pod/job,y而 childownerReferences引用了 中的父资源x,K8s 会终止子 pod/job。

参考

  • 当遇到数据不正确的 ownerReferences 时,解决垃圾收集控制器的非确定性行为。当检测到子对象和所有者对象之间的命名空间不匹配时,会记录具有 OwnerRefInvalidNamespace 原因的事件。kubectl-check-ownerreferences 工具可以在升级之前运行以定位具有无效 ownerReferences 的现有对象。
    • 具有 ownerReference 的命名空间对象引用了同一命名空间中不存在的命名空间类型的 uid,现在始终将其视为该所有者不存在,并删除子对象。
    • 具有引用命名空间类型的 uid 的 ownerReference 的集群范围对象现在始终被视为该所有者不可解析,并且垃圾收集器将忽略子对象。(#92743,@liggitt)[SIG API 机械、应用程序和测试]

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

4

1 回答 1

1

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

命名空间旨在彼此独立,因此在 ownerReferences、secret/configmap 卷引用等内容中不允许跨命名空间引用。

此外,授予命名空间 a 的权限通常不是为了提供与命名空间 b 中的对象交互的可见性或能力(或导致系统控制器与命名空间 b 中的对象交互)。

更新 GC 跨命名空间注释 #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,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 脚本根据标签删除其控制器对象不存在的所有对象。它还可以在配置了适当的服务帐户的集群内运行。


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

于 2021-06-15T11:15:34.763 回答