创建k8s operator

目录

1.前提条件

2.进一步准备

2.1.安装golang

2.2.安装code(vscode的linux版本)

2.3.安装kubebuilder

3.开始创建Operator

3.1.什么是operator?

3.2.GV & GVK & GVR

3.3.创建operator

3.3.1. 生成工程框架

3.3.2.生成api(GVK)        

 3.3.3.实现代码逻辑,更新yaml定义

3.3.3.1.实现CR

 3.3.3.2.(依据代码定义)更新yaml

3.3.3.3.实现controller的Reconcile的方法

3.3.4.安装CRD

3.3.5.本地运行

3.3.5.1.运行项目

3.3.5.2.测试

3.3.5.1.1.准备测试CRD的yaml配置

 3.3.5.1.2.使用kubectl apply将CRD 实例部署到集群中

  3.3.5.3.停止运行

3.3.5.3.1.删除自定义的CRD实例

 3.3.5.3.1.停止工程运行

3.3.6.集群运行测试

3.3.6.1.修改Makefile

 3.3.6.2.将应用部署到k8s集群上

 3.3.6.3.测试

3.3.6.4.停止运行

参考文章


1.前提条件

使用kind搭建本地k8s集群之后,会准备好以下内容:

  • 本地多节点集群
  • kubectl 客户端命令工具
  • Lens k8s dashboard 可视化客户端工具
图1 查看本地集群信息

图2 本地集群workload信息

2.进一步准备

2.1.安装golang

按教程安装

图3 golang安装后查看go版本

        当前安装版本是:1.17.2 

2.2.安装code(vscode的linux版本)

这里有两种方式,一种是已经在windows上安装了vscode的情况下,希望在子系统的Ubuntu中也能使用vscode,一种是直接在Ubuntu安装Vscode。

我这里使用的第一种,按官方教程安装。如果是第二种,请按此方法安装。

# 使用命令打开vscode
code .
图4 在WSL2中使用命令打开Vscode

         WSL2和Win10的文件夹是互通的,当然可以直接在Win10中双击打开VScode,然后打开对应的项目路径,但是这样就有个缺点,无法在Terminal中使用一些Unbuntu的命令,有时候问题不大,但我们操作k8s的客户端是基于kubectl的,这个是使用这种方式的最重要原因,后续调试需要的必须条件。

2.3.安装kubebuilder

按官方文档安装

os=$(go env GOOS)
arch=$(go env GOARCH)

# download kubebuilder and extract it to tmp
curl -L https://go.kubebuilder.io/dl/2.2.0/${os}/${arch} | tar -xz -C /tmp/

# move to a long-term location and put it on your path
# (you'll need to set the KUBEBUILDER_ASSETS env var if you put it somewhere else)
sudo mv /tmp/kubebuilder_2.2.0_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin

校验kubebuilder安装后的情况 

图5 检查kubebuilder

3.开始创建Operator

3.1.什么是operator?

        我理解就是K8s的核心组件无法满足一些特定需求,而提供给开发者一个自定义资源的机会。当然,在我参考的文章中,也有比较系统的描述。但是从我的角度,确实比较易懂的解释就是这样的。既然是自定义资源,那我们需要知道一个资源需要有那些要素,这样才能定义

3.2.GV & GVK & GVR

  • GV: Api Group & Version

    • API Group 是相关 API 功能的集合
    • 每个 Group 拥有一或多个 Versions
  • GVK: Group Version Kind

    • 每个 GV 都包含 N 个 api 类型,称之为 Kinds,不同 Version 同一个 Kinds 可能不同
  • GVR: Group Version Resource

    • Resource 是 Kind 的对象标识,一般来 Kind 和 Resource 是 1:1 的,但是有时候存在 1:n 的关系,不过对于 Operator 来说都是 1:1 的关系

我们看个例子

apiVersion: apps/v1                 # 这个是 GV,G 是 apps,V 是 v1
kind: Deployment                    # 这个就是 Kind
metadata:                           # 这个是当前这种资源的媒体信息,你可以理解为detail info
  name: local-path-provisioner
  namespace: local-path-storage
  ...
spec:                               # spec就是Resource了,GVR中的R
  ...

3.3.创建operator

3.3.1. 生成工程框架

