云原生|详解Kubernetes Operator在项目中的开发应用

news2024/11/25 20:42:28

目录

一、使用场景

(一)client-go中处理逻辑

(二)controller-runtime中处理逻辑

二、使用controller-runtime开发operator项目

(一)生成框架代码

(二)定义crd字段

(三)生成crd文件

(四)初始化manager

(五)配置controller

(六)配置webhook


一、使用场景

controller-runtime是基于kubernetes控制器模式衍生出来的一套框架。控制回路(Control Loop)是一个非终止回路,用于调节系统状态。一个控制器至少追踪一种类型的 Kubernetes 资源。这些 对象 有一个代表期望状态的 spec 字段。该资源的控制器负责确保其当前状态接近期望状态。

从中,我们可以得出,controller-runtime开发需要遵循以下几点。

  1. controller-runtime需要持续监听kubernetes对象。(通过list/watch机制实现)

  2. controller-runtime需要提供某些机制,Kubernetes对象的status(实际状态)维持到与spec(期望状态)一致。(通过reconcile实现)

(一)client-go中处理逻辑

在client-go中,会将一种Kubernetes对象封装成一个对的informer类型。informer类型中包含Reflector,DeltaFIFO,Indexer,EventHandler。

  • Reflector:用于调用Kubernetes的API接口。informer会通过两个Kubernetes的API接口来实现kubernetes对象的监听。list/watch失败时,会自动重新list/watch

  • list接口:通过http请求,获取informer中定义的全量kubernetes对象数据到deltaFIFO中

  • watch接口:从本地存储的最大resourceVersion开始监听。当发送 watch 请求时,API 服务器会响应更改流。这些更改逐项列出了在你指定为 watch 请求参数的 resourceVersion 之后发生的操作(例如 ADDED、MOD-IFIED、DELETED、BOOKMARK、ERROR)的结果。

  • DeltaFIFO:存储每个待处理的Kubernetes对象。DeltaFIFO中有两个存储kubernetes对象的数据结构,一个是存储对象key值的一维数组,一个存储数据流的map结构。

  • queue: 一维数组,每个kubernetes对象对应一个key(namespace/name)。多次入队的变更数据会合并存储,出队时,处理整个对象。

  • items: 存储kubernetes对象的变更流。(Added,Updated,Deleted,Replaced,Sync)启动informer时,持续从deltaFIFO中读取数据进行处理。

  • Indexer:从DeltaFIFO中获取的Kubernetes对象,存储到内存map中。

  • EventHandler:从DeltaFIFO中获取的Kubernetes对象,根据对象的变更事件类型,来进行不同的处理。一般是将key值传递给工作队列。然后通过custom controller进行处理。

(二)controller-runtime中处理逻辑

根据要监听的Kubernetes对象,定义Informer

定义EventHandler处理逻辑。将informer eventhandler中的key值存入工作队列。该工作队列中会对key值进行去重处理。以避免在一个工作队列出现并发处理同一个对象的情况。

从工作队列中取出key值,在reconcile进行处理。

自定义结构体实现reconcile方法。在该方法中,协调kubernetes对象的状态,使其向期望状态靠拢。

controller-runtime框架简介

controller-runtime框架简介 

controller-runtime顶层使用manager进行封装。manager包含以下信息

  • cluster:用于与kubernetes集群通信。包含kubernetes的kubeconfig配置信息,连接kuberenetes的apiserver的客户端信息,注册到operator的kubernetes对象scheme信息,用于获取gvk和gvr的RESTMapper信息,用于informer存储的indexer信息,用于和kubernetes对象读,写和事件发布的客户端信息。

  • controller:用于informer的配置与启动,reconcile的定义

  • cache:缓存informer信息。包含informer的定义和indexer数据读取。

  • webhook:用于发布kubernetes中的三种类型的webhook服务。

  • election:用于operator的主备配置

  • prometheus:用于发布prometheus的数据服务

  • probe:定义operator的探针服务,包含两种探针数据:健康探针和存活探针

二、使用controller-runtime开发operator项目

(一)生成框架代码

