首页 > 技术文章 > client -go 架构

wuchangblog 2022-05-09 22:58 原文

一、重点模块

在client-go包中,client-go实现了几个核心的组件,帮助我们与api-server进行通信,我们仅需要实现业务相关的逻辑

 1、discovery用于发现api server支持的API,定义DsicoveryClient客户端。作用是用于发现k8s所支持GVR(Group, Version, Resources),比如kubectl api-versions使用了该机制,

 2、dynamic 包含了dynamic client 的逻辑,通过dynamic client,我们可以操作任意的K8S的API对象,包括自定义(即:CRD)的以及K8S内置的资源对象

 3、informe包含了所有内置的资源的 informer,便于操作K8S的资源对象

 4、kubernetes 库包含所有访问K8S API的clientset

 5、lister 包含了所有内置资源的lister,用于读取缓存中K8S资源对象的信息,对于Get()和List()而言,listers提供给二者的数据都是从缓存中读取的。

 6、plugin/pkg/client/auth 包含了所有可选 认证插件,用于从外部获取credential,如:GCP,Openstack等

 7、rest                        # 定义RestClient,实现了Restful的API。同时会支持Protobuf和Json格式数据。

 8、tools包含了一系列的工具,在编写控制器的时候会用到提供的一些工具方法,# 定义诸如SharedInformer、Reflector、DealtFIFO和Indexer等常用工具。

实现client查询和缓存机制,减少client与api-server请求次数,减少api-server的压力。

 9、提供诸如WorkQueue、Certificate等常用方法

二、流程架构

 1、reflector 主要来list和watch我们想要关注的K8S资源对象,然后 reflector将资源对象的变更事件放到Delta FIFO这个队列里面。

ResourceVersion
保证客户端数据一致性和顺序性
并发控制

2、同时将资源的相关信息放到缓存Cache当中,资源对象的数据发生变更时,新的事件来了之后,通过informer里面的事件处理方法,

到注册的事件方法,将事件的变更消息放到WorkQueue队列中,同时回应多个worker处理队列里面的消息,

3、worker里面将资源的状态写入到api server中,同时为了减轻api server的压力,通过informer提供的cache机制,获取资源对象的信息。

4、worke主要逻辑为根据资源对象的当前status和spec,也就是期望的状态进行对比,如果不一致则进行相应的处理

三、控制器逻辑

-- 观察:通过监控kubernetes资源对象变化的事件来获取当前对象状态,我们只需要注入EventHandler让client-go将变化的事件对象信息放入

   WorkQueue中

-- 分析:确定当前状态和期望状态的不同,由Worker完成

-- 执行: 执行能够驱动对象当前状态变化的操作,由Woker完成

-- 更新:更新对象的当前状态,由Worker完成 

四、RESTClient原理

概要:在client--go中,如果Reflector要和api server交互,需要通过client来实现

Cleint 类型

-- RESTClient:最基础的客户端,提供最基本的封装

-- Clientset:是一个client的集合,在Clientset中包含了所有K8S内置资源的Client,通过Clientset便可以很方便的操作如Pod,Service这些资源

-- dynamicClient:动态客户端,可以操作任意K8S的资源,包括CRD定义的资源

-- DiscoveryClient:用于发现K8S体个的资源组,资源版本和资源信息,比如:kubectl api-resources

1、RESTClient的使用

-- RESTClientFor:为创建RESTClient准备config,比如限速器,编解码器等

-- UnversionedRESTClientFor:与RESTClientFor类似,只是允许config.GroupVersion为空

 // config
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) if err != nil { panic(err.Error()) } // create the client clientset, err := kubernetes.NewForConfig(config) if err != nil { panic(err.Error()) }

 

推荐阅读