# 创建工程文件夹
mkdir create-crd-demo
# 使用kubebuilder初始化一个项目框架
# --domain: 资源域名,结合后续步骤进一步理解一下
# --repo: project是一个golang工程,go工程使用package管理,这个是go.mod的module信息,如果该工程要作为其他工程的导入包,那这个就要填可访问的repo路径才可以,此处只要不是没意义的就可以了。
kubebuilder init --domain geoff.crd.demo --repo k8s-operator/kubebuilder-crd-demo
图6 使用kubebuilder创建工程框架

具体的工程目录如下:

.
├── Dockerfile    # 工程Dockerfile,构建镜像的时候使用
├── Makefile    # 定义make命令集合,将一些命令定义成一个function XXX, 然后make XXX执行命令。
├── PROJECT    # 项目信息
├── README.md    # 工程说明
├── config    # 这个是生成CRD所需要的yaml定义,使用Kustomize管理
│   ├── default    # 一些默认配置
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager    # 部署CRD所需的 yaml
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus    # Prometheus监控相关配置,demo应该用不到
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml 
│   └── rbac    # 部署所需的 rbac 授权 yaml
│       ├── auth_proxy_client_clusterrole.yaml
│       ├── auth_proxy_role.yaml
│       ├── auth_proxy_role_binding.yaml
│       ├── auth_proxy_service.yaml
│       ├── kustomization.yaml
│       ├── leader_election_role.yaml
│       ├── leader_election_role_binding.yaml
│       ├── role_binding.yaml
│       └── service_account.yaml
├── go.mod    # 项目直接依赖(直接)
├── go.sum    # 项目全部依赖(直接+间接)
├── hack
│   └── boilerplate.go.txt
└── main.go    # 项目程序启动入口

3.3.2.生成api(GVK)        

刚才只是创建一个工程框架,一个壳子,接下来,我们创建一个api

# 创建k8s的api (GVK)
kubebuilder create api --group apps --version v1 --kind CustomeCrdDemo
图7 使用kubebuilder在生成的工程下继续生成api(GVK)相关定义

 我们注意到,工程目录多出了一些文件夹

.
├── Dockerfile
├── Makefile
├── PROJECT
├── README.md
├── api    # 新生成的和api(GVK)相关的定义
│   └── v1
│       ├── customecrddemo_types.go    # 这里是定义 spec 的地方
│       ├── groupversion_info.go    # GV 的定义,一般无需修改
│       └── zz_generated.deepcopy.go    # 和deepcopy相关的方法
├── bin
│   └── controller-gen    # 和go generater tool
├── config
│   ├── crd    # 自动生成的CRD文件,不用修改这里,只需要修改了v1中的go文件,之后执行make generate会更新当前目录的yaml定义文件
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches
│   │       ├── cainjection_in_customecrddemoes.yaml
│   │       └── webhook_in_customecrddemoes.yaml
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   ├── rbac
│   │   ├── auth_proxy_client_clusterrole.yaml
│   │   ├── auth_proxy_role.yaml
│   │   ├── auth_proxy_role_binding.yaml
│   │   ├── auth_proxy_service.yaml
│   │   ├── customecrddemo_editor_role.yaml
│   │   ├── customecrddemo_viewer_role.yaml
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── role_binding.yaml
│   │   └── service_account.yaml
│   └── samples    # 这里是CRD示例文件,可以使用`kubectl apply -f`用来部署到集群当中
│       └── apps_v1_customecrddemo.yaml
├── controllers
│   ├── customecrddemo_controller.go    # 在这里实现 CRD controller的逻辑
│   └── suite_test.go   # 这里写测试 
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
└── main.go

 3.3.3.实现代码逻辑,更新yaml定义

3.3.3.1.实现CR

        到上面部分为止,我们已经通过kubebuilder生成了CRD所需的项目框架,接下来我们进行自定义开发,此时我们使用VScode来开发吧

# 在当前目录下打开VScode
code .

        我们随便增加CRD的spec字段,增加ResourceName、AdditionalInfo。这字段会在之后生成的yaml文件中的spec字段体现。