官方推荐使用kubebuilder插件来自动生成controller-runtime框架。

生成项目框架:kubebuilder init --domain demo --plugins=go/v4-alpha

生成kubernetes的crd对象对应的api(使用Kubernetes默认的对象可忽略):kubebuilder create api --group webapp --version v1 --kind Guestbook

生成webhook服务代码:kubebuilder create webhook --group webapp --version v1 --kind Guestbook --defaulting --programmatic-validation

生成的代码目录结构如下

  • api:包含crd的api定义,webhook文件,需在guestbook_types.go中补充需要的字段。然后通过Makefile中的命令生成所需要的文件(可部署到kubernetes集群的yaml文件,实现client-go中定义的object方法的go文件)

  • bin:生成文件时,用到的工具。controller-gen(生成crd关联文件)和kustomize(生成opertor项目的部署文件)

  • config:kustomize执行时用到的配置文件。

  • controllers:controllers示例文件。包含自定义的Reconcile结构体,实现了Reconcile方法用于协调kubenetes资源,和用于定义informer的方法。

  • hack:controller-gen执行时用到的配置文件。

  • dockerignore Dockerfile:生成operator项目镜像文件

  • main.go:启动文件

  • Makefile:封装一些make命令。包含生成代码命令,部署operator项目命令等

  • PROJECT:执行kubebuider命令后生成的项目配置信息文件

(二)定义crd字段

补充guestbook_types.go文件。该文件中,需要补充两类数据。

  • struct中的字段

spec中定义期望状态字段。status中定义实际状态字段。

字段后的json标签用于生成kubernetes中crd文件对应的字段。omitepty表示该字段是否该字段是否必填。

  • kubebuilder注释

用于生成crd文件和实现了client-go中定义的runtime.Object的deepcopy文件。

官网中kubebuilder注释展示了注释的4种用法:

- Validation(定义在字段上,用于生成crd文件的字段验证)

- Additional Printer Columns(定义在结构体上,对应crd文件中的spec.ver-sions.additionalPrinterColumns)

- Subresources(定义在结构体上,对应crd文的.spec.version.subresources)

- Multiple Versions(定义在结构体上,在多版本的中定义指定版本,对应crd文件中的spec.versions.storage字段定义)

⚠️定义在结构体上的注释与注释之间不能有空行

(三)生成crd文件

执行make manifest生成WebhookConfiguration,ClusterRole,Custom-ResourceDefinition

  • WebhookConfiguration:根据//+kubebuilder:webhook注释生成,一般定guestbook_webhook.go文件中
  • ClusterRole:根据//+kubebuilder:rbac注释生成,一般定义controllers/guestbook_controller.go文件中
  • CustomResourceDefinition:根据guestbook_types.go和groupversion_in-fo.go文件生成。

执行make generate生成实现zz_generated.deepcopy.go文件

zz_generated.deepcopy.go文件:实现了runtime.Object中的方法,用于client-go依赖包中的类型转换。根据//+kubebuilder:object注释生成。

(四)初始化manager

在main.go文件中对manager进行初始化。

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
   Scheme: scheme,
   MetricsBindAddress:     metricsAddr,
   Port:                   9443,
   HealthProbeBindAddress: probeAddr,
   LeaderElection: enableLeaderElection,
   LeaderElectionID: "aefd3536.demo",
})

配置controller

if err = (&controllers.GuestbookReconciler{
   Client: mgr.GetClient(),
   Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
   setupLog.Error(err, "unable to create controller", "controller", "Guestbook")
   os.Exit(1)
}

配置webhook

if err = (&webappv1.Guestbook{}).SetupWebhookWithManager(mgr); err != nil {
   setupLog.Error(err, "unable to create webhook", "webhook", "Guestbook")
   os.Exit(1)
}

配置探针

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
   setupLog.Error(err, "unable to set up health check")
   os.Exit(1)
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
   setupLog.Error(err, "unable to set up ready check")
   os.Exit(1)
}

启动manager

if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
   setupLog.Error(err, "problem running manager")
   os.Exit(1)
}

(五)配置controller

guestbook_controller.go文件中定义了两个方法。

