RESTClient原理
# RESTClient原理
# 环境要求
K8S版本:v1.23.3
[root@k8s-master ~]# kubectl cluster-info
Kubernetes control plane is running at https://10.11.121.111:6443
CoreDNS is running at https://10.11.121.111:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
client-go版本: v0.23.3
# Client-go架构
# 控制器逻辑
- 观察:通过监控Kubernetes资源对象变化的事件来获取当前对象状态,我们只需要注入EventHandler让client-go将变化的事件对象信息放入WorkQueue中。
- 分析:确定当前状态和期望状态的不同,由Worker完成。
- 执行:执行能够驱动对象当前状态变化的操作,由Worker完成。
- 更新:更新对象的当前状态,由Worker完成。
# Client类型
RESTClient
: 最基础的客户端,提供最基本的封装Clientset
:是一个Client的集合,在Clientset中包含了所有K8S内置资源的Client,通过Clientset便可以很方便的操作如Pod、Service这些资源dynamicClient
:动态客户端,可以操作任意K8S的资源,包括CRD定义的资源DiscoveryClient
:用于发现K8S提供的资源组、资源版本和资源信息,比如:kubectl api-resources
# RESTClient的使用
RESTClient 是底层的用于网络请求的对象,可以直接通过 RESTClient 提供的 RESTful 方法如 Get()、Put()、Post()、Delete() 等和 APIServer 进行交互。
同时支持 JSON 和 protobuf 两种序列化方式
支持所有原生资源
RESTClientFor
: 为创建RESTClient
准备config,比如限速器、编解码器等UnversionedRESTClientFor
: 与RESTClientFor
类似,只是允许config.GroupVersion为空
...
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
...
client, err := RESTClientFor(config)
# Clientset的使用
Clientset 是调用 Kubernetes 资源对象最常用的客户端,可以操作所有的资源对象。
Kubernetes 集群资源的方式,通过 client-go 提供的 Clientset 对象来获取资源数据,主要有以下三个步骤:
- 使用 kubeconfig 文件或者 ServiceAccount(InCluster 模式)来创建访问 Kubernetes API 的 Restful 配置参数,也就是代码中的
rest.Config
对象 - 使用 rest.Config 参数创建 Clientset 对象,这一步非常简单,直接调用
kubernetes.NewForConfig(config)
即可初始化 - 然后是 Clientset 对象的方法去获取各个 Group 下面的对应资源对象进行 CRUD 操作
...
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err)
}
clientset, err := kubernetes.NewForConfig(config)
deploymentsClient := clientset.AppsV1().Deployments()
...
# dynamicClient的使用
deployment、pod这些资源,其数据结构是明确的固定的,可以精确对应到Clientset中的数据结构和方法,但是对于CRD(用户自定义资源),Clientset客户端就无能为力了
。此时需要有一种数据结构来承载资源对象的数据,也要有对应的方法来处理这些数据;- 此刻,前面提到的Unstructured可以登场了,没错,把Clientset不支持的资源对象交给Unstructured来承载,接下来看看dynamicClient和Unstructured的关系:
- 先看数据结构定义,和clientset没啥区别,只有个restClient字段:
type dynamicClient struct {
client *rest.RESTClient
}
使用方法:
...
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err)
}
client, err := dynamic.NewForConfig(config)
...
# DiscoveryClient的使用
kubectl api-versions命令,大家应该不陌生吧,可以返回当前kubernetes环境的所有Group+Version的组合,如下:
[root@k8s-master ~]# kubectl api-versions
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
authentication.k8s.io/v1
...
通过查看kubectl源码可见,上述命令的背后就是使用了DiscoveryClient来实现的,使用如下:
...
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err)
}
client, err := discovery.NewDiscoveryClientForConfig(config)
...
另外还有两个DiscoveryClient,分别支持将数据缓存在磁盘文件或内存当中
上次更新: 2023/11/28, 22:03:59