K8S之自定义Controller
简介
在此之前我们先来了解下kubernetes的两个概念"声明式API"和"控制器模式"。
"声明式API"核心原理就是当用户向kubernetes提交了一个API对象的描述后,Kubernetes会负责为你保证整个集群里各项资源的状态,都与你的API对象描述的需求相一致。而对于每个保存在etcd里的API对象,kubernetes都通过启动一种叫做"控制器模式"的无限循环,不断检查,然后调谐,最后确保整个集群的状态与这个API对象的描述一致。在kubernetes中,我们所熟悉的deployment\statefulset都是其自带的一些控制器。
k8s提供了强大了扩展能力来操作它里面的资源,
这些资源可以是内置资源,比如pod、node等,也可以自定义资源CRD。
对于自定义资源,稍微麻烦些,我们需要做如下几步:
自定义CRD
通过k8s提供的代码生成器自动生成基础代码
编写自己的业务逻辑,也就是自定义controller来操作CRD
对于内置资源,我们就只需第三步就可以了。
注:CRD+自定义controller又被称作operator
https://github.com/operator-framework/awesome-operators" href="https://github.com/operator-framework/awesome-operators%2a%2a%2a">https://github.com/operator-framework/awesome-operators*
自定义CRD
比如我们想模仿pod的yaml那样自定义一个资源:
apiVersion: xxxx/v1beta1
kind: TsTest
metadata:name: tstest-sample
spec:# Add fields heredeploymentName: tstest-sample-deploymentreplicas: 2 如果我们直接kubectl create 这个yaml文件会报错,因为k8s不认识这个资源,
那怎样才能让k8s识别我们的自定义资源呢,需要像下面这样创建一个自定义资源描述文件,标准格式如下:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:# 名字必需与下面的 spec 字段匹配,并且格式为 '<名称的复数形式>.<组名>'name: tstests.stable.example.com
spec:# 组名称,用于 REST API: /apis/<组>/<版本>group: stable.example.com# 列举此 CustomResourceDefinition 所支持的版本versions:- name: v1# 每个版本都可以通过 served 标志来独立启用或禁止served: true# 其中一个且只有一个版本必需被标记为存储版本storage: trueschema:openAPIV3Schema:type: objectproperties:spec:type: objectproperties:cronSpec:type: stringimage:type: stringreplicas:type: integer# 可以是 Namespaced 或 Clusterscope: Namespacednames:# 名称的复数形式,用于 URL:/apis/<组>/<版本>/<名称的复数形式>plural: tstests# 名称的单数形式,作为命令行使用时和显示时的别名singular: tstest# kind 通常是单数形式的驼峰编码(CamelCased)形式。你的资源清单会使用这一形式。kind: TsTest# shortNames 允许你在命令行使用较短的字符串来匹配资源shortNames:- ts 上面就定义了一个叫TsTest的crd,然后通过kubectl命令创建它,此时我们再次执行我们最开始定义的那个资源文件,就不会报错了,并且也可以像pod那样CRUD操作了
但是上面的那些都只是让k8s能够识别我们自定义的这个资源,当我们通过yaml文件创建这个资源的时候,k8s也只是将这个资源记录在了etcd中了而已,没有触发任何的业务逻辑。
自定义controller
k8s提供了一个专门的client-go库来简化开发者扩展k8s的代码编写,编写自定义controller也是基于client-go库,因此实现自定义controller大致就是:
第1步是listwatch的初始化,主要是返回一个针对某类资源的ListFunc和WatchFunc。
第2步是informer的初始化,新建Indexer并将上述Listwatcher一同放入informer结构中
第3步是给informer添加AddEventHandler(通常包含add update delete),并根据情况引入workqueue(可是默认的也可以是限速、延时等队列)
第4步是启动informer.Run(),然后等待同步完成
第5步是worker的启动,监听退出信号等待退出。
其实一个controller就是一个生产者和消费者模式,上面的1-4对应的就是生产者操作,5步对应的就是消费者操作。
下面以简单的示例代码来看:
//Create the endpoints watcher,endpointsQueue,endpointController
endpointsListWatcher := cache.NewListWatchFromClient(clientset.CoreV1().RESTClient(),"endpoints", v1.NamespaceAll, fields.Everything())
endpointsQueue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
endpointsIndexer, endpointsInformer := cache.NewIndexerInformer(endpointsListWatcher, &v1.Endpoints{}, ReSyncPeriod,cache.ResourceEventHandlerFuncs{AddFunc: c.addEndpoints,DeleteFunc: c.deleteEndpoints,UpdateFunc: c.updateEndpoints,}, cache.Indexers{})//Create the configmap watcher,endpointsQueue,endpointController
configmapListWatcher := cache.NewListWatchFromClient(clientset.CoreV1().RESTClient(),"configmaps", v1.NamespaceAll, fields.Everything())
configmapQueue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
configmapIndexer, configmapInformer := cache.NewIndexerInformer(configmapListWatcher, &v1.ConfigMap{}, ReSyncPeriod,cache.ResourceEventHandlerFuncs{AddFunc: c.addConfigMap,DeleteFunc: c.deleteConfigMap,UpdateFunc: c.updateConfigMap,}, cache.Indexers{})c.endpointsQueue = endpointsQueue
c.endpointsIndexer = endpointsIndexer
c.endpointsInformer = endpointsInformerc.configmapQueue = configmapQueue
c.configmapIndexer = configmapIndexer
c.configmapInformer = configmapInformer 上面的代码就是对应1-2步
go c.endpointsInformer.Run(stopCh)
go c.configmapInformer.Run(stopCh)
go c.informerFactory.Start(stopCh)
go c.stsplusInformerFactory.Start(stopCh)//Wait for all involved caches to be synced, before processing items from the endpointsQueue is started
//if !cache.WaitForCacheSync(stopCh, c.endpointsInformer.HasSynced, c.configmapInformer.HasSynced) {
if !cache.WaitForCacheSync(stopCh, c.endpointsInformer.HasSynced, c.configmapInformer.HasSynced, c.podListerSynced, c.stsplusListerSynced) {runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))return
} 上面这段代码对应的就是3-4步。
for i := 0; i < threadiness; i++ {go wait.Until(c.runEndPointsProcessWorker, time.Second, stopCh)go wait.Until(c.runConfigmapProcessWorker, time.Second, stopCh)
}<-stopChfunc (c *Controller) processEndPointsEvents() bool {seelog.Infof("[processEndPointsEvents]: start to processEndPointsEvents")endpointsKey, endpointsQuit := c.endpointsQueue.Get()//Wait until there is a new item in the working endpointsQueuefor ;!endpointsQuit; endpointsKey, endpointsQuit = c.endpointsQueue.Get(){defer c.endpointsQueue.Done(endpointsKey)//Handle the error if something went wrong during the execution of the updateRoute methodgo c.handleRoute(endpointsKey.(string))//defer c.handleErr(endpointsErr, endpointsKey)//c.endpointsQueue.Done(endpointsKey)}return true
} 上面这段代码对应的就是5步。
到目前为止,一个自定义controller的模式化代码就完成了,剩下的就是具体的业务代码了,
因此可以看出,依靠k8s提供的这个client-go库,真正的做到了开发者只需关注业务开发,基础相关的代码都已经被封装了。
源码分析
代码太多,后面有时间再分析吧,先上个总结:
Reflector使用ListAndWatch方法,先从apiserver中list某类资源的所有实例,拿到对象的最新版本,
然后用watch方法监听该resourceversion之后的所有变化,若中途出现异常,reflector则会从断开的resourceversion处重新监听所有变化
一旦有Add、Del、Update动作,Reflector会收到更新通知,该事件及它所对应的API对象这个组合,被称为增量Delta,它会被放进DeltaFIFO中
Informer会不断从这个DeltaFIFO中读取增量,每拿出一个对象,Informer就会判断这个增量的事件类型,然后创建或更新本地的缓存。
DeltaFIFO再pop这个事件到controller中,controller会调用事先注册到ResourceEventHandler回调函数进行处理。
【Kubebuilder】
因为对于k8s内置的资源来说,client-go已经提供了对应的infomer、cache、listenAndWatch等操作,但是对于自定义资源来说,如果要编写自定义controller,这些都得自己编写这些样板代码,基于此,社区针对k8s的api扩展,提供了一个通用的工具来自动生成脚手架,这个工具就是Kubebuilder
Kubebuilder 是一个基于 CRD 来构建 Kubernetes API 的框架,可以使用 CRD 来构建 API、Controller 和 Admission Webhook。Kubebuilder的工作流程如下:
创建一个新的工程目录;
创建一个或多个资源 API CRD 然后将字段添加到资源;
在控制器中实现协调循环(reconcile loop),watch 额外的资源;
在集群中运行测试(自动安装 CRD 并自动启动控制器);
更新引导集成测试测试新字段和业务逻辑;
使用用户提供的 Dockerfile 构建和发布容器。
相关文章:
K8S之自定义Controller
简介 在此之前我们先来了解下kubernetes的两个概念"声明式API"和"控制器模式"。"声明式API"核心原理就是当用户向kubernetes提交了一个API对象的描述后,Kubernetes会负责为你保证整个集群里各项资源的状态,都与你的API对象…...
无线电相关的SCI期刊有哪些? - 易智编译EaseEditing
以下是几个无线电相关的SCI期刊: IEEE Transactions on Wireless Communications: 这是一个IEEE无线通信协会的期刊,主要涵盖了无线通信领域的最新研究进展,包括无线网络,通信系统和信号处理等方面。 IEEE Transacti…...
Rust - 结构体基本使用
基础代码示例 为了理解何时需要使用结构体,官方文档给了一个案例,就是计算长方形的面积,这里我们会一步一步的重构代码直到使用结构体为止。 计算长方形的面积的具体逻辑就是获取长方形的宽度和高度,然后通过公式计算出长方形的…...
29. Kubernetes 核心组件讲解——Controller Manager
本章讲解知识点 Controller Manager 概述Replication ControllerNode ControllerResourceQuota ControllerNamespace ControllerService Controller 与 Endpoint Controller1. Controller Manager 概述 1.1 基本概念 一般来说,智能系统和自动系统通常会通过一个“操作系统”…...
BetaFlight统一硬件配置文件研读之feature命令
BetaFlight统一硬件配置文件研读之feature命令 1. 源由2. 代码分析3. 实例分析4. 配置情况4.1 feature4.2 feature list4.3 feature feature_name4.4 feature -feature_name 5. 参考资料 统一硬件配置文件的设计是一种非常好的设计模式,可以将硬件和软件的工作进行解…...
ChatGPT 不好用?那你看下这份 Prompt 工程指南
作为大型语言模型接口,ChatGPT 生成的响应令人刮目相看,然而,解锁其真正威力的关键还是在于提示工程。 在本文中,我们将揭示制作提示的专家级技巧,以生成更准确、更有意义的响应。无论你使用 ChatGPT 是为了服务客户、…...
冲浪杂记——
华为od是指什么? 华为OD(Open Developer Platform)是华为面向全球开发者推出的开放平台,旨在为开发者提供丰富的技术资源和开发工具,支持开发者快速构建基于华为技术的应用程序、解决方案和服务。华为OD平台为开发者提…...
深入理解Python中的进程与线程
前言 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务并发的执行,从而…...
Data retry场景介绍
本文介绍PDN激活失败或者IP Address缺失时的处理机制。 终端是否会retry? 如何设置data retry timer? Modem retry还是上层应用发起retry? IPV4V6 Fallback 3GPP TS 24.008 6.1.3.1定义了UE使用IPV4V6 pdp type建PDN失败后,如果网络以#Cause50、#Cause51或者#Cause52 …...
lua | 数组与迭代器的使用
目录 一、数组 一维数组 多维数组 二、迭代器 泛型for迭代器 无状态的迭代器 多状态的迭代器 本文章为笔者学习分享 学习网站:Lua 基本语法 | 菜鸟教程 一、数组 数组:相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数…...
【云原生】云原生服务网格流量控制思考
文章目录 前言一、什么是流量控制?二、存在三种场景三、场景分析 前言 随着云原生技术的不断发展及应用,很多服务都已部署上云。 保障云上环境的稳定是重要的一环。 一个重要的影响稳定的场景就是突发大流量冲击。 面对该场景,较好的应对…...
《数据库的嵌套查询和统计查询》
选择Study数据库,用SQL语句进行以下查询操作。 1.嵌套查询 ①求选修了数据结构的学生学号和成绩。 SELECT Sno, grade FROM sc WHERE Cno 007;②求007课程的成绩高于于文轩的学生学号和成绩。 SELECT Sno, grade FROM sc WHERE Cno 007 AND grade …...
【网站架构】Nginx 4层、7层代理配置,正向代理、反向代理详解
大家好,欢迎来到停止重构的频道。 本期我们讨论网络代理。 在往期《大型网站 安全性》介绍过,出于网络安全的考虑,一般大型网站都需要做网络区域隔离,以防止攻击者直接操控服务器。 网站系统的应用及数据库都会放在这个网络安全…...
mysql备份和恢复
mysql备份和恢复 数据丢失的原因: 程序错误 人为操作错误 运算错误 磁盘故障 灾难(火灾,地震)和盗窃 数据库备份分类 物理备份 数据库此操作系统的物理文件(数据文件,日志文件等)的备份 …...
新闻月刊 | GBASE 4月市场动态一览
产品动态 4月,GBASE南大通用大规模分布式并行数据库GBase 8a MPP Cluster中标人保财险“2022年基础软件产品及服务采购”项目。这是自2019年GBASE与人保财险达成合作以来支持建设的第三期项目。项目上线后,将极大满足人保财险大数据中心及研发中心的增量…...
Java --- springboot2数据响应与内容协商
目录 一、数据响应与内容协商 1.1、响应json 1.1.1、返回值解析器 1.1.2、springMVC支持的返回值类型 1.1.3、HttpMessageConverter原理 1.2、内容协商 1.2.1、引入依赖 1.2.2、 postman分别测试返回json和xml 1.2.3、开启浏览器参数方式内容协商功能 1.3、自定义 Message…...
“中特估”乘风破浪!后续机遇在哪?
5月第一个交易日,“中特估”继续乘风破浪,A股银行板块集体大涨。 随着新一轮国企改革正在推进,中特估体系也在积极构建之中。在市场缺乏增量资金背景下,市场选股范式已经转向数字经济AI、央国企价值重估的两条主线,此…...
OpenShift 4 - 在 CI/CD Pipeline 中创建 KubeVirt 容器虚拟机 - 方法3
《OpenShift / RHEL / DevSecOps 汇总目录》 说明:本文已经在支持 OpenShift 4.12 的 OpenShift 环境中验证 文章目录 创建并运行 CI/CD Pipeline访问 VMPipeline 的 Task 解读 创建并运行 CI/CD Pipeline 执行命令,生成公钥-私钥对。 $ ssh-keygen$ l…...
功率放大器在Lamb波信号波包模型验证研究中的应用
实验名称:窄带激励条件下的兰姆波时域信号参数估计研究 研究方向:Lamb波 测试目的: 基于Lamb波的二阶频散理论,提出了时域信号的波包模型,为全文奠定理论基础。模型考虑两种情况:初始激励以单模态传播和…...
Apache Hadoop
一、Apache Hadoop入门 1.1、Hadoop介绍 狭义上:hadoop指的是Apache一款java开源软件,是一个大数据分析处理平台。 Hadoop HDFS:分布式文件系统。 解决了海量数据存储问题。 Hadoop Distributed File System (HDFS™)Hadoop MapReduce&…...
Audacity音频编辑终极指南:从零开始掌握免费专业工具
Audacity音频编辑终极指南:从零开始掌握免费专业工具 【免费下载链接】audacity Audio Editor 项目地址: https://gitcode.com/GitHub_Trending/au/audacity Audacity是一款功能强大的开源音频编辑软件,支持多轨录音、音频剪辑和效果处理&#x…...
LuatOS扩展库API——【airlbs 】airlbs 定位服务
LuatOS 是物联网终端开发的常用工具,为轻量级嵌入式 Lua 脚本运行框架兼实时系统,基于 Lua 5.3 深度优化,适配 4G-Cat.1、MCU 等物联网终端硬件。其以 Lua 脚本开发,采用协程多任务架构,配套完善开发资源,含…...
2PG450x500双齿辊破碎机CAD装配图
2PG450x500双齿辊破碎机CAD装配图是机械设计领域中用于呈现设备整体结构的关键学习资料。该设备通过两个同步旋转的齿辊实现物料的破碎功能,其核心作用在于将大块物料均匀破碎至指定粒度,满足后续加工或输送需求。装配图以二维工程语言精准描述各部件的相…...
QMCDecode:免费解锁QQ音乐加密文件的终极解决方案
QMCDecode:免费解锁QQ音乐加密文件的终极解决方案 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下载目录,默认转换结…...
如何快速掌握KLayout:专业版图设计的终极实战指南
如何快速掌握KLayout:专业版图设计的终极实战指南 【免费下载链接】klayout KLayout Main Sources 项目地址: https://gitcode.com/gh_mirrors/kl/klayout KLayout是一款功能强大的开源版图设计工具,专门用于集成电路(IC)和…...
SDMatte Web界面实操手册:从上传到下载透明PNG的完整步骤
SDMatte Web界面实操手册:从上传到下载透明PNG的完整步骤 1. 认识SDMatte:你的智能抠图助手 SDMatte是一款专为高质量图像抠图设计的AI工具,它能帮你轻松完成各种复杂的抠图任务。想象一下,你拍了一张漂亮的玻璃杯照片ÿ…...
中国 AI 大模型应用市场趋势分析报告
中国 AI 大模型应用市场趋势分析报告 报告类型:新兴趋势识别 蓝海机会评估 覆盖市场:中国大陆 数据时效:截至 2026 年 3 月 研究方法:多源数据交叉验证(艾媒咨询、中商情报、36氪研究院、虎嗅、中国工业互联网研究院等…...
消费级GPU福音:OpenClaw+百川2-13B量化版显存占用实测
消费级GPU福音:OpenClaw百川2-13B量化版显存占用实测 1. 为什么关注显存占用? 去年折腾大模型本地部署时,最头疼的就是显存问题。我的RTX3060显卡只有12GB显存,跑Llama2-13B原版模型时,加载阶段就直接爆显存。直到发…...
TranslucentTB:打造高效透明任务栏的终极指南
TranslucentTB:打造高效透明任务栏的终极指南 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB TranslucentTB 是一款专为 Wind…...
哈尔滨全屋定制厂家:值得信赖的筛选逻辑深度解析
哈尔滨全屋定制厂家筛选逻辑深度解析:5步找到值得信赖的本地品牌 “哈尔滨全屋定制厂家选择,不是看广告多响,而是这5个筛选逻辑能帮你避开90%的坑”。对于准备在哈尔滨做全屋定制的业主来说,选对厂家直接决定了最终效果与性价比&…...
