当前位置: 首页 > news >正文

k8s控制器定时把k8s apiserver内存和cpu打得很高

k8s控制器定时把k8s apiserver内存和cpu打得很高

近期发现,k8s apiserver的内存和cpu定时(每隔10h)被客户一个控制器打的很高,有个小突刺。排查发现,用户的控制器开启了resyncPeriod,默认值就是10h。

一般来说controller runtime框架、knative框架,都会默认这个值为10h。不同的是,controller runtime框架会打算到10h附近,而knative框架是严格10h。当然真实时间会受到上次执行的影响,略有偏差。

                      image

 

定位到问题后,解决起来也很简单,构建informer时,将resyncPeriod设置为0就行。

但是,客户有担心,偶发k8s里面缓存不够新的问现象,担心关闭resyncPeriod会影响到informer机制中缓存的更新。第一反应,客户是不是对ResyncPeriod这个参数有什么误解?这个参数不会重新到APIServer拉取全量数据,而只是把indexer里面的缓存的所有key list一遍,重新推进DeltaFIFO,触发controller将所有事件重新调协一遍。

顺带把整个informer机制相关的debug一遍,确认无误。此处粘贴一些图做些记录。

1. Informer机制各种类详细介绍

https://blog.imoe.tech/2023/02/15/kubernetes-informer-mechanism/

这篇写得非常好。

网上有大量文章,写的并不准确。包括ResyncPeriod参数,竟然把它说成可以重新从K8S APIServer全量拉取informer数据,更新informer缓存,避免watch机制错误导致缓存数据的不一致。这些文章给我带来了很大的干扰。所以我不断调整ResyncPeriod,debug测试。发现控制器并没有根据ResyncPeriod参数,去LIST K8SAPISERVER更新整个缓存;而只是从indexer的ThreadSafeMap里,list所有的key,重新推入DeltaFIFO,触发事件,让控制器重新handler。

image

 

client-go 组件

  • Reflector:指的是 cache 包中定义的 Reflector 类,用于监控 Kubernetes 资源变化,其功能由 ListAndWatch 函数实现。当 Reflector 接收到资源变更的事件,会获取到变更的对象并在函数 watchHandler 中放到 Delta Fifo 队列。
  • Delta FIFO:是一个 FIFO 的队列,用来缓存 Reflector 拉取到的变更事件和资源对象;
  • Informor:是流程中最重要的节点,是整个流程的桥梁,Informer 也是在 cache 包中定义的,其功能在 processLoop 函数中实现,负责:
    • 从 Delta FIFO 中 pop 出对象并更新到 Indexer 的 cache 中;
    • 调用自定义 Controller,传递该对象。
  • Indexer:指在 cache 包中定义的 Indexer 类,主要是在资源对象上提供了索引和本地缓存的功能。经典的使用场景是基于对象的 Labels 创建索引,Indexer 可以支持使用索引函数来维护索引,同时 Indexer 使用线程安全的 Data Store 来存储资源对象和对应的 Key。默认使用的是 cache 包里的 MetaNamespaceKeyFunc 函数来生成对象的 Key,格式如:<namespace>/<name>

自定义组件

上图中 Informer reference 和 Indexer reference 是指在自定义 Controller 中需要自己创建的 Informer 和 Indexer 的实例,用来与整个流程进行交互,需要根据需要的资源创建对应的实例。client-go 提供了 NewIndexerInformer 函数来创建 Informer 和 Indexer 实例,也可以使用 SharedInformerFactory 的工厂方法来创建实例。

每个资源都会对应一个 Informer,每个 Informer 都通过 Watch 创建一个长连接。如果一个资源创建了多个 Informer 无疑是非常浪费的,所以通常都使用 SharedInformerFactory 工厂方法来创建,这样每种资源都复用一个 Informer,从而降低开销。

 
2. informer多重缓存的数据结构
上一篇对各种组件和方法有详细介绍,但是缓存的数据结构搞得有点云里雾里。下面这篇文章是个完美的补充:
https://juejin.cn/post/7132767272841510926

 

image

 

 

 

不过,各位可能有个小小的疑问,客户每10h全量调协处理一遍数据,正常应该客户的pod cpu和内存打得很高,为什么会K8S APIServer也被打得高?

这里面客户有个错误用法,他没有进行事件过滤,正常来说,重新全量调协,是要处理那些需要处理的数据,不需要的应该用EventHandler过滤掉。客户没有做,导致每个事件,他都会调协处理,处理逻辑里面有大量list资源的操作(list加了labelSelector条件), 导致K8S APIServer缓存打得很高。

不过,在协助处理客户这个问题时,我也有点小小的疑惑:

前期客户的处理逻辑里面有大量list资源操作,甚至部分没有加resourceVersion=0(直查etcd)。这种情况下,把K8S APIServer内存打得很高,可以理解。

但是后面用户把全部list操作加上resourceVersion=0后,仍然会把K8S APIServer打得很高,这个就很奇怪。K8S APIServer在接受list请求时,直接从内存里面拿数据,为何会内存瞬间打得很高?难道针对大量list请求操作,它瞬间产生大量的局部变量?看来得看看k8s相关代码,才能解答。

 

http://www.sczhlp.com/news/67665/

相关文章:

  • 本土化DevOps新纪元:Gitee如何填补CODING停服后的市场空白
  • 网站建设的后如何发布wordpress 引入js
  • 网站换域名了怎么做301重定向网站前台做好以后用什么生成后台管理系统
  • 电子商务网站建设产品网页制作个人简历网页的步骤
  • 请问哪里可以做网站中山网站推广
  • 安徽中兴建设工程有限公司网站wordpress帖子缩略图
  • docker 搭建时间服务器ntp
  • 部署Nginx(源码安装+Docker部署)
  • 青岛做视频的网站成都网站建设好
  • 公司做零申报在哪个网站上做彩网站有哪些
  • 青浦手机网站建设闲鱼网站是哪家公司做的
  • 好的网站模板潮州做网站
  • 温州知名网站推广网站建设php怎么安装
  • 广东两学一做考试网站征婚网站怎么做
  • 用户后台网站珠海网站设计公司
  • 字符串的处理
  • C# Avalonia 12- Drawing - LineJoins
  • 浏览器控制台中打印请求体携带参数
  • 中电金信:GFIX升级窗口期仅剩3个月,金融机构如何高效完成系统改造?
  • # Gitee DevOps深度评测:本土化工具链如何重塑中国开发者效率版图
  • 网站域名空间到期自己怎么续费厦门做网站哪家公司好
  • pc网站优化排名软件广州网页设计公司招聘
  • 网站未建设的情况说明wordpress粘贴媒体库
  • wap网站是什么二级建造师证报考条件
  • 网站建设及解决方案望野王绩拼音版
  • 宝安各大网站制作比较好的微信小程序定位权限怎么打开
  • 婚恋网站排名前三凡科网邮箱登陆
  • 网站 逻辑结构p2p网站建设 上海
  • 苏州自助建站品牌网络推广方案
  • Django信号