func (r *GuestbookReconciler) SetupWithManager(mgr ctrl.Manager) error {
   return ctrl.NewControllerManagedBy(mgr).
      For(&webappv1.Guestbook{}).
      WithEventFilter(predicate.Funcs{
         CreateFunc: func(_ event.CreateEvent) bool {
            return false
         },
      }).
      WithOptions(controller.Options{MaxConcurrentReconciles: 2}).
      Complete(r)
}

在main.go文件中调用,用于定义informer并将informer配置到manager中

  • informer中kubernetes对象

框架对对象类型的定义提供了三种方法:

  • Watches(source.Source, handler.EventHandler, ...WatchesOption)
  • For(client.Object,...ForOption)
  • Owns(client.Object,...OwnsOption)

其中For和Owns是等同与Watches。For的第二个参数默认为EnqueueRequestForObject。Owns的第二个参数默认为EnqueueRequestForOwner

方法参数说明

  • Source:第一个参数,kubernetes对象类型
  • EventHandler:第二个参数,从DeltaFIFO中取出来的数据,在进入工作队列前进行的操作。EnqueueRequestForObject表示不做任何处理,直接进入工作队列。EnqueueRequestForOwner需要和For方法配合使用,Owns中的对象中ownerReference引用的对象类型需要和For中定义的对象类型相同,且ownerReference中的controller为true。
  • Predicate:第三个参数,从工作队列取出来的数据,在进行reconcile处理前进行的操作。通过builder的WithEventFilter可以给所有的对象添加Predicate。

EventHandler和Predicate方法说明

Create:kubernetes对象新增时调用

Update:kubernetes对象更新时调用

Delete:kubernetes对象删除时调用

Generic:未知的操作。非kubernetes集群的变更事件。在operator中自行使用

  • controller配置

通过builder.WithOptions定义配置。controller中有以下配置可定义。

  • MaxConcurrentReconciles:从工作队列取出的数据,可使用几个协程进行处理。默认一个
  • Reconciler:协调器,需要实现Reconciler方法。默认为guest-book_controller.go文件中定义的Reconcile
  • RateLimiter:工作队列的限流策略。默认有两种限流策略。令牌桶策略(BucketRateLimiter):默认100个令牌数量。每秒可取10个令牌。退避策略(ItemExponentialFailureRateLimiter):reconcile返回失败时,重新入队。下次出队时间按2的指数次方增长。初始5ms,最大1000s。
  • LogConstructor:reconcile中从context中取到的日志logr。默认是mgr中定义的日志。
  • CacheSyncTimeout:informer同步超时时间。在informer进行list/watch时,只有当list接口调用的数据全部同步到informer的indexer后,才算informer同步成功。
  • RecoverPanic:reconcile异常时是否自动恢复。
func (r *GuestbookReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
   _ = log.FromContext(ctx)
 
   // TODO(user): your logic here
 
   return ctrl.Result{}, nil
}

Reconcile方法为自定义的逻辑。在实现自定义逻辑时,不需要太过于关注中间状态的影响,只需要保证当前状态应该尽量往期望状态靠拢。Reconcile返回值的Result中,也可以定义是否重新入队与出队时间。

(六)配置webhook

框架提供了三种webhook:

Defaulter

func (r *Guestbook) Default() {
   guestbooklog.Info("default", "name", r.Name)
 
   // TODO(user): fill in your defaulting logic.
}

对应kubernetes中的MutatingAdmissionWebhook对象。

Validator

func (r *Guestbook) ValidateCreate() error {
   guestbooklog.Info("validate create", "name", r.Name)
 
   // TODO(user): fill in your validation logic upon object creation.
   return nil
}
 
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *Guestbook) ValidateUpdate(old runtime.Object) error {
   guestbooklog.Info("validate update", "name", r.Name)
 
   // TODO(user): fill in your validation logic upon object update.
   return nil
}
 
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
func (r *Guestbook) ValidateDelete() error {
   guestbooklog.Info("validate delete", "name", r.Name)
 
   // TODO(user): fill in your validation logic upon object deletion.
   return nil
}

