• Operator 基础原理和概念


    什么是operator

    定义

    operator是coreos 公司工程师在2016年提出,就是可以根据应用独有的领域逻辑编写的自定义控制器。

    如何理解operator?

    k8s的资源类型实现都要满足俩个条件:

    • 对资源类型的模型抽象,比如创建deployment 的yaml中的定义
    • 实际去处理这个资源类型抽象的控制器,例如namespace控制器,deployment控制器。并通过restful api 对外提供能力。

    上面这种资源设计方式叫做“声明式API”

    operator就是采用上面的模式实现,主要组成有:模型抽象-CRD、具体业务逻辑动作的处理-controller

    对于使用者来说,提交了定义好的CRD对象来描述期望的状态之后,无需关注处理过程,关注结果即可,过程由controller处理。

    相关概念

    CRD(costom resource definition): 自定义资源

    controller:控制器

    group/version: api组 api版本

    Kind/resouce: api类型 kind的实例

    GVK: 定义一种资源的方式,通过GVK的信息(group/version/kind)确定一个具体资源类型GVR。

    GVR: 实例化GVK定义的资源类型,体现在restful api 交互上

    GVK和GVR的转换:GVR通过rest mapper映射到对应的GVK

    api资源路径格式:/api/apps/v1/namespace/$namespace/job

    • “api/apps” : 组

    • “v1”: 版本

    • “job”: 资源

    什么是controller

    简单来说,就是控制器,控制k8s的资源实体。

    在这里插入图片描述

    client-go原理

    kubernetes官方在2016年八月把k8s资源操作相关核心源码抽离出来,组成了一个新的项目,client-go。

    client-go是k8s集群资源操作的编程式交互客户端库,通过与api server进行交互完成资源操作。

    client-go主要用于内置、自定义资源的增删查改操作,通过client-go提供的能力,就可以实现controller的能力,所以学习client-go,对我们理解controller很重要。

    目录结构

    .
    ├── CHANGELOG.md
    ├── CONTRIBUTING.md
    ├── INSTALL.md
    ├── LICENSE
    ├── OWNERS
    ├── README.md
    ├── SECURITY_CONTACTS
    ├── applyconfigurations
    ├── code-of-conduct.md
    ├── discovery   # 包含discovery客户端,用于发现api server 支持的资源信息
    ├── doc.go
    ├── dynamic     # 包含dynamic 客户端,用户对自定义k8s资源执行通过操作
    ├── examples   #client-go使用示例
    ├── go.mod
    ├── go.sum
    ├── informers   # 包含各种资源的informer实现
    ├── kubernetes   #包含k8s内置资源的clientset
    ├── kubernetes_test
    ├── listers   #提供监听服务
    ├── metadata
    ├── openapi
    ├── pkg
    ├── plugin
    ├── rest
    ├── restmapper
    ├── scale
    ├── testing
    ├── third_party
    ├── tools      #与util一起提供常用工具,便于编写controller
    ├── transport  #提供安全连接功能
    └── util 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    主体结构

    client共支持4中与api server交互的客户端逻辑。如下
    在这里插入图片描述

    • restclient:对http请求以及相关操作进行封装
    • clientset:k8s内置资源的客户端集合,仅能操作内置资源
    • discovery client:发现api server支持的资源组、资源版本和资源信息。(kubectl api-version 主要使用discovery client)
    • dynamic client:对任意k8s资源执行操作。

    架构

    client-go主要用于k8s控制其中,包括内置控制器(kube-controller-manager)和CRD控制器。client提供了编写自定义controller所使用的各种机制,如下

    • list-watch机制

      • 功能:把k8s中的对象资源存储到本地并实时更新,拥有很高的实时性、可靠性和顺序性。
      • list:调用list restful api,短链接实现,获取资源信息
      • watch:调用watch restful api,长链接实现,获取事件类型和最新的资源信息
    • reflector:使用list-watch 方法监听指定类型的资源对象,通过list获取所有实例的resouceversion,并监听在这个版本后面所有的变化,并把收到的event用反射机制处理为监控的实体对象,即把GVK转为go type

    • deltafifo:上面得到的event及它对应的实体对象组合成为增量delt。

    • localStore:通过event类型,创建和更新本地缓存,并建立索引提供快速查找的能力indexer,可以减少api server压力。

    • workqueue:deltafifo同步完localstore后,会把这个event pop到内部的controller的回调函数resourehandler,进行简单的过滤工作,最后吧变更的对象放入workqueue中,供worker控制循环处理。

    • Worker:控制循环,work执行真正的业务逻辑,通过对比状态进行动作处理

    在这里插入图片描述

    kububuilder原理

    什么是kubebuilder

    kubebuilder是一个用go语言构建kubernetes apis的框架,通过这一套编程框架,可以便捷的使用crd构建api、controller和admission webhook,实现对k8s自定义资源的扩展。

    架构

    在这里插入图片描述

    1. Kubebuilder Scaffolds是实现这个脚手架最核心的逻辑,它借助 API Scaffolder对象模块,实现了 CRD的 Template和 Controller的核心代码块。

    2. 用户主要关注Userdefined 模块,需要根据实际场景,设计 CRD的结构定义,当然这里的 CRD的数量可以有多个。

    3. 用户还需要实现 Reconcile的逻辑。这里,首先了解 Reconcile的含义,用户自定义了CRD结构,而在 Kubernetes集群中,想要实现这样的 CRD 结构定义,Reconcile 需要协调逻辑。举例来说,假设用户定义了 MysqlCluster{Name:demo,Num:3} 这样的结构体,而希望在系统中创建MySQL的集群,而构造 MySQL 集群的构造过程,就是 Reconcile过程做的工作。

    4. 运行环境,用户自定义的部分能工作的前提是要有一个 Kubernetes集群,即架构中最下面的部分,它负责安装 CRD及运行 Controller

    5. controller runtime负责运行controller,包含了schema、manager、client、cache等核心模块。

      • schema。在Controller Runtime模块中,Kubebuilder构建出来的 CRD会注册到 Scheme模块,schema模块提供了Kinds与对应的 GoType的映射,即给定了GoType,就能够知道它的GKV(GroupKindVerision),这也是Kubernetes所有资源的注册模式。举例来说,我们给定了一个Scheme,“demo1.example.org/v1”.Demo{},这个GoType映射到demo1.example.org/v1的 DemoGVK。
      {
      "apiVersion":"demo1.example.org/v1","kind":"Demo",
      "metadata":{
      ...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

      通过这个 GoType,能够正确地获取 GVR的信息,从而提供给 Controller, 获取期望的状态,即协调的逻辑。

      • manager,controller总控,负责初始化一些公共模块以及controller运行管理。

        在Controller Runtime中Controller最依赖的除了Scheme之外,还包括 Manager 的初始化、安装和启动工作。Manager 的初始化依赖 Controller Runtime库初始化 Manager对象,包括 Client、Cache 等模块的生成工作。然后调用Client就可以实现对CRD的“增、删、改、查”,而查询的逻辑是通过本地的Cache 模块实现的。这里的Cache 负责监听CRD 的变化,它是通过监听Scheme,从而收集所有与 Controller有关的GVR 资源,并创建对应的监听器,从而实现当监听到Kubernetes集群中的CRD发生变化触发 Controller的协调进程Reconcile工作。

    6. Kuberbuilder工具生成的内容还包括 Finalizer,它用于处理 Kubernetes资源的预删除逻辑,保障资源被删除后能够从 Cache中读取到,清理相关的其他资源;

    7. OwnerReference用于清理资源时, 对于任何一个对象, 若它的 OwnerReference字段值为待删除对象,则这个对象也会被清理,支持对象的变更,也会触发 Owner对象的Controller 的协调过程。

    8. Index 用于提供资源的缓存,提升客户端资源的查询效率。

    目录结构

    .
    ├── api         ## 这里定义了 sample 的结构体 GVK,以及所需的 deepcopy 实现         
    │   └── v1
    │       ├── groupversion_info.go
    │       ├── sample_types.go
    │       └── zz_generated.deepcopy.go 
    ├── bin
    │   └── manager ## controller 编译后的 二进制文件
    ├── config      ## 包含了我们在使用 crd 是可能需要的 yml 文件,包括rbac、controller的deployment 等
    │   ├── certmanager
    │   ├── crd
    │   ├── default
    │   ├── manager
    │   ├── prometheus
    │   ├── rbac
    │   ├── samples  #crd资源类型的部署yaml
    │   └── webhook
    ├── controllers         ## 我们的controller 逻辑就放在这里
    │   ├── sample_controller.go
    │   └── suite_test.go
    ├── Dockerfile          
    ├── go.mod
    ├── go.sum
    ├── hack
    │   └── boilerplate.go.txt
    ├── main.go
    ├── Makefile  #编译打包工具
    └── PROJECT
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    代码流程讲解

    1. CRD创建

      • crd go type定义
      • reconcile 协调逻辑
    2. manager 初始化

      • ctrl.NewManager -> controller runtime manager.new -> 初始化cache schema client等模块
    3. controller 初始化

      • SetupWithManager 安装crd到manager。-> controller runtime builder方法初始化controllerManager对象 -> 进一步关联crd gotype -> complate方法完成controllermanager 对象的构建,包括do controller(传递reconcile) ,do watch,实现了基于schema和controllerManager对象的CRD的注册和监听流程
      • do controller 完成controller的创建并注册到mgr,关联reconcile
      • do watch doWatch会可以watch多种资源类型,controller的Watch函数启动监控对象,其根据eventhandler(监控资源对象入队Controller.Queue前需要被EventHandler处理)、监控资源source生成watchDescription结构并添加到controller的watches数组中, 实现监控资源与Controller的绑定,等待controllerManager的启动
    4. client初始化

      • NewManager -> New -> setoptionsdefault 初始化默认的client -> 初始化读client ->初始化写client
      • 传递给controller, 初始化client -> 传给每个crd controller -> SetupWithManager 完成controller初始化
    5. manager启动

      • 启动controller生产端,启动cache -> 启动所有watch -> 启动controller,controlle.start -> 启动source,完成informer的创建、并将事件回调与informer关联起来。
      • 启动controller消费端 -> processNextWorkItem -> Do.Reconcile(req)
    6. Finalizers,是每种资源在声明周期结束时都会使用到的字段,属于k8s GC垃圾回收器,是一种删除拦截机制,可以执行一些预删除处理,需要在reconcile中实现。

      • 运行逻辑:Finalizers字段不为空时,delete -> update,更新deletetimestamp 字段,之后,如果再次检测发现finalizers为空,k8s GC可以删除该资源。

      • **使用姿势:**创建对象时定义好finalizer字段,任意string,删除资源的时候,update deletiontimestamp字段,执行所有的pre-hook操作,然后将finalizes字段值为空

    核心模块介绍

    1. controller runtime,是对client-go的部分能力的封装,也重写了部分controller组件逻辑,和clientl-go是两个用途不同的项目。

    2. manager

    3. controller

    4. client

    5. cache

    6. webhook

    参考文献

    《云原生应用开发 Operator原理与实践》

  • 相关阅读:
    RSA加密与解密原理
    Procreate iPad绘画教程
    大数据(9g)FlinkCEP
    李永乐六套卷复盘
    【C++入门】烦人的引用
    重修之Java-基础篇-流程控制
    F (1083) : DS堆栈--行编辑
    IBDP学生怎么写PS?
    八股文第十七天
    244.2-248-css-HTML5语义化元素,其他新增元素,video兼容性写法,audio
  • 原文地址:https://blog.csdn.net/qq_43490312/article/details/126663452