controller-runtime搭建operator开发环境
目录
基本结构
注入CRD
基本结构
首先下载相应的go pkg
go get -u sigs.k8s.io/controller-runtime
接下来需要创建控制器和Manager
Operator的本质是一个可重入的队列编程模式,而Manager可以用来管理Controller、Admission Webhook,包括访问资源对象的client、cache、scheme、提供了一个简单的依赖注入机制、优雅关闭的信号处理机制等。

参见官方文档中的示例代码
opsController.go
package kubeimport ("context""sigs.k8s.io/controller-runtime/pkg/client""sigs.k8s.io/controller-runtime/pkg/reconcile"
)type OpsController struct {client.Client
}func NewOpsController() *OpsController {return &OpsController{}
}func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {return reconcile.Result{}, nil
}func (a *OpsController) InjectClient(c client.Client) error {a.Client = creturn nil
}
先监听官方资源,比如Ingress(后续需要在Manager中指定),因此将调谐函数补全为
func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {resource := &v1.Ingress{}a.Client.Get(ctx, req.NamespacedName, resource)fmt.Println(resource)return reconcile.Result{}, nil
}
当有一个新的Ingress对象被提交到Apiserver,都会将整个结构打印在控制台上。
package kubeimport (v1 "k8s.io/api/networking/v1""os""sigs.k8s.io/controller-runtime/pkg/builder""sigs.k8s.io/controller-runtime/pkg/client/config"logf "sigs.k8s.io/controller-runtime/pkg/log""sigs.k8s.io/controller-runtime/pkg/log/zap""sigs.k8s.io/controller-runtime/pkg/manager""sigs.k8s.io/controller-runtime/pkg/manager/signals"
)func InitManager() {logf.SetLogger(zap.New())var log = logf.Log.WithName("builder-examples")mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{})if err != nil {log.Error(err, "could not create manager")os.Exit(1)}err = builder.ControllerManagedBy(mgr). // Create the ControllerManagedByFor(&v1.Ingress{}). // ReplicaSet is the Application APIComplete(NewOpsController())if err != nil {log.Error(err, "could not create controller")os.Exit(1)}if err := mgr.Start(signals.SetupSignalHandler()); err != nil {log.Error(err, "could not start manager")os.Exit(1)}
}
在这段代码中,将Ingress的指挥权分配给了刚才创建的Controller(可以同时被多个Controller管理),并且启动Manager,这里其实也是operator的入口函数。
随便提交一个Ingress对象,控制台输出打印,结束。
至此,我们完成了一个Operator最基本的调用过程。
注入CRD
Operator=CRD+Controller+Webhook
在实际的环境中,往往需要高度定制的资源,来完成复杂的流程控制和预期导向。
所以,这一小节就来生成CRD以及完成对CR的监听和控制。
同样是在源码中,可以发现一段示例代码,就是上述实现的一个demo。
其中,完成了对CRD的申明,深拷贝,和对外暴露的注册函数。
Kubernetes官方发布的代码生成脚手架code-generator中也有对此的一段实现代码。
根据这段demo,需要填入CRD的一些预设字段,用来创建Manager监听对象以及Controller在调用client-go时的反序列化操作。
在启动Manager之前,需要将CRD注册到Scheme中去,并且加入对CRD的控制与分配控制器。
err = v1.AddToScheme(mgr.GetScheme())if err != nil {log.Error(err, "could not register scheme")}err = builder.ControllerManagedBy(mgr). // Create the ControllerManagedByFor(&v1.Operation{}). // ReplicaSet is the Application APIComplete(NewOpsController())if err != nil {log.Error(err, "could not create controller")os.Exit(1)}
修改调谐函数,对触发的对象打印到控制台。
func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {resource := &v1.Operation{}err := a.Client.Get(ctx, req.NamespacedName, resource)if err != nil {return reconcile.Result{}, err}fmt.Println(resource)return reconcile.Result{}, nil
}
参考官方文档 ,需要编辑一个yaml并应用,这里同样是进行字段的申明,主要是将对象提交到Apiserver中去。
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:# 名字必需与下面的 spec 字段匹配,并且格式为 '<名称的复数形式>.<组名>'name: operations.extensions.octoboy.com
spec:# 组名称,用于 REST API: /apis/<组>/<版本>group: extensions.octoboy.com# 列举此 CustomResourceDefinition 所支持的版本versions:- name: v1# 每个版本都可以通过 served 标志来独立启用或禁止served: true# 其中一个且只有一个版本必需被标记为存储版本storage: trueschema:openAPIV3Schema:type: objectproperties:spec:type: objectproperties:action:type: string# 可以是 Namespaced 或 Clusterscope: Namespacednames:# 名称的复数形式,用于 URL:/apis/<组>/<版本>/<名称的复数形式>plural: operations# 名称的单数形式,作为命令行使用时和显示时的别名singular: operation# kind 通常是单数形式的驼峰命名(CamelCased)形式。你的资源清单会使用这一形式。kind: Operation# shortNames 允许你在命令行使用较短的字符串来匹配资源shortNames:- ops
然后启动我们的Operator,并简单编写一个对象yaml。
apiVersion: extensions.octoboy.com/v1
kind: Operation
metadata:name: myopsnamespace: default
spec:action: "restart"
同时应用,观察到控制台输出
&{{Operation extensions.octoboy.com/v1} {myops default 1344e481-4db4-461d-8d8d-b07713a76236 3927679 1 2023-03-07 14:21:09 +0800 CST <nil> <nil> map[] map[kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"extensions.octoboy.com/v1","kind":"Operation","metadata":{"annotations":{},"name":"myops","namespace":"default"},"spec":{"action":"restart"}}
] [] [] [{kubectl-client-side-apply Update extensions.octoboy.com/v1 2023-03-07 14:21:09 +0800 CST FieldsV1 {"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}},"f:spec":{".":{},"f:action":{}}} }]} {} {0001-01-01 00:00:00 +0000 UTC}}
至此,通过controller-runtime搭建起了一个简易的Operator控制器。
相关文章:
controller-runtime搭建operator开发环境
目录 基本结构 注入CRD 基本结构 首先下载相应的go pkg go get -u sigs.k8s.io/controller-runtime 接下来需要创建控制器和Manager Operator的本质是一个可重入的队列编程模式,而Manager可以用来管理Controller、Admission Webhook,包括访问资源对…...
FPGA使用GTX实现SFP光纤收发SDI视频 全网首创略显高端 提供工程源码和技术支持
目录1、前言2、设计思路和框架3、vivado工程详解4、上板调试验证并演示5、福利:工程代码的获取1、前言 FPGA实现SDI视频编解码目前有两种方案: 一是使用专用编解码芯片,比如典型的接收器GS2971,发送器GS2972,优点是简…...
Django 之 CharField 和 TextField
CharField test_char models.CharField(max_length288)设置长度为 288 并不会报错,这取决于你的数据库后端,mysql char 类型长度为 255,django 里面设置超过 255 并不会有提示,个人感觉有点误导人,起码给个警告也行&…...
recyclerview 使用的坑
1.有不同的布局 12_GridLayoutManager setSpanSizeLookup()方法 - 简书 setSpanSizeLookup 这个方法要会 spanCount和 getSpanSize spanCount/getSpanSize() 才是这一项所占的宽度 2.均分 item布局要设置宽度为match_paraent 3.设置完了。发现高度不一样,…...
DBeaver连接mysql、oracle数据库
1. DBeaver连接mysql 1) 下载DBeaver https://dbeaver.io/download/,并安装 2) 新建数据库连接 3)选择mysql驱动程序 4)填写连接设置内容 5)点击 “编辑驱动设置”,并填写相关信息 6)选择本地…...
Kivy GridLayout 布局
Kivy GridLayout 是一种用于构建用户界面的布局类型,可以帮助我们快速创建具有固定列和行的网格布局。GridLayout 布局是可以适用于任意数量的行和列的布局,然后在这些行和列中放置 UI 元素。 Kivy 的 GridLayout 使用起来类似于 HTML 的表格,…...
Spark高手之路2—Spark安装配置
文章目录Spark 运行环境一、Local 模式1. 下载压缩包2.上传到服务器3. 解压4. 启动 Local 环境5. 命令行工具6. 退出本地模式7. 提交应用二、Standalone 模式1. 解压2. 修改配置文件1)进入解压缩后路径的 conf 目录,复制 workers.template 文件为 worker…...
Java中对象的比较
目录元素的比较基本类型的比较引用类型的比较1. 覆写基类的equals2. 基于Comparble接口类的比较3. 基于比较器比较三种方法对比元素的比较 基本类型的比较 这里就拿整型, 字符型, 布尔型 为例: public static void main(String[] args) {int a 10;int b 20;System.out.pri…...
Python编程训练题2
1.11 有 n 盏灯,编号 1~n(0<n<100)。第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关(这些灯将被关掉),第 3 个人按下所有编号为 3 的倍数的开关(其…...
Shifu基础功能:设备管理
设备管理 deviceshifu_configmap.yaml中的telemetries表示自动测量记录传导。Shifu通过telemetries中设置的方法,以指定时间向设备周期性地发送请求,来判断设备的连接情况。如果设备出现故障或者连接出现问题,edgeDevice的状态将发生改变&am…...
交互:可以执行命令行的框架才是好框架
上一节课,我们开始把框架向工业级迭代,重新规划了目录,这一节课将对框架做更大的改动,让框架支持命令行工具。 第三方命令行工具库 cobra obra 不仅仅能让我们快速构建一个命令行,它更大的优势是能更快地组织起有许多…...
eunomia-bpf 和 wasm-bpf 项目的 3 月进展
eunomia-bpf 项目是一个开源项目,旨在提供一组工具,用于在 Linux 内核中更方便地编写和运行 eBPF 程序。在过去一个月中,该项目取得了一些新的进展,以下是这些进展的概述。 首先,eunomia-bpf 动态加载库进行了一些重要…...
Spring框架核心功能手写实现
文章目录概要Spring启动以及扫描流程实现基础环境搭建扫描逻辑实现bean创建的简单实现依赖注入实现BeanNameAware回调实现初始化机制模拟实现BeanPostProcessor模拟实现AOP模拟实现概要 手写Spring启动以及扫描流程手写getBean流程手写Bean生命周期流程手写依赖注入流程手写Be…...
k8s-镜像构建Flink集群Native session
一.Flink安装包下载 wget https://dlcdn.apache.org/flink/flink-1.14.6/flink-1.14.6-bin-scala_2.12.tgz 二.构建基础镜像推送私服 docker pull apache/flink:1.14.6-scala_2.12 docker tag apache/flink:1.14.6-scala_2.12 172.25.152.2:30002/dmp/flink:...
在 k8S 中搭建 SonarQube 7.4.9 版本(使用 PostgreSQL 数据库)
本文搭建的 SonarQube 版本是 7.4.9-community,由于在官方文档中声明 7.9 版本之后就不再支持使用 MySQL 数据库。所以此次搭建使用的数据库是 PostgreSQL 11.4 版本。 一、部署 PostgreSQL 服务 1. 创建命名空间 将 PostgreSQL 和 SonarQube 放在同一个命名空间…...
从getBean()分析BeanFactory和ApplicationContext
本文说了哪些问题: BeanFactory 是啥ApplicationContext 是啥什么时候去实例化一个 bean, BeanFactory 和 ApplicationContext 实例化 bean 都是在什么时候 一个 Bean 什么时候被初始化 任何一个 Bean, 都是在 getBean () 的时候被初始化的.BeanFactory 需要字节手动调用 getb…...
详解Redis的主从同步原理
前言 Redis为了保证服务高可用,其中一种实现就是主从模式,即一个Redis服务端作为主节点,若干个Redis服务端作为主节点的从节点,从而实现即使某个服务端不可用时,也不会影响Redis服务的正常使用。本篇文章将对主从模式…...
前端项目上线后,浏览器缓存未刷新问题
文章目录问题背景一、解决办法二、实现原理关于缓存强缓存协商缓存刷新页面对浏览器的影响总结问题背景 前端页面开发测试完,要进行上线,某些页面上传更新到服务器之后,浏览器并没有更新,渲染的还是老页面。这是因为浏览器读了缓存…...
Vulnhub系列:Raven 1
该篇为Vulnhub系列靶机渗透,本次靶机存在4个flag。下面开始我们今天的渗透之旅。Raven靶机有很多种思路,我将对其进行一一整理。首先进行信息收集,利用arp-scan和nmap,进行靶机的ip及端口扫描发现了22、80、111端口。下面访问80端…...
MybatisPlus------多数据源环境(十一)
MybatisPlus------多数据源环境(十一) 生产环境中常常会存在多个数据源。 比如读写分离、一主多从、混合模式等等。 首先再pom文件中需要引入依赖: 多数据源所需要使用到的依赖 <!-- 多数据源所需要使用到的依赖--><depend…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