//……
// CustomeCrdDemoSpec defines the desired state of CustomeCrdDemo
type CustomeCrdDemoSpec struct {
	// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// Foo is an example field of CustomeCrdDemo. Edit customecrddemo_types.go to remove/update
	// Foo string `json:"foo,omitempty"`

	// 资源名称
	ResouresName string `json:"resourceName,omitempty"`
	// 附加信息
	AdditionalInfo string `json:"additionalInfo,omitempty"`
}
//……
图8 修改xxx_type.go中关于CRD spec字段的定义

 3.3.3.2.(依据代码定义)更新yaml

        执行命令更新yaml,这里我们直接在VScode的Terminal中执行就可以了,不需要在WSL2上执行命令,方便开发。

# 重新生成yaml文件
make manifests generate

        更新yaml,struct上字段备注成为了description,是有意义的

# 新生成的yaml文件:config/crd/bases/apps.geoff.crd.demo_customecrddemoes.yaml
……
spec:
  description: CustomeCrdDemoSpec defines the desired state of CustomeCrdDemo
  properties:
    additionalInfo:
      description: 附加信息
      type: string
    resourceName:
      description: 资源名称
      type: string
……

 其中,yaml的路径和生成项目时设置的--domain是有关系的。

3.3.3.3.实现controller的Reconcile的方法

        不做复杂的实现,只增加日志打印。 

// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.11.2/pkg/reconcile
func (r *CustomeCrdDemoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	log := log.FromContext(ctx)

	// TODO(user): your logic here
	log.Info("=========================== Create a new CRD instance ===========================")

	return ctrl.Result{}, nil
}
图9 实现controller的Reconcile的方法

3.3.4.安装CRD

# 往k8s安装CRD的定义
make install
图11 直接在Vscode的Terminal执行make install
图12 在集群中能看到install后已经存在了CRD的定义

3.3.5.本地运行

3.3.5.1.运行项目

# 运行工程应用
make run
图12 运行工程项目(在install之后)

         运行之后,项目成功跑起来了,没有报错就算是成功了。

3.3.5.2.测试

3.3.5.1.1.准备测试CRD的yaml配置

        我们自己定义的struct有两个字段,一个是resourceName、AdditionalInfo,我们要实现一个CRD的实例dem哦,目前项目工程路径:config/samples/xxx.yaml下有个自动生成的CRD模板,我们按照定义需要给这两个字段配置信息。

apiVersion: apps.geoff.crd.demo/v1
kind: CustomeCrdDemo
metadata:
  name: customecrddemo-sample
spec:
  # TODO(user): Add fields here
  resourceName: "my-crd-instance-1"
  AdditionalInfo: "这是我测试的第一个CRD资源实例"
图13 准备CRD测试实例的yaml,需要实现spec的字段
 3.3.5.1.2.使用kubectl apply将CRD 实例部署到集群中
# 使用kubectl apply一个CRD实例
# 其中项目目录下config/samples/xxx.yaml是make generate mainfests生成的
kubectl apply -f ./config/samples/apps_v1_customecrddemo.yaml
图14 部署CRD实例demo
图15 集群上已经能看到刚刚部署的CRD实例demo
图16 项目工程(CRD operator)日志打印了,operator实现成功

  3.3.5.3.停止运行

3.3.5.3.1.删除自定义的CRD实例
# 删除了刚刚的CRD demo实例
kubectl delete -f config/samples/
图17 删除自定义的CRD实例demo
 3.3.5.3.1.停止工程运行

        直接在Vscode的Terminal中执行:Ctrl+C即可停止项目运行

图18 将本地运行的项目停止

3.3.6.集群运行测试

        上一章节,我们看到可以在本地run了project,直接看到当CRD被部署后,直接触发了我们controller中实现的日志。实际上,我们开发好了之后,这个operator application是要部署到k8s集群上的,主要controller的实现逻辑,这样CRD才能起作用。如何操作其实工程的README.md也有说明的,可以先看看。

3.3.6.1.修改Makefile

# 本地集群的名称
KUBE_CLUSTER = k8s-local-dev 

……

# 增加一个function,将本地的image上传到Kind的容器中
.PHONY: kind-load
kind-load: ## load the local image to the kind cluster
	kind load docker-image ${IMG} --name ${KUBE_CLUSTER}

……
图17 增加kind-load,可以将image上传到kind创建的集群容器中

 3.3.6.2.将应用部署到k8s集群上

以下是部署到集群的步骤:构建镜像、上传到集群容器中、部署

其中IMG是一个可以自行设置镜像名的变量,此处为:k8s-crd-demo:1.0。

