宽度发生变化事件监听_干货分享 Kubernetes之controllerruntime事件再处理

56326a682ce28d4803c80555a904852f.png

410dc1ff09d8ede0b31081c6a5b96dec.png

友情提示:全文6000多文字,预计阅读时间11分钟

一、前言

Kubernetes(K8s) 作为一个可移植的、可扩展的开源平台,已经被广泛应用于管理容器化的工作负载和服务。虽然K8s本身提供了丰富的资源类型,但是在使用中,仍然存在扩展资源的需求。

本文将以项目中遇到的一个实际问题作为切入点,详细分析问题原因,同时介绍下使用第三方框架扩展K8s资源时的工作原理。

二、背景

在描述具体问题前,先对涉及的K8s概念做一些简单介绍。

17c77269e21696f5de499a8abbf6da01.png

图(1) CRD关系图

1)CRD

CRD全称是CustomResourceDefinition,即自定义资源。CRD也是K8s的一种资源,创建一个CRD即在K8s中定义了一种新的资源类型,这个资源类型可以像K8s中的原生资源一样,既可以通过kubectl命令行,也可以通过访问apiserver来进行操作。

2)Resource Event

这里的Event是当资源本身发生变化时触发的事件,并不是K8s中的Event资源。共有四种类型,CreateEvent,UpdateEvent,DeleteEvent,GenericEvent。其中GenericEvent用来处理未知类型的Event,比如非集群内资源事件,一般不会使用。如果控制器"订阅"了这个资源,那么资源发生变化时,比如被更新或者被删除时,控制器会获取到这个事件。Event是联系控制器和资源的数据通道。

3)controller-runtime

controller-runtime被用来创建K8s资源控制器,如果引入了CRD的话,单纯定义这个资源只能起到存数据的作用,并没有业务处理逻辑。通过controller-runtime可以监听资源的变化,捕获Resource Event,触发相应的处理流程,让这个自定义资源表现出和原生资源相同的行为。

4)kubebuilder

kubebuilder是一个根据模板生成代码的工具,使用kubebuilder可以快速渲染出一个依赖controller-runtime的控制器。在分析controller-runtime之前,需要先用它来生成一个controller。

为了使CRD像原生资源那样工作,需要创建对应的控制器(controller),这个控制器需要捕获资源发生变化时的事件,完成指定的操作。理解了CRD的使用方法和运行原理,这样遇在到问题时,才能够方便定位和解决。

三、问题

在项目中使用controller-runtime监听CRD资源过程中,发现在资源变化触发事件,如果请求事件没有被正确处理而返回错误时,事件会被重复处理,但是每次处理的时间间隔并不规则。表现为日志中显示事件被再处理的间隔时间并不等长,从几秒到十几分钟的分布。精简后的日志显示如下。

controller.go:36] failed at:  2020-06-30 08:14:38.492813441 +0000 UTC m=+0.733523768controller.go:36] failed at:  2020-06-30 08:14:39.493302606 +0000 UTC m=+1.734012936controller.go:36] failed at:  2020-06-30 08:14:40.49372105 +0000 UTC m=+2.734431343controller.go:36] failed at:  2020-06-30 08:14:41.49402338 +0000 UTC m=+3.734733690controller.go:36] failed at:  2020-06-30 08:14:42.494593356 +0000 UTC m=+4.735303683controller.go:36] failed at:  2020-06-30 08:14:43.495217453 +0000 UTC m=+5.735927765controller.go:36] failed at:  2020-06-30 08:14:44.49564783 +0000 UTC m=+6.736358135controller.go:36] failed at:  2020-06-30 08:14:45.496101659 +0000 UTC m=+7.736811950controller.go:36] failed at:  2020-06-30 08:14:46.496564312 +0000 UTC m=+8.737274709controller.go:36] failed at:  2020-06-30 08:14:47.776977606 +0000 UTC m=+10.017687933controller.go:36] failed at:  2020-06-30 08:14:50.339145951 +0000 UTC m=+12.579856239controller.go:36] failed at:  2020-06-30 08:14:55.459778396 +0000 UTC m=+17.700488722controller.go:36] failed at:  2020-06-30 08:15:05.700252055 +0000 UTC m=+27.940962359controller.go:36] failed at:  2020-06-30 08:15:26.180615289 +0000 UTC m=+48.421325604controller.go:36] failed at:  2020-06-30 08:16:07.140934099 +0000 UTC m=+89.381644386controller.go:36] failed at:  2020-06-30 08:17:29.061481373 +0000 UTC m=+171.302191703controller.go:36] failed at:  2020-06-30 08:20:12.901929639 +0000 UTC m=+335.142639963

大体观察到,前面日志的时间差值在1s左右,后面的差值变成了5s,10s,20s左右。所以产生了下面的疑问:

1) 这些事件的处理时间间隔是不是会持续增加?

2) 如果持续增加,最大会有多长?

3) 这样持续的事件处理会不会影响到controller性能?

4) 当集群中事件数量规模扩大时会不会冲刷掉正常的请求?

四、分析

为了解Event是如何被处理的,将从上到下分析下controller-runtime的启动流程,Reconcile函数在何时被调用、调用出错时如何再处理等步骤。为了聚焦在事件再处理的步骤上,对前面的几个步骤先做下简单的描述。也借此了解下controller-runtime的整体架构。

65e898cdd4afe8e2347bb46f3fc30e01.png

图(2) Kubernetes controller架构图(图片来自网络)

上面提到的问题在步骤7和步骤8中产生,也是本文分析的重点。

在分析controller-runtime之前,需要先使用kubebuilder构建一个简单的controller,因为这不是本文的重点,所以下面略过生成步骤,直接进入到分析步骤。kubebuilder的使用参考链接(https://book.kubebuilder.io/quick-start.html)。

其中reconcile.Reconcile函数被简化为

go func (r *ClusterReconciler) Reconcile(req ctrl.Request) (ctrl.Result,error) {
         klog.Infof("failed at:  %s",time.Now())     return ctrl.Result{},errors.New("err") }

1)controller-runtime启动

*controller-runtime版本: 0.5.5

648e8d5c9cdcad7b3c5020bac0f8e9eb.png

图(3) controller-runtime启动

在controller-runtime中,Event的处理逻辑是Reconciler对象,Reconciler被controller引用,这里的controller便是控制器。在controller之上,还有一个更高层的管理者manager。manager中可以设置多个controller,但是一个controller中只有一个Reconciler。

1.1)生成manager

goimport ("sigs.k8s.io/controller-run
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值