前言

如果某个 kubernetes 资源添加了 finalizers(终结器),那么当这个资源被触发删除的时候,他不能正常的完全被删除。通过命令你还能查询到该资源。

添加 finalizers

往资源的 metadata 中添加 finalizers 字段即可,字段的内容可以任意定义。

cat << EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: mymap
  finalizers:
  - kubernetes
EOF

你可能经常会遇到下面格式的终结器,目的是为了防止 volumnes 被意外删除。

  • kubernetes.io/pv-protection
  • kubernetes.io/pvc-protection

笔者的文章同时发布于 [kubeclub](https://www.kubeclub.cn/kubernetes/172.html
云原生技术社区,一个分享云原生生产经验,同时提供技术问答的平台,前往查看

内部机制

在 K8s 中,只要对象 ObjectMeta 里面的 Finalizers 不为空,对该对象的 delete 操作就会转变为 update 操作,具体说就是 update deletionTimestamp 字段,其意义就是告诉 K8s 的 GC 在 deletionTimestamp 这个时刻之后,只要 Finalizers 为空,就立马删除掉该对象。

使用场景

当资源被删除时,虽然我们能 get 到这个事件,但是本地 cache 里面已经查不到资源的任何信息了,不利于我们做一些资源回收的工作,通过添加 finalizers ,资源被删除时候我们还可以查询到资源(只读),此时我们可以处理一系列 pre-hook 的任务,任务都处理完后我们将 finalizers 更新为空,此时 kubernetes 的 GC 就会自动帮我们完全删除资源了。

# 将 finalizers 字段移除
kubectl patch configmap/mymap \
    --type json \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'

额外说明

  1. 我通过 nginx 创建了一个 pod,并为该 pod 添加 finalizers
  2. pod 启动完成可以通过 podip 访问到 nginx
  3. 触发 pod 删除之后,由于 finalizers 还在,所以 pod 无法删除,此时 deletionTimestamp 字段已经有了
  4. 但是此时 nginx 已经的 podip 已经无法访问到服务了
  5. 通过将 yaml 的 finalizers 字段去除后,pod 被完全删除
Logo

开源、云原生的融合云平台

更多推荐