按如下命令执行后,即可在k8s集群中看到部署的CRD controller应用。

# 构建镜像(有时候会失败,可能是网络问题,多试几遍),IMG需要指定,不然后面部署还是有问题
make docker-build IMG=k8s-crd-demo:1.0
# local镜像上传到Kind创建的k8s集群所在的所有node中(如果本地是)
make kind-load IMG=k8s-crd-demo:1.0
# 部署controller
make deploy IMG=k8s-crd-demo:1.0

        在这个过程中,bin/目录存在一些二进制的工具包,可以先删除,是之前make run时下载的,有可能会报错。

图18 bin目录应该要提前删除kustomize工具
图19 make deploy IMG=xxx将controller部署到k8s上
图20 将operator这个应用application部署到k8s集群

 3.3.6.3.测试

 同上面3.3.5.2,直接测试即可

3.3.6.4.停止运行

# undeploy controller
make undeploy
# 卸载CRD
make uninstall

参考文章

如何在 Ubuntu 20.04 上安装 Go-腾讯云开发者社区-腾讯云

开始通过 WSL 使用 VS Code | Microsoft Learn

快速入门 - Kubebuilder 中文文档

3. KubeBuilder 简明教程 - Mohuishou

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/88175.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【DC】逻辑综合实战

DC实战 0. 学习目标1. Design1.1 Design Schematic1.2 Design Specification 2. 配置文件和约束文件2.1 配置文件(1) common_setup.tcl 文件(2) dc_setup.tcl 文件(3) .synopsys_dc.setup 文件 2.3 启动工具查看单元库信息(1) 查看目标库的时间单位 2.3 设计约束文件(1) 时钟约…

(三)行为模式:4、迭代器模式(Iterator Pattern)(C++示例)

