关于我们

  • -2019-
    09
    08

    技术分享|当我谈Kubernetes扩展性时,我谈些什么?(二)

    上篇文档留了一个“未完待续”即扩展功能的代码实现部分,这部分代码实现就是编写自定义控制器。我们先对自定义控制器做一个简单的定义:一套独立于核心代码可以独立运行以满足扩展功能的程序。既然是程序那就躲不过数据结构&执行逻辑,以下我们就从这两个维度解析自定义控制器。


    数据结构


    还是这个经典的图:


    核心结构之Informer


    定义:带有本地缓存和索引机制的可以注册事件的资源对象client。


    每一种资源对象不管是内置还是自定义的都有自己的Informer,用于控制器与实际资源的交互,Informer的代码是代码生成器自动生成,这部分在上一篇已经提及。


    Informer使用资源提供的client(也是自动生成的代码)跟APIServer建立连接。Informer中的Reflector使用ListAndWatch机制来获取并监听这些资源对象实例的变化。在 ListAndWatch 机制下,一旦APIServer端有新的资源实例被创建、删除或者更新,Reflector都会收到“事件通知”。


    这时,该事件及它对应的API对象这个组合(Delta)就会被放进一个Delta FIFO Queue中。Informer会不断地从这个Delta FIFO Queue里读取增量。每拿到一个增量,Informer就会判断这个增量里的事件类型,然后创建或者更新本地对象的缓存。


    比如,如果事件类型是Add(添加对象),那么Informer就会通过一个叫作 Indexer的库把这个增量里的API对象保存在本地缓存中,并为它创建索引。相反地,如果增量的事件类型是Deleted(删除对象),那么Informer就会从本地缓存中删除这个对象。


    重要结构之WorkQueue


    定义:资源对象与控制循环之间的缓冲队列,控制循环执行的任务的backlog。


    上面提到Informer除了会根据资源对象的变更事件触发本地缓存更新外,还会根据事先注册好的ResourceEventHandler触发相应的Func,这些Func的作用就是把资源对象以形式Namespace/Name作为key加入工作队列中,执行控制循环再通过Informer以key的作为查询条件查询出资源对象,此时查询出的资源对象即对象的期望状态,这个期望状态是我们后面执行扩展功能的基础。


    执行逻辑


    执行逻辑的代码篇幅比较大,这里做了精简只保留核心的流程,理解这个流程就可以尝试写简单的代码逻辑了。


    步骤1使用我们上篇文章提到的资源对象client作为Informer的参数生成Informer实例。


    步骤2是给Informer添加事件处理函数,逻辑上面讲数据结构时已经讲过这里直接上代码:


    1. fooInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
    2.    AddFunc: controller.enqueueFoo,
    3.    UpdateFunc: func(old, new interface{}) {
    4.       controller.enqueueFoo(new)
    5.    },
    6. })


    有了步骤2资源再变更就会有事件触发,事件触发相应的函数,把资源对象加入工作队列。


    步骤3是创建控制器实例:


    1. controller := NewController(kubeClient, exampleClient,
    2.    kubeInformerFactory.Apps().V1().Deployments(),
    3.    exampleInformerFactory.Samplecontroller().V1alpha1().Foos())


    步骤4是启动控制器:


    1. // Launch two workers to process Foo resources

      for i := 0; i < threadiness; i++ {

        go wait.Until(c.runWorker, time.Second, stopCh)

    2. }


    可以看到实际是启动两个协程做worker。


    步骤5是在协程worker中开始从工作队列取出任务执行。


    步骤6是最核心的地方,从工作队列中取出资源名称,通过资源的Informer client取出本地的缓存数据,这个就是资源的期望状态,知道资源的期望状态就可以做一些事情了。几种典型应用场景:


    (1)数据找不到了,期望状态是删除这时就要写删除数据的逻辑,把集群中实际的资源删除。

    (2)数据在本地缓存有,但是集群中没有,那就新创建资源。

    (3)本地缓存与集群中都有,以本地缓存为准更新集群中的资源以达到期望状态


    以上就是自定义控制器的核心内容介绍,因为篇幅限制这里没有大幅的源代码,但是核心的点本篇都已经提到,剩下的就是以上面的介绍为切入点,理解控制器的工作机制,读懂核心代码,尝试去实际操作,享受K8S可编程扩展带来的便利。基于K8S的创新项目正在以爆炸之势增长,了解扩展机制就有了创新的基础,点燃了一株孱弱的小火苗,不要小看了它谁知道它明天能不能燎原呢?

    分享到:

    Copyright ©2011 - 2016 北京乐虎国际官网登录科技有限责任公司    京ICP备14057888号  | 技术支持:因脉科技 

    北京市海淀区中关村互联网文化创意产业园15号楼A座二层 010 - 6549 9766

    中国江苏省南京市栖霞区仙林大道16号长三角总部经济园1011室 025-85560266

  • 首页
  • 产品
  • T2Cloud云产品
  • 计算
  • 网络
  • 存储
  • 运维
  • 兼容与开放
  • 服务
  • 生态
  • 产品试用
  • 客户案例
  • 合作伙伴
  • 关于我们
  • 乐虎国际官网登录 
  • 公司动态
  • T2cloud社区
  • 大事记 
  • 加入我们
  • 联系我们