Kubernets Pod 存在 Finalizers 一直处于 Terminating 状态

Metadata 


定义了对象的原数据,namespace是用来放置对象的,对象可以通过namespace做隔离。

任何的kubernetes的对象会分为两类,一类像节点这种对象,一个计算节点是属于整个集群的,这类对象是nonnamespace,它的namespace值永远都是空的。

还有一种是pod,service,都是归属于某个租户/用户的,这些对象属于namespace。

一个对象namespace+name就代表了在整个集群当中唯一值。

 typemeta定义了我是啥,metadata定义了我是谁。

Finalizer

如果只接触社区的kubernetes,那么对Finalizer可能没有太多的概念,Finalizer本身是资源锁。

一个对象,当我们创建的时候,把这个对象的请求发送到apiserver,apiserver经过认证鉴权存入到etcd,如果删除这个对象,也是经过一样的链路,它最后从etcd中删除掉,这个删除本身是物理删除,相当于etcd当中这条数据就抹掉了,这个对象就消失了。

如果写了控制器监控这个对象,那么会监听这个对象的创建,这个对象创建了就去做一些事情,对象删除了就会去做另外一些事情,我们不能够相信系统永远都在工作,假设控制器出错了,或者控制器在升级,这个时候控制器没有在工作,这个时候去删除对象,假设这个对象消失了,那么这个事件已经消失了,在这个对象删除之后,再去启动我的控制器,控制器是看不到之前这个对象删除的事件,因为在控制器启动之前这个事件已经发生了,在启动新的控制器实例的时候,没有这个消息通知,所以就丢失了对象删除的这样一个事件。

扫描二维码关注公众号,回复: 14359585 查看本文章

所以fanalizer本质上是资源锁,一个对象加了finalizer,在删除对象的时候不会做物理删除,它会做逻辑删除,其实也就是在它属性的事件戳里面deletetimestamp置为在删除那一刻的时间戳。

这样的好处是当用户去删除对象,如果这个对象有finalizer,那么这个对象不会消失,然后这个控制器可以捕获这个事件,即使是控制器在维护,然后重新启动之后就能够看到这个事件了,当发现一个对象deletetimestamp不为空,说明用户想删除它,那么控制器里面就可以去做一些逻辑处理。

当我们去配置外部资源的时候,比如创建一个pod,这个pod创建完之后,要去配置外部的一些网络,或者配置外部的dns,外部的负载均衡,这个时候就需要为对象加finalizer,那么这需要我写一个控制器,控制器去配置外部dns,配置外部dns之前就要给这个对象加上finalizer,由我都配置控制器去加的,加好finalizer之后这个对象就被锁住了,它只要有finalizer就不会被物理删除,当我去删除这个对象的时候,控制器会看到update的事件,看到这个对象的deletetimestamp不为空,那么这个controller要去清除外部配置,当完成外部配置的清除之后,那么由controler将finalizer删除掉,清除掉之后,k8s发现这个对象finalizer为空了,那么自动由逻辑删除变为物理删除,这个对象就消失了。

所以finalizer是个资源锁。

Pod 一直处于 Terminating 状态 存在 Finalizers


k8s 资源的 metadata 里如果存在 finalizers ,那么该资源一般是由某程序创建的,并且在其
创建的资源的 metadata 里的 finalizers 加了一个它的标识,这意味着这个资源被删除时需要
由创建资源的程序来做删除前的清理,清理完了它需要将标识从该资源的 finalizers 中移除,然
后才会最终彻底删除资源。
比如 Rancher 创建的一些资源就会写入 finalizers 标识。
处理建议: kubectl edit 手动编辑资源定义,删掉 finalizers ,这时再看下资源,就会发现
已经删掉了

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/125596872