当前位置: 首页 > news >正文

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)确定一个具体资源类型,体现在restful api 交互上

GVR: 实例化GVK定义的资源类型

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 

主体结构

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":{
    ...
    }
    

    通过这个 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. 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

  2. manager

  3. controller

  4. client

  5. cache

  6. webhook

参考文献

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

相关文章:

  • Math对象常用的方法
  • MySQL高级篇——锁
  • 【编程题】【Scratch二级】2022.06 画正方形
  • 【学习笔记】内存的连续分配管理方式
  • 图解 cv2.HoughLines cv2.line 参数原理
  • 使用简易网络实现二分类
  • XAML笔记
  • 5个自动化小技巧:聪明的员工和管理者如何提升效率?
  • JAVA轻量级错误码设计最佳实践
  • Nidia的Deepstream,官方给的案例介绍,deepstream-test1\deepstream-tes2\deepstream-test5
  • RESTful风格学习笔记【包含示例】
  • Java:单例模式详解
  • 第十九天人工智能课程总结
  • opencv入门 二
  • Java:在Java中使用函数接口
  • bearychat的java client
  • Elasticsearch 参考指南(升级前重新索引)
  • go append函数以及写入
  • Object.assign方法不能实现深复制
  • Python 反序列化安全问题(二)
  • STAR法则
  • vue-cli在webpack的配置文件探究
  • 浮现式设计
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 技术胖1-4季视频复习— (看视频笔记)
  • 听说你叫Java(二)–Servlet请求
  • 异步
  • 整理一些计算机基础知识!
  • #vue3 实现前端下载excel文件模板功能
  • #微信小程序:微信小程序常见的配置传值
  • #预处理和函数的对比以及条件编译
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (六)Hibernate的二级缓存
  • (转) ns2/nam与nam实现相关的文件
  • (转)ABI是什么
  • (转)socket Aio demo
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET MVC之AOP
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NetCore部署微服务(二)
  • .NET导入Excel数据
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @RequestMapping-占位符映射
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [20170705]diff比较执行结果的内容.txt
  • [ai笔记4] 将AI工具场景化,应用于生活和工作
  • [Android]Android P(9) WIFI学习笔记 - 扫描 (1)
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • [BZOJ4337][BJOI2015]树的同构(树的最小表示法)
  • [C# 开发技巧]实现属于自己的截图工具
  • [flink总结]什么是flink背压 ,有什么危害? 如何解决flink背压?flink如何保证端到端一致性?