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

K8S之自定义Controller

简介

在此之前我们先来了解下kubernetes的两个概念"声明式API"和"控制器模式"。
"声明式API"核心原理就是当用户向kubernetes提交了一个API对象的描述后,Kubernetes会负责为你保证整个集群里各项资源的状态,都与你的API对象描述的需求相一致。而对于每个保存在etcd里的API对象,kubernetes都通过启动一种叫做"控制器模式"的无限循环,不断检查,然后调谐,最后确保整个集群的状态与这个API对象的描述一致。在kubernetes中,我们所熟悉的deployment\statefulset都是其自带的一些控制器。

k8s提供了强大了扩展能力来操作它里面的资源,
这些资源可以是内置资源,比如pod、node等,也可以自定义资源CRD。

对于自定义资源,稍微麻烦些,我们需要做如下几步:

  1. 自定义CRD

  2. 通过k8s提供的代码生成器自动生成基础代码

  3. 编写自己的业务逻辑,也就是自定义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, &amp;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, &amp;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库,真正的做到了开发者只需关注业务开发,基础相关的代码都已经被封装了。

源码分析

代码太多,后面有时间再分析吧,先上个总结:

  1. Reflector使用ListAndWatch方法,先从apiserver中list某类资源的所有实例,拿到对象的最新版本,

  2. 然后用watch方法监听该resourceversion之后的所有变化,若中途出现异常,reflector则会从断开的resourceversion处重新监听所有变化

  3. 一旦有Add、Del、Update动作,Reflector会收到更新通知,该事件及它所对应的API对象这个组合,被称为增量Delta,它会被放进DeltaFIFO中

  4. Informer会不断从这个DeltaFIFO中读取增量,每拿出一个对象,Informer就会判断这个增量的事件类型,然后创建或更新本地的缓存。

  5. 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的工作流程如下:

  1. 创建一个新的工程目录;

  2. 创建一个或多个资源 API CRD 然后将字段添加到资源;

  3. 在控制器中实现协调循环(reconcile loop),watch 额外的资源;

  4. 在集群中运行测试(自动安装 CRD 并自动启动控制器);

  5. 更新引导集成测试测试新字段和业务逻辑;

  6. 使用用户提供的 Dockerfile 构建和发布容器。

相关文章:

K8S之自定义Controller

简介 在此之前我们先来了解下kubernetes的两个概念"声明式API"和"控制器模式"。"声明式API"核心原理就是当用户向kubernetes提交了一个API对象的描述后&#xff0c;Kubernetes会负责为你保证整个集群里各项资源的状态&#xff0c;都与你的API对象…...

无线电相关的SCI期刊有哪些? - 易智编译EaseEditing

以下是几个无线电相关的SCI期刊&#xff1a; IEEE Transactions on Wireless Communications&#xff1a; 这是一个IEEE无线通信协会的期刊&#xff0c;主要涵盖了无线通信领域的最新研究进展&#xff0c;包括无线网络&#xff0c;通信系统和信号处理等方面。 IEEE Transacti…...

Rust - 结构体基本使用

基础代码示例 为了理解何时需要使用结构体&#xff0c;官方文档给了一个案例&#xff0c;就是计算长方形的面积&#xff0c;这里我们会一步一步的重构代码直到使用结构体为止。 计算长方形的面积的具体逻辑就是获取长方形的宽度和高度&#xff0c;然后通过公式计算出长方形的…...

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. 参考资料 统一硬件配置文件的设计是一种非常好的设计模式&#xff0c;可以将硬件和软件的工作进行解…...

ChatGPT 不好用?那你看下这份 Prompt 工程指南

作为大型语言模型接口&#xff0c;ChatGPT 生成的响应令人刮目相看&#xff0c;然而&#xff0c;解锁其真正威力的关键还是在于提示工程。 在本文中&#xff0c;我们将揭示制作提示的专家级技巧&#xff0c;以生成更准确、更有意义的响应。无论你使用 ChatGPT 是为了服务客户、…...

冲浪杂记——

华为od是指什么&#xff1f; 华为OD&#xff08;Open Developer Platform&#xff09;是华为面向全球开发者推出的开放平台&#xff0c;旨在为开发者提供丰富的技术资源和开发工具&#xff0c;支持开发者快速构建基于华为技术的应用程序、解决方案和服务。华为OD平台为开发者提…...

深入理解Python中的进程与线程

前言 今天我们使用的计算机早已进入多CPU或多核时代&#xff0c;而我们使用的操作系统都是支持“多任务”的操作系统&#xff0c;这使得我们可以同时运行多个程序&#xff0c;也可以将一个程序分解为若干个相对独立的子任务&#xff0c;让多个子任务并发的执行&#xff0c;从而…...

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迭代器 无状态的迭代器 多状态的迭代器 本文章为笔者学习分享 学习网站&#xff1a;Lua 基本语法 | 菜鸟教程 一、数组 数组&#xff1a;相同数据类型的元素按一定顺序排列的集合&#xff0c;可以是一维数组和多维数…...