对应kuberenetes中的ValidatingWebhookConfiguration对象。

convertion.Webhook

对应crd中的spec.convertion中定义的webhook

中心版本

// Hub 标注为中心版本
func (r *Guestbook) Hub() {
 
}

其他版本

func (r *Guestbook) ConvertTo(dst conversion.Hub) error {
   // todo 当前版本向中心版本转换
   return nil
}
func (r *Guestbook) ConvertFrom(src conversion.Hub) error {
   // todo 中心版本向当前版本转换
   return nil
}

那么以上就是k8s operator在项目中的开发应用啦,希望对你有所帮助~

本次分享就到这里啦,更多技术干货小知识欢迎关注“神州数码云基地”公众号

版权声明:文章由神州数码武汉云基地团队实践整理输出,转载请注明出处。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式消息队列RocketMQ概念详解

目录 1.MQ概述 1.1 RocketMQ简介 1.2 MQ用途 1.3 常见MQ产品 2.RocketMQ 基本概念 2.1 消息 2.2 主题 2.3 标签 2.4 队列 2.5 Producer 2.6 Consumer 2.7 NameServer 2.8 Broker 2.9 RocketMQ 工作流程 1.MQ概述 1.1 RocketMQ简介 RocketMQ 是阿里开源的分布式消…

云原生:从基本概念到实践,解析演进与现状

文章目录 云原生:从基本概念到实践,解析演进与现状概念演进之路DockerKubernetesCloud NativeServerless 业界现状总结 结语 云原生:从基本概念到实践,解析演进与现状 本文仅用于简单普及,达到的目的是给没接触过或者很…

苹果手机无法开机?黑屏打不开怎么办?出现这种问题的解决办法分享!

各位在使用苹果手机的小伙伴有没有遇到苹果手机突然就黑屏开不了机,打电话也没有任何反应,手机也无法关机重启,这是什么问题呢?我们遇到这种问题该如何去处理呢? 小编今天就来跟大家说说苹果手机突然开不了机的原因以及…

【Linux命令】脚本里常用的几个命令

脚本里常用的命令 一、SORT命令1.1、语法格式1.2常用选项 二、uniq命令2.1命令格式2.2常用选项2.3小实验,过滤出现三次以上的IP地址 三、tr命令3.1语法格式3.2常用选项3.3实验 四、cut命令4.1语法格式4.2常用选项 五、split命令5.1语法格式5.2常用选项 六、eval七、…

在行 | “数智”为离散制造发展注入动能

在行业现场解析行业难题, 用主题方案创新数智价值。 制造业作为我国实体经济的主体,是国民经济体系的重要组成部分,其中以离散制造比重最大,是解决就业等民生问题的支柱。随着技术和经济水平的提升,市场对离散制造行业…

CnOpenData淘宝村淘宝镇名单数据

一、数据简介 随着电商的迅猛发展,以淘宝村为代表的新型城镇化不断推进。淘宝镇和淘宝村是电商巨头阿里巴巴推出的一系列支持中小企业、新创企业发展的计划,旨在为中小企业及创新企业提供融资、营销、培训、咨询等服务。截至2022年,全国涌现了…

创新案例 |探索 Tive 80% 的收入增长得益于智能物流服务、跟踪和实时可视化

您正在寻找可靠的物流解决方案吗? Tive 是领先的智能物流服务提供商,提供跟踪和实时可见性解决方案。使用 Tive,您可以主动监控公路、空运、海运和铁路运输。它可以帮助您减少运输问题并确保准时和全面交付,从而改善客户体验。 …

融合CDN和单CDN的产品对比

仅针对特定地理位置的公司可以使用单一CDN解决方案,建议网站内容在全球分发的优先选择融合CDN来进行加速。 如果您的网站内容/应用程序大多是静态的,那么单一CDN解决方案可能适合大多数市场需求;但如果您的流量高于平均水平,媒体流…

【表面缺陷检测】基于yolov5的钢板表面缺陷检测(附代码和数据集,Windows系统)

写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 路虽远,行则将至;事虽难,做则必成。只要有愚公移山的志气、滴水穿石的毅力,脚踏实地,埋头苦干,积跬步以至千里,就…

