§ 0x01 起因

开发控制器时,团队内一直在讨论是否需要为单个控制器对象添加并发控制(即加锁),最终把 controller-runtime 框架中并发数改为1,同时启用了 k8s 的 leader election机制保证只有单实例来规避并发的可能。

这种做法其实是有问题的,没有搞清楚 controller-runtime 框架本身是什么样的行为,强行把并发限制为1,可能导致性能上不去。

刚好在使用 cluster-api 过程中又遇到另外一个问题,某个 cluster 对象的 Reconcile 过程死锁阻塞了,导致这个对象后续都不再有 Reconcie 日志产生,而且注意到 cluster-api 的默认并发数是10。这两个问题的解答都需要对 controller-runtime 的行为进行梳理。

一般情况下直接看 controller-runtime 的文档就能明白了,不过在看过 https://github.com/kubernetes-sigs/controller-runtime/blob/main/pkg/reconcile/reconcile.go 中的文档,对 Reconcile 的解释,并没有强调同一个对象的并发 Reconcie 行为:是不会并发,还是会有并发?没有体现。没办法只能看代码了。

§ 0x02 无奈地去看源码

最终的关键逻辑在 k8s.io/client-go/util/workqueue/queue.go 中。

Type 对象中有3个关键数据结构。

  1. queue 队列,用来添加新对象。
  2. dirty hashset 记录 dirty 的对象集合。一个对象被取出处理时,如果又收到新的对象时,它就是 dirty 的,需要两次处理。 Add 时加入, Done 时取出,重新放回 queue 中。
  3. processing hashset 正在处理的对象集合。 Get 获取对象时放入,Done 调用时取出。

对应的数据流转图如下:

以上 hashset 的定义如下:

type empty struct{}
type t interface{}
type set map[t]empty

它是一个以泛型为 key 的map 。结合 controller-runtime,它存放的对象类型是 Request,定义如下:

type Request struct {
// NamespacedName is the name and namespace of the object to reconcile.
types.NamespacedName
}

而 types.NamespacedName 是个包含 Namepsace 和 Name 的 struct 类型。

通过分析 Type 类型的 Add 方法,可以解释一个对象 A 正在被 Reconcile 过程中,又有一个事件触发时, controller-runtime 的行为。

Add 上述场景会把对象放在 dirty 集合中,判断已在 processing 集群中则返回。所以解释这个问题的关键在于,set 类型中是是否存在某个元素是如何判断的,即 Request 对象对应的 struct 类型是如何在 map 中取 hash 的。

这种验证比较简单,直说结论:struct 类型是逐个对象迭代计算出的 hash 值,所以同一个对象转换得到的 Request 对象取值是一样的,最终对应的 hash 值 也是一样的。

§ 0x03 结论

即便控制器的并发数不为1,同一个进程中,不会有多个协程同时处理一个对象。

详细如下:

  1. 正在处于中的对象,Add 调用不会入队,只记录在 dirty 中。
  2. 对象处于完成后,在 Done 调用时检查,如在 dirty 中,再次入队,开始下一轮的处理。保证不丢事件。

这种设计核心思想是,用 map 对事件进行合并;使用队列保证顺序。

k8s中controller-runtime并发Reconcile分析的更多相关文章

  1. K8s中Pod健康检查源代码分析

    了解k8s中的Liveness和Readiness Liveness: 表明是否容器正在运行.如果liveness探测为fail,则kubelet会kill掉容器,并且会触发restart设置的策略. ...

  2. SpringMVC中 Controller的 @ResponseBody注解分析

    需求分析:需要 利用    out 对象返回给财付通是否接收成功 .那么将需要如下代码: /** * 返回处理结果给财付通服务器. * @param msg: Success or fail. * @ ...

  3. k8s deployment controller源码分析

    deployment controller简介 deployment controller是kube-controller-manager组件中众多控制器中的一个,是 deployment 资源对象的 ...

  4. k8s replicaset controller分析(2)-核心处理逻辑分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

  5. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  6. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

  7. k8s replicaset controller分析(1)-初始化与启动分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

  8. k8s replicaset controller 分析(3)-expectations 机制分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

  9. k8s endpoints controller分析

    k8s endpoints controller分析 endpoints controller简介 endpoints controller是kube-controller-manager组件中众多控 ...

  10. k8s client-go源码分析 informer源码分析(5)-Controller&Processor源码分析

    client-go之Controller&Processor源码分析 1.controller与Processor概述 Controller Controller从DeltaFIFO中pop ...

随机推荐

  1. .NET Core MVC基础之返回文件类型

    .NET Core MVC基础之返回文件类型 前言 上一篇文章讲了基础的返回类型,这篇文章讲解如何返回文件类型给浏览器下载. 系列文章 .NET MVC基础之页面传值方式 通过图片流来返回图片 返回类 ...

  2. supervisor 安装和基本使用

    安装 yum install supervisor touch /var/run/supervisor/supervisor.sock chmod 777 /var/run/supervisor/su ...

  3. 【论文阅读】RAL 2022: Receding Moving Object Segmentation in 3D LiDAR Data Using Sparse 4D Convolutions

    参考与前言 Status: Finished Type: RAL Year: 2022 论文链接:https://www.ipb.uni-bonn.de/wp-content/papercite-da ...

  4. 【AppStore】一文让你学会IOS应用上架Appstore

    前言 咱们国内现在手机分为两类,Android手机与苹果手机,现在用的各类APP,为了手机的使用安全,避免下载到病毒软件,官方都极力推荐使用手机自带的应用商城进行下载,但是国内Android手机品类众 ...

  5. MiniAuth 一个轻量 ASP.NET Core Identity Web 后台管理中间插件

    MiniAuth 一个轻量 ASP.NET Core Identity Web 后台管理中间插件 「一行代码」为「新.旧项目」 添加 Identity 系统跟用户.权限管理网页后台系统 开箱即用,避免 ...

  6. 2024 Selenium10个替代品

    随着自动化测试需求的不断增长,Selenium作为广泛使用的自动化测试工具,虽然功能强大,但也存在一些限制和挑战.在2024年, 越来越多的替代工具涌现,它们提供了更高效.更易用的解决方案.那么,哪些 ...

  7. JVM系列(一) -浅谈虚拟机的成长史

    一.摘要 众所周知,Java 经过多年的发展,已经从一门单纯的计算机编程语言,发展成了一套成熟的软件解决方案.从互联网到企业平台,Java 是目前使用最广泛的编程语言. 以下这段内容是来自 Java ...

  8. 2023/4/14 SCRUM个人博客

    1.我昨天的任务 初步了解项目的整体框架,并对接下来的人脸识别库以及组件有基本了解和安装 2.遇到了什么困难 ------------ 3.我今天的任务 获得了人脸识别作弊检测和绘制界面的分工,准备先 ...

  9. Python和RPA网页自动化-浏览器切换不同窗口页面

    以百度为例,点击[BOSS直聘]词条会打开一个BOSS新窗口页面,分别使用Python和RPA网页自动化在不同的窗口页面来回切换窗口完成以下顺序步骤 1.Python代码如下 步骤:打开新窗口页面后, ...

  10. Jmeter函数助手32-UUID

    UUID函数用于返回一个伪随机类型4通用唯一标识符(UUID).该函数没有参数,直接引用即可