【云原生】云原生服务网格流量控制思考

文章目录 前言一、什么是流量控制&#xff1f;二、存在三种场景三、场景分析 前言 随着云原生技术的不断发展及应用&#xff0c;很多服务都已部署上云。 保障云上环境的稳定是重要的一环。 一个重要的影响稳定的场景就是突发大流量冲击。 面对该场景&#xff0c;较好的应对…...

《数据库的嵌套查询和统计查询》

选择Study数据库&#xff0c;用SQL语句进行以下查询操作。 1&#xff0e;嵌套查询 ①求选修了数据结构的学生学号和成绩。 SELECT Sno, grade FROM sc WHERE Cno 007;②求007课程的成绩高于于文轩的学生学号和成绩。 SELECT Sno, grade FROM sc WHERE Cno 007 AND grade …...

【网站架构】Nginx 4层、7层代理配置,正向代理、反向代理详解

大家好&#xff0c;欢迎来到停止重构的频道。 本期我们讨论网络代理。 在往期《大型网站 安全性》介绍过&#xff0c;出于网络安全的考虑&#xff0c;一般大型网站都需要做网络区域隔离&#xff0c;以防止攻击者直接操控服务器。 网站系统的应用及数据库都会放在这个网络安全…...

mysql备份和恢复

mysql备份和恢复 数据丢失的原因&#xff1a; 程序错误 人为操作错误 运算错误 磁盘故障 灾难&#xff08;火灾&#xff0c;地震&#xff09;和盗窃 数据库备份分类 物理备份 数据库此操作系统的物理文件&#xff08;数据文件&#xff0c;日志文件等&#xff09;的备份 …...

新闻月刊 | GBASE 4月市场动态一览

产品动态 4月&#xff0c;GBASE南大通用大规模分布式并行数据库GBase 8a MPP Cluster中标人保财险“2022年基础软件产品及服务采购”项目。这是自2019年GBASE与人保财险达成合作以来支持建设的第三期项目。项目上线后&#xff0c;将极大满足人保财险大数据中心及研发中心的增量…...

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月第一个交易日&#xff0c;“中特估”继续乘风破浪&#xff0c;A股银行板块集体大涨。 随着新一轮国企改革正在推进&#xff0c;中特估体系也在积极构建之中。在市场缺乏增量资金背景下&#xff0c;市场选股范式已经转向数字经济AI、央国企价值重估的两条主线&#xff0c;此…...

OpenShift 4 - 在 CI/CD Pipeline 中创建 KubeVirt 容器虚拟机 - 方法3

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在支持 OpenShift 4.12 的 OpenShift 环境中验证 文章目录 创建并运行 CI/CD Pipeline访问 VMPipeline 的 Task 解读 创建并运行 CI/CD Pipeline 执行命令&#xff0c;生成公钥-私钥对。 $ ssh-keygen$ l…...

功率放大器在Lamb波信号波包模型验证研究中的应用

实验名称&#xff1a;窄带激励条件下的兰姆波时域信号参数估计研究 研究方向&#xff1a;Lamb波 测试目的&#xff1a; 基于Lamb波的二阶频散理论&#xff0c;提出了时域信号的波包模型&#xff0c;为全文奠定理论基础。模型考虑两种情况&#xff1a;初始激励以单模态传播和…...

Apache Hadoop

一、Apache Hadoop入门 1.1、Hadoop介绍 狭义上&#xff1a;hadoop指的是Apache一款java开源软件&#xff0c;是一个大数据分析处理平台。 Hadoop HDFS&#xff1a;分布式文件系统。 解决了海量数据存储问题。 Hadoop Distributed File System (HDFS™)Hadoop MapReduce&…...

PHP+vue大学生心理健康评价和分析系统8w3ff

本整个大学生心理健康管理系统是按照整体需求来实现各个功能的&#xff0c;它可以通过心理健康测评来检测大学生的心理健康&#xff0c;并且给予预警&#xff0c;还可以预约医生来解决问题。并且&#xff0c;管理员可以查看用户信息&#xff0c;发布一些关于心理健康的文章。该…...

【图像分割】【深度学习】SAM官方Pytorch代码-Mask decoder模块MaskDeco网络解析

【图像分割】【深度学习】SAM官方Pytorch代码-Mask decoder模块MaskDeco网络解析 Segment Anything&#xff1a;建立了迄今为止最大的分割数据集&#xff0c;在1100万张图像上有超过1亿个掩码&#xff0c;模型的设计和训练是灵活的&#xff0c;其重要的特点是Zero-shot(零样本迁…...

A Restful API

