Kubernetes Controller的并发reconciling

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 当Controller watch的对象十分频繁的发生变更,reconcile队列中就会堆积大量的reocncile请求。此时“并发reconciling”就显得尤为重要。和默认的单个reconcile循环相比,多个reconcile循环可以更快速的处理reconcile队列中的请求。并发reconciling的确有很大的性能提升,但是如果不深入研究相关的代码,开发人员很容易会担心一个问题:并发reconciling会引入一致性问题吗?比如:有没有可能两个reconcile循环同时处理相同的对象呢?本文会解决你的这个疑问。

本文翻译自:https://openkruise.io/blog/learning-concurrent-reconciling/,如果你对并发reconciling也存在一致性担忧,请继续阅读本文。

Controller模式是Kubernetes成功的重要因素之一,它是保证Kubernetes API处于目标状态的核心机制。通过CRD、Controller以及Operator,其他系统可以很方便的集成进Kubernetes。

众多开发者使用Controller运行时库和对应的Controller工具--KubeBuilder来构建他们自己的Kubernetes Controller。在OpenKruise项目中,我们同样使用了KubeBuilder生成脚手架代码进而实现reconciling逻辑。在这篇博客中,我将会分享一些从Kruise Controller开发中学习到的东西,尤其是并发reconciling。

肯定有人已经注意到:controller runtime是支持并发reconciling的。下面是创建controller时的Options参数结构体[source code]

typeOptionsstruct {
// MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1.MaxConcurrentReconcilesint// Reconciler reconciles an objectReconcilerreconcile.Reconciler}

当Controller watch的对象十分频繁的发生变更,reconcile队列中就会堆积大量的reocncile请求。此时“并发reconciling”就显得尤为重要。和默认的单个reconcile循环相比,多个reconcile循环可以更快速的处理reconcile队列中的请求。并发reconciling的确有很大的性能提升,但是如果不深入研究相关的代码,开发人员很容易会担心一个问题:并发reconciling会引入一致性问题吗?比如:有没有可能两个reconcile循环同时处理相同的对象呢?

如你期望的那样,答案是否定的。两次reconcile不会同时处理相同的对象。这个“魔法”是由Kubernetes client-go中实现的工作队列保证的,controller runtime的reconcile队列使用的正是这个队列。这个工作队列[source code]的算法如下图所示:

为了实现多个reconcile循环不会同时处理同一个对象,这个工作队列除了一个队列(queue)以外,还用到了两个集合(set)。

  1. 1. Figure1(a)代表了一个空队列的初始状态,假设将会有4个reconcile请求到达,其中两个请求关联的对象都是object A。
  2. 2. 当一个请求到达,与之关联的目标对象首先会被添加到dirty set中,如果这个对象已经在dirty set中,则这个对象会被丢掉(译者注:这里的“丢掉”指的是不再进行接下来的判断流程,即:无论在不在processing set中,都不会入队);然后,如果这个对象不在processing set中,则将这个对象入队。Figure1(b)表示连续添加了3个对象进入队列。
  3. 3. 当一个reconcile循环准备好处理一个请求的时候,它就会从队首取出一个对象,同时将这个对象加入processing set,并且从dirty set中移除(如Figure1(c)所示)。
  4. 4. 此时,如果有一个正在处理中的对象对应的请求到达,这个对象只会被添加到dirty set中,并不会入队(如Figure1(d)所示)。这保证了一个对象只可能被一个reconcile循环处理。
  5. 5. 当这个reconcile结束,这个对象会从processing set中被移除。如果这个对象还存在于dirty set中,则这个对象会被加入到队尾(如Figure1(e)所示)。

上述算法会有如下影响:

  • * 它避免了多个reconcile循环同时处理相同的对象。
  • * 对象的处理顺序可能会和相应请求的到达顺序不同,即便只有一个reconcile线程。因为Controller一定会将集群渲染到最终目标状态,所以这两个顺序不同通常不会造成错误。然而,乱序reconcile可能会导致一个请求被明显的延迟。

以Figure2为例:

  1. 1. 假设当前只有一个reconcile线程,并且有两个处理object A的请求到达。
  2. 2. 它们其中一个会被处理,一个会加入到dirty set中(如Figure2(b)所示)。
  3. 3. 如果当前的reconciling持续了很久,在此期间有很多新的reconcile请求到达,这些新请求都会进入队列(如Figure2(c)所示)。
  4. 4. 当这次reconciling结束,object A会被加入队尾(如Figure2(d)所示)。因此直到队列里的前面对象都被处理完,A才会被再次处理。很明显第二个处理A的请求是在这些请求之前到达的,但是实际的处理却在这些请求之后,因此造成了不能忽视的延迟。

一个简单的缓解这类延迟的方法--并发reconciling。因为一个go routine的消耗通常很小,所以即使当前Controller是空闲的,多个reconcile线程也不会占用太多资源。所以MaxConcurrentReconciles通常会被设置为大于1的整数。

最后要说的是:reconcile请求是可能会被丢弃的(如果目标目标对象已经在dirty set中)。这意味着我们不能假定Controller可以追踪到某个对象的所有状态更改事件。回顾Tim Hockin的演讲,Kubernetes的Controller是水平触发的,而不是边缘触发。It reconciles for state, not for events.

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1月前
|
Kubernetes 负载均衡 应用服务中间件
k8s学习--ingress详细解释与应用(nginx ingress controller))
k8s学习--ingress详细解释与应用(nginx ingress controller))
169 0
|
3月前
|
弹性计算 运维 Kubernetes
Kubernetes(K8S) Controller - Deployment 介绍
Kubernetes(K8S) Controller - Deployment 介绍
38 1
|
3月前
|
Kubernetes 容器 Perl
在K8S中,Replica Set和Replication Controller之间有什么区别?
在K8S中,Replica Set和Replication Controller之间有什么区别?
|
3月前
|
存储 Kubernetes 关系型数据库
Kubernetes(K8S) Controller - StatefulSet、DaemonSet 介绍
Kubernetes(K8S) Controller - StatefulSet、DaemonSet 介绍
33 0
|
6月前
|
运维 Kubernetes 容灾
kubernetes核心技术之Controller控制器知识总结
kubernetes核心技术之Controller控制器知识总结
60 1
|
6月前
|
消息中间件 Kubernetes 监控
kubernetes—Controller详解(二)
kubernetes—Controller详解(二)
84 0
|
6月前
|
Kubernetes 测试技术 Perl
kubernetes—Controller详解(一)
kubernetes—Controller详解(一)
94 0
|
存储 Kubernetes 调度
【云原生】k8s核心概念—Pod & Controller & Service & Serect & ConfigMap介绍——20230213
【云原生】k8s核心概念—Pod & Controller & Service & Serect & ConfigMap介绍——20230213
271 0
|
Kubernetes 应用服务中间件 调度
kubernetes Ingress、Ingress controller
kubernetes Ingress、Ingress controller
|
JSON Kubernetes 安全
Kubernetes Admission Controller 简介 - 注入 sidacar 示例
Kubernetes Admission Controller 简介 - 注入 sidacar 示例
113 0