目录 1、迭代器模式(Iterator Pattern)含义 2、迭代器模式的UML图学习 3、迭代器模式的应用场景 4、迭代器模式的优缺点 (1)优点 (2)缺点 5、C实现迭代器模式的实例 1、迭代器模式(Itera…

S7-300 PLC 模拟量采集(从硬件组态到软件FC编写)

S7-300PLC属于退市产品,很多老的生产线仍然沿用,所以这篇博客我们一步步介绍如何从硬件组态到软件FC的编写,首先我们组态模拟量模块。 1、硬件组态 组态好硬件后,我们开始设计软件FC,模拟量采集往往都会有很多回路,下面我们介绍如何在STEP7中创建模拟量采集FC,S_ITR,有关…

C++ IO流

文章目录 一.C语言的输入与输出二.流是什么三.CIO流1.C标准IO流2.C文件IO流&#xff08;1&#xff09;文件操作步骤&#xff08;2&#xff09;以二进制的形式操作文件&#xff08;3&#xff09;以文本的形式操作文件&#xff08;4&#xff09;使用>>和<<对文件进行…

【LeetCode-中等题】560. 和为 K 的子数组

题目 题解一&#xff1a;逆序枚举数组 //方法一:枚举数组&#xff08;顺序&#xff09;int count 0;// 记录最终符合条件的数组个数int n nums.length;for(int end 0; end<n ; end){int sum 0;//记录每一次经过的元素总和for(int start end; start>0;start--){sum n…

RabbitMQ介绍

RabbitMQ的概念 RabbitMQ 是一个消息中间件&#xff1a;它接受并转发消息。你可以把它当做一个快递站点&#xff0c;当你要发送一个包裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按照这种逻辑 RabbitMQ 是 一个快递…

测试框架pytest教程(8)失败重试-pytest-rerunfailures

pytest-rerunfailures是一个pytest插件&#xff0c;用于重新运行失败的测试用例。当测试用例在第一次运行时失败&#xff0c;该插件会自动重新运行指定次数的失败用例&#xff0c;以提高稳定性和减少偶发性错误的影响。 要使用pytest-rerunfailures插件&#xff0c;需要按照以…

[Makefile] 预宏定义的使用

main.c 文件如下&#xff1a; #include <stdio.h> int main() {printf("soft infomation\n");//以下信息均在gcc时已预定义printf("soft_ver:\t%s\n",__VER__);printf("author:\t\t%s\n",__AUTHOR__);printf("sn_num:\t\t%d\n"…

基于Googlenet深度学习网络的交通工具种类识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ....................................................................................% 获…

OpenCV基础知识(5)— 几何变换

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。OpenCV中的几何变换是指改变图像的几何结构&#xff0c;例如大小、角度和形状等&#xff0c;让图像呈现出缩放、翻转、旋转和透视效果。这些几何变换操作都涉及复杂、精密的计算。OpenCV将这些计算过程都封装成了非常灵活的…

嵌入式Linux开发实操(十一):ETH网络接口开发

# 前言 嵌入式linux也有些是支持网口的,比如RGMII,嵌入式系统资源支持以太网和其他基本接口的硬件平台(板上或片上系统),有充足的NOR或NAND Flash闪存,用于容纳OS、lib库、fileSystem文件系统、APP应用程序、Bootloader引导程序等。嵌入式Linux是开源的、可修改的,并且…

go语言中channel类型

目录 一、什么是channel 二、为什么要有channel 三、channel操作使用 初始化 操作 单向channel 双向channel&#xff0c;可读可写 四、close下什么场景会出现panic 五、总结 一、什么是channel Channels are a typed conduit through which you can send and receive …

回归预测 | MATLAB实现DBN-ELM深度置信网络结合极限学习机多输入单输出回归预测

回归预测 | MATLAB实现DBN-ELM深度置信网络结合极限学习机多输入单输出回归预测 目录 回归预测 | MATLAB实现DBN-ELM深度置信网络结合极限学习机多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现DBN-ELM深度置信网络结合极限学习…

Redis 分布式锁存在什么问题 ?如何解决 ?

目录 1. 如何实现分布式锁 2. Redis 分布式锁存在什么问题 2.1 解决死锁问题 2.2 解决锁误删问题 1. 如何实现分布式锁 Redis 天生就可以作为一个分布式系统来使用&#xff0c;所以它实现的锁都是分布式锁。 Redis 可以通过 setnx&#xff08;set if not exists&#xff09…

c语言实现队列

文章目录 前言一、队列的特征二、队列的实现1、队列的设计2、队列的初始化3、元素的入队和出队4、返回队头的数据和队尾的数据5、返回队列的长度6、队列的销毁 三、循环队列四、队列和栈综合练习 前言 栈的特点是元素后进先出(Last In First Out)&#xff0c;而对应的还有一种…

Android GreenDao数据库升级(附Demo)

前言 大家好久不见&#xff0c;一转眼马上八月份下旬了&#xff0c;最近由于工作比较忙&#xff0c;没时间给大家更新博文。百忙之中抽出时间&#xff0c;给大家来更新一篇关于GreenDao3数据库的升级。 关于GreenDao的详细介绍以及一些逻辑性的增、删、改、查等&#xff0c;可以…

3:Ubuntu上配置QT交叉编译环境并编译QT程序到Jetson Orin Nano(ARM)

1.Ubuntu Qt 配置交叉编译环境 1.1 ubuntu 20.04安装Qt sudo apt-get install qtcreator 1.2 配置QT GCC配置同上 最后配置Kits 上面设置完成之后 &#xff0c;设置Kits 中的Device(这是为了能够直接把项目部署到arm设备上) 点击NEXT之后会出现连接被拒绝&#xff0c;不用担…

ARM-汇编指令

一&#xff0c;map.lds文件 链接脚本文件 作用&#xff1a;给编译器进行使用&#xff0c;告诉编译器各个段&#xff0c;如何进行分布 /*输出格式&#xff1a;32位可执行程序&#xff0c;小端对齐*/ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm",…

React原理 - React Virtual DOM 原理

目录 扩展学习资料 Virtual DOM 是什么【虚拟dom】 React渲染 Virtual DOM VS 原生DOM【vDom是否比原生Dom更高效】 Virtual DOM数据结构 Virtaual DOM Diff【虚拟dom前后比对&#xff0c;更新不同dom的算法】 源码解读 react源码组织方式&#xff1a; React Stack Rec…

YOLOv5基础知识入门(7)— NMS(非极大值抑制)原理解析

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。NMS是指非极大值抑制&#xff08;non maximum suppression&#xff09;&#xff0c;它是一种常用于物体检测任务的算法。在物体检测中&#xff0c;通常会有多个预测框&#xff08;bounding box&#xff09;被提议出来&…