SpringBoot 定义Restful API 定义POJOOrderBuyer 定义RestfulControllerGet API for queryPost API for addPut API for updateDelete API for delete 定义AjaxResponse Patavariable RequestParm RequestBodyRequestHeader 定义POJO Order import java.util.Date; import ja…...

从零开始学习JSP,让你全面掌握Web开发技能

JSP&#xff08;Java Server Pages&#xff09;&#xff0c;是一种动态网页技术&#xff0c;它允许开发者使用Java代码和HTML标签来创建网页。在这篇文章中&#xff0c;我们将详细介绍JSP的基本概念、语法和应用。 一、JSP的基本概念 1.1 JSP的含义 JSP是一种网页技术&#…...

java基于知识库的中医药问询系统

本系统主要包含了等系统用户管理、中医药常识管理、科室信息管理、知识库管理多个功能模块。下面分别简单阐述一下这几个功能模块需求。 管理员的登录模块&#xff1a;管理员登录系统对本系统其他管理模块进行管理。 用户的登录模块&#xff1a;用户登录本系统&#xff0c;对个…...

【新星计划-2023】什么是ARP?详解它的“解析过程”与“ARP表”。

一、什么是ARP ARP&#xff08;地址解析协议&#xff09;英文全称“Address Resolution Protocol”&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机&#xff0c;并接收返回消息&#xff0c;以此确…...

自动驾驶行业观察之2023上海车展-----车企发展趋势(2)

自主品牌发展 比亚迪&#xff1a;展示3款新车&#xff0c;均于2023年年内上市 比亚迪在本次展会上推出了3款新车&#xff1a;宋L概念车&#xff08;王朝系列&#xff09;、驱逐舰07&#xff08;海洋系列&#xff09;、海鸥&#xff08;海洋系列&#xff09;。 • 宋L&#x…...

通知所有员工所需的时间

题目描述 公司里有 n 名员工&#xff0c;每个员工的 ID 都是独一无二的&#xff0c;编号从 0 到 n - 1。公司的总负责人通过 headID 进行标识。 在 manager 数组中&#xff0c;每个员工都有一个直属负责人&#xff0c;其中 manager[i] 是第 i 名员工的直属负责人。对于总负责…...

Docker:bash: vim: command not found

进入docker容器 docker exec -it [容器ID] /bin/bash docker exec -it e56e7bbe85ad /bin/bash 在使用 Docker 容器时&#xff0c;有时候里边没有安装vim&#xff0c;敲vim命令时提示说&#xff1a;vim: command not found&#xff0c;这个时候就需要安装vim&#xff0c;可是…...

排序算法之选择排序

选择排序&#xff08;Selection Sort&#xff09;是一种简单直观的排序算法&#xff0c;其基本思路是在未排序的数据序列中找到最小元素&#xff0c;将其放在已排序的数据序列的末尾。重复该过程&#xff0c;直到整个序列排序完成。 具体实现过程如下&#xff1a; 首先&#x…...

临沂网站制作计划/免费seo关键词优化排名

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用&#xff0c;和丰富的 HTTP 工具。 使用 Express 可以快速地搭建一个完整功能的网站。Express 框架核心特性&#xff1a;可以设置中间件来响应 HTTP 请求。定义了路由表用于执行不…...

视频的网站自助建站/广州做seo的公司

part 1--入门&#xff1a;1. xcode 版本下载 以及 iphone sdk 下载&#xff1a;最新版本在此下载&#xff1a;http://developer.apple.com/devcenter/ios/index.action其他版本请看http://connect.apple.com/cgi-bin ... 1.0.1.1.0.3.3.3.3.12. 入门教程&#xff1a;http://www…...

wordpress 禁止自动保存 插件/网络营销策划书封面

变量变量&#xff1a;将运算的中间结果暂存到内存中&#xff0c;以便后续程序调用。变量的命令规则&#xff1a;变量由字母、数字、下划线组合而成。不可以数字开头&#xff0c;更不能全是数字。不能是python的关键字。不要用中文。名字要有意义。不要太长。区分大小写。推荐使…...

单招网站开发/企业网站建设公司

eclipse插件的安装方法大体有以下三种:...

农特产品网站建设合同模板/东莞百度seo

断路器 照明&#xff1a;1P 16A&#xff0c;约承受3520W功率&#xff0c;占一位&#xff1b;插座&#xff1a;1P 16A&#xff0c;约承受3520W功率&#xff0c;占一位&#xff1b;厨房、卫生间各一路&#xff1a;25A&#xff08;带漏电保护&#xff09;&#xff0c;约承受5500W…...

福州市做网站公司/搜收录批量查询

序列帧动画经常用到&#xff0c;最直接的方式就是用Animation录制。但某些情况下这种方式并不是太友好&#xff0c;需要靠代码的方式进行序列帧动画的实现。 代码实现序列帧动画&#xff0c;基本的思路是定义一个序列帧的数组/列表&#xff0c;根据时间的流逝来确定使用哪一帧…...