iPhone语音备忘录删除了怎么恢复?恢复备忘录,只需3个方法!

案例:语音备忘录被清空 【苹果语音备忘录有我很多会议记录,但是被我清理手机垃圾的时候顺便清理了。有什么方法恢复回来吗?】 很多人都知道,iphone语音备忘录是使用起来非常方便的一种记录方式,但是如何在不小心删除备…

Python之引用

1. 引用简介与工具引入 Python 中对于变量的处理与 C 语言有着很大的不同,Python 中的变量具有一个特殊的属性:identity,即“身份标识”。这种特殊的属性也在很多地方被称为“引用”。 为了更加清晰地说明引用相关的问题,我们首…

MySQL---多表联合查询(下)(内连接查询、外连接查询、子查询(ALL/ANY/SOME/IN/EXISTS关键字)、自关联查询)

1. 内连接查询 数据准备: use mydb3;-- 创建部门表 create table if not exists dept3(deptno varchar(20) primary key , -- 部门号name varchar(20) -- 部门名字 );-- 创建员工表 create table if not exists emp3(eid varchar(20) primary key , -- 员工编号e…

代表Java未来的ZGC深度剖析

JAVA程序最爽的地方是它的GC机制,开发人员不需要关注内存申请和回收问题。同时,JAVA程序最头疼的地方也是它的GC机制,因为掌握JVM和GC调优是一件非常困难的事情。在ParallelOldGC、CMS、G1之后,JDK11带来的全新的「ZGC」为我们解决…

css中常用伪类表单验证:invalid、:valid、:required、以及:not 、:lang、:empty的使用

MDN文档关于伪类的相关介绍 1、 :invalid :invalid 是 CSS 伪类选择器&#xff0c;用来选择任何未通过验证的 <form>、<fieldset>、<input> 或其他表单元素。 <form class"form"><label for"email">邮箱地址:</label>…

Sqlite3 生成lib库文件

特此记录&#xff01; QT使用SQL一般有两种方式 No1&#xff0c;使用Qt内部的Sql模块 No2&#xff0c;不通过Qt的Sql模块&#xff0c;直接使用Sqlite的lib库&#xff0c;使用Sqlite的标准C/C接口就行 接下来主要针对第二种。 第一步&#xff0c;进入官网 SQLite Download P…

Google Play应用广告该如何运作

Google 应用广告是一种付费广告渠道&#xff0c;可以帮助我们把应用推向特定的目标受众。比如可以使用应用安装广告&#xff0c;用来吸引用户安装我们的应用&#xff0c;我们可以选择手动设置出价和定位&#xff0c;或使用 Google Ads 自动设置目标和出价。 Google 在创建和投…

unity3D 魔兽争霸游戏开发案例教程

文章连载更新中&#xff0c;可以提前领取素材进行预习&#xff0c;自学 素材领取&#xff1a;私信发送 领取RPG网络开发教材 这里写目录标题 游戏玩法这门课适合哪些人学习学完了能达到什么效果项目准备基础系统战斗系统同步设计精讲社交系统副本系统优化项目准备正文美术准备&…

给k8s集群添加负载均衡的能力

常识: k8s没有自带负载均衡能力, 需云服务提供商来做负载均衡, 或者自己装负载均衡控制器. 负载均衡控制器有很多, 这次装Ingress-Nginx https://kubernetes.github.io/ingress-nginx/ 文档里根据环境有很多安装方式,不要用quick start的,因为那是云环境下的. 我们的k8s是自己的…

微信小程序商品分类页最佳实践

首先我们来分析下UI小妹发来的产品原型图&#xff1a; 微信小程序商品分类页需要实现 1.单击左边的商品类目&#xff0c;右侧实现联动跳转到对应商品类目标题&#xff1b; 2.触屏拖动右侧商品列表&#xff0c;右侧跳转到对应商品类目&#xff1b; 2.分析需求我们可以把屏幕分…

使用阿里云服务器三分钟搭建网站教程(详细图文详解)

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流程&#xff1a; …