删掉 Deployment,ReplicaSet 和 Pod 为什么也跟着没了?靠的是从属对象上的 ownerReferences 和垃圾回收器。这篇用 ConfigMap 搭出所有者和从属,把 background、foreground、orphan 三种级联模式各跑一遍,再看 ownerReferences 写错了会发生什么。
kubectl delete cm owner1 --cascade=background:configmap "owner1" deleted from k13 namespace;耗时 40 ms;owner1 还在吗:False 从属 child1、child1b 分别在 39 ms、39 ms 后消失
从属 ownerReferences 里写着所有者的名字和 uid。--cascade=background(默认)删除所有者,40 毫秒就返回,所有者立刻消失;垃圾回收器随后发现从属的所有者没了,在约 40 毫秒内把从属也删掉。
1.5 秒后:owner2 还在吗 True;deletionTimestamp=有;finalizers=['foregroundDeletion'] 从属:fast(blockOwnerDeletion=true,无 finalizer)还在吗 False;slow(blockOwnerDeletion=true,带 finalizer)还在吗 True;noblock(blockOwnerDeletion=false,带 finalizer)还在吗 True 只摘掉 slow(blockOwnerDeletion=true)的 finalizer:owner2 在 38 ms 后消失;此时 noblock(blockOwnerDeletion=false,finalizer 还在)还在吗 True
所有者被标记删除,但仍然存在,finalizers 里多了 foregroundDeletion。无 finalizer 的从属 fast 很快被删,带 finalizer 的 slow(blockOwnerDeletion: true)卡住了所有者;只摘掉 slow 的 finalizer,所有者 38 毫秒后消失,而 noblock(blockOwnerDeletion: false,finalizer 还在)仍然存在——只有 blockOwnerDeletion: true 的从属才会阻塞所有者。
删除前 child3 的 ownerReferences:[{"apiVersion": "v1", "blockOwnerDeletion": true, "kind": "ConfigMap", "name": "owner3", "uid": "52d9cae2-54b7-4180-9e6e-148fef0a9c75"}]
kubectl delete cm owner3 --cascade=orphan:configmap "owner3" deleted from k13 namespace
之后 child3 还在吗 True;ownerReferences=None--cascade=orphan 删除所有者之后,从属还在,但 ownerReferences 已经被垃圾回收器摘掉(实测为 None),今后不会再被级联。把 Deployment 删掉而保留它的 Pod 就是这个模式。
ownerReferences 指向不存在的所有者(随便写的 uid):从属 ghost 在 39 毫秒后被垃圾回收器删掉 所有者 owner4 在 k13-other 里真实存在,从属 child4 在 k13:在 40 毫秒后被删掉(跨命名空间的 ownerReferences 不被支持,所有者按“不存在”处理) 相关事件:REASON MESSAGE | OwnerRefInvalidNamespace ownerRef [v1/ConfigMap, namespace: k13, name: owner4, uid: 49af3f1c-3fc6-4771-9018-34190c1fb034] does not exist in namespace "k13"
从属的 ownerReferences 指向一个不存在的 uid,约 40 毫秒就被垃圾回收器删掉。所有者真的存在、只是在别的命名空间,结果一样,同时产生事件 OwnerRefInvalidNamespace:跨命名空间的 ownerReferences 不被支持,所有者按“不存在”处理。所以手写 ownerReferences 一定要用真实的 uid,并且和从属在同一个命名空间(或者所有者是集群级资源)。