对象删不掉?十有八九是 metadata.finalizers 里还有人没点头。这篇在 ConfigMap 上模拟一个“控制器”,把带 finalizer 对象的删除过程拆成两步看清楚:先打标记、再摘 finalizer;并用 PVC 保护这个内置例子对照真实场景。
kubectl delete cm a --wait=false:退出码 0;configmap "a" deleted from k12 namespace;耗时 39 ms
之后 kubectl get cm a 仍然能读到;deletionTimestamp=2026-10-10T08:57:42Z deletionGracePeriodSeconds=0 finalizers=['example.com/block']
data 还在:{"v":"1"}对象带着 finalizers 时,kubectl delete 几十毫秒就返回 deleted,但对象还在:apiserver 只做了一件事,把 metadata.deletionTimestamp 设上。这时 kubectl get 照常能读到,data 原样保留。真正的删除要等 finalizers 变空,由写下这个 finalizer 的控制器负责:先做完清理工作,再把自己那一项摘掉。
改 data:退出码 0;configmap/a patched;data={"v":"2"}
再加一个 finalizer:退出码 1;metadata.finalizers: Forbidden: no new finalizers can be added if the object is being deleted, found new finalizers []string{"example.com/another"}
再删一次:deletionTimestamp 2026-10-10T08:57:42Z → 2026-10-10T08:57:42Z(没有变化:True)
想撤销删除(删掉 deletionTimestamp):退出码 0;configmap/a patched (no change)
同名重建:error: failed to create configmap: object is being deleted: configmaps "a" already exists改 data 仍然允许;新增 finalizer 被拒绝(no new finalizers can be added if the object is being deleted);再删一次不会改变 deletionTimestamp;想用 patch 把 deletionTimestamp 删掉得到 (no change),撤销不了;同名重建报 object is being deleted: configmaps "a" already exists。规则很简单:finalizer 只能减不能加。
kubectl delete cm b(默认 --wait=true),4 秒后由“控制器”摘掉 finalizer:退出码 0;configmap "b" deleted from k12 namespace;总共等了 4.1 秒 kubectl get cm b:Error from server (NotFound): configmaps "b" not found 有两个 finalizer 时只摘掉一个:对象还在吗 True;剩下 ['example.com/second'] 再摘掉最后一个:对象还在吗 False
kubectl delete 默认等到对象真的消失才返回:“控制器”4 秒后把 finalizers 置空,命令就等了 4.1 秒。有多个 finalizer 时必须全部摘光,摘掉一个对象仍在。所谓“强制删除卡住的对象”,就是替那个不工作的控制器把 finalizer 摘掉——对象会立刻消失,但它本该做的清理没有发生。
Pod user 已经 Running、PVC data 已经被它使用:phase=Bound finalizers=['kubernetes.io/pvc-protection'] kubectl delete pvc data 之后:仍然存在,phase=Bound deletionTimestamp=有 finalizers=['kubernetes.io/pvc-protection'] 删除用它的 Pod 之后:PVC 消失了(Pod 删除完成后又过了约 0.1 秒)
PVC 创建时就带着 kubernetes.io/pvc-protection。Pod user 正在使用它时 kubectl delete pvc data,PVC 仍是 Bound,只是多了 deletionTimestamp;把用它的 Pod 删掉后,PVC 在约 0.1 秒内消失。这个 finalizer 防止的是“卷还在被挂载时底层存储被回收”。