client-go源码结构及Client客户端对象

1. client-go源码结构及说明

源码目录结构及说明:

源码目录

说明

discovery

提供DiscoveryClient发现客户端

dynamic

提供DynamicClient动态客户端

informers

每种kubernetes资源的动态实现

kubernetes

提供ClientSet客户端

listers

为每一个kubernetes资源提供Lister功能,该功能对Get和List请求提供只读的缓存数据

plugin

提供OpenStack、GCP和Azure等云服务商授权插件

rest

提供RESTClient客户端,对Kuberntes API Server执行RESTful操作

scale

提供ScaleClient客户端,用于扩容或缩容Deployment、ReplicaSet、Replication Controller等资源对象

tools

提供常用工具,例如Sharedinformer、Reflector、DealtFIFO及Indexers。提供Client查询和缓存机制,以减少向kube-apiserver发起的请求数等

transport

提供安全的TCP连接,支持Http Stream,某些操作需要在客户端和容器之间传输二进制流,例如exec、attach等操作。该功能由内部的spdy包提供支持

util

提供常用方法,例如WorkQueue工作队列、Certificate证书管理

2. Client客户端对象

client-go支持4种客户端对象与Kubernetes API Server进行交互,如图所示:

RESTClient是最基础的客户端。RESTClient对HTTP Request进行了封装,实现了RESTful风格的API。ClientSet、DynamicClient及DiscoveryClient客户端都是基于RESTClient实现的。

  • ClientSet在RESTClient的基础上封装了对Resource和Version的管理方案。每一个Resource可以理解为一个客户端,而ClientSet则是多个客户端的集合,每一个Resource和Version都以函数的方式暴露给开发者。ClientSet只能够处理Kubernetes内置资源,它是通过client-gen代码生成器自动生成的。

  • DynamicClient与ClientSet最大的不同之处是,ClientSet仅能访问Kubernetes自带的资源(即Client集合内的资源),不能直接访问CRD自定义资源。DynamicClient能够处理Kubernetes中的所有资源对象,包括Kubernetes内置资源与CRD自定义资源

  • DiscoveryClient发现客户端,用于发现kube-apiserver所支持的资源组、资源版本、资源信息(即Group、Version、Resources)

以上4种客户端都可以通过kubeconfig配置信息连接到指定到Kubernetes API Server。

2.1 kubeconfig配置管理

kubeconfig可用于管理访问kube-apiserver的配置信息,也支持多集群的配置管理,可在不同环境下管理不同kube-apiserver集群配置。kubernetes的其他组件都是用kubeconfig配置信息来连接kube-apiserver组件。kubeconfig存储了集群、用户、命名空间和身份验证等信息,默认kubeconfig存放在$HOME/.kube/config路径下。kubeconfig的配置信息如下:

kubeconfig配置信息分为3部分,分别为:

  • clusters:定义kubernetes集群信息,例如kube-apiserver的服务地址及集群的证书信息

  • users:定义kubernetes集群用户身份验证的客户端凭据,例如client-certificate、client-key、token及username/password等。

  • context:定义kuberntes集群用户信息和命名空间等,用于将请求发送到指定的集群

2.1.1 代码练习

由于在windows上进行,所以采用的环境变量的形式设置的kubeconfig文件,查询pod信息,代码如下:

2.1.3 合并多个kubeconfig配置信息

多个配置信息合并如图所示:

源码路径:k8s.io\client-go\tools\clientcmd\loader.go

从代码中可以看出,merge分为四步,①先将map类型的config进行合并到mapConfig中;②将非map类型的配置合并到nonMapConfig中;@将mapConfig合并到config中;④将nonMapConfig合并到config中;

2.2 RESTClient客户端

RESTClient是最基础的客户端,其他的ClientSet、DynamicClient及DiscoveryClient都是基于RESTClient实现的。RESTClient对HTTP Request进行了封装,实现了RESTful风格的API。

2.2.1 代码练习

2.2.2 源码分析

由上练习得知,RESTClient发送请求的过程对Go语言的标准库net/http进行了封装,由Do—>request函数实现,源码如下:

源码路径:k8s.io\client-go\rest\request.go

其中,r.transformResponse(resp, req)作为传入函数的函数体;是真正对result对象进行解析的函数。request函数源码如下:

源码路径:k8s.io\client-go\rest\request.go

2.3 ClientSet客户端

RESTClient是最基础的客户端,使用时需要指定Resource和Version等信息,编写代码时需要提前知道Resource所在的Group和对应的Version信息。ClientSet相比而言使用更加便捷,一般情况,对Kubernetes进行二次开发时通常使用ClientSet。 ClientSet在RESTClient的基础上封装了对Resource和Version的管理方法,每个Resource可以理解为一个客户端,而ClientSet则是多个客户端的集合,每个Resource和Version都以函数的方式暴露给开发者。

注意:ClientSet仅能访问Kubernetes自身的内置资源,不能直接访问CRD自定义资源;如果需要使用ClientSet访问CRD,则需要通过client-gen代码生成器重新生成ClientSet;DynamicClient可以访问CRD资源

2.3.1 代码练习

2.3.2 源码分析

  1. 追踪kubernetes.NewForConfig(config)函数,可以看到,针对不同的资源类型,都有一个NewForConfig函数,源码如下:

源码路径:k8s.io\client-go\kubernetes\clientset.go

继续进入一层的NewForConfig中,调用的是rest.RESTClientFor(&config)来生成客户端。源码如下:

  1. 追踪Pods函数的代码,可以看到返回的pods函数对象中的client为RESTClient,源码如下:

源码路径:k8s.io\client-go\kubernetes\typed\core\v1\pod.go

  1. 追踪的Pods函数的List方法源码如下:

源码路径:k8s.io\client-go\kubernetes\typed\core\v1\pod.go

2.4 DynamicClient客户端

DynamicClient客户端是一种动态客户端,可以对任意的Kubernetes资源进行RESTful操作,包括CRD资源。 DynamicClient内部实现了Unstructured,用于处理非结构化数据结构(即无法提前预知的数据结构),这也是DynamicClient能够处理CRD资源的关键。

DynamicClient不是类型安全的,因此在访问CRD自定义资源是要注意,例如,在操作不当时可能会导致程序崩溃。 DynamicClient的处理过程是将Resource(如PodList)转换成Unstructured结构类型,Kubernetes的所有Resource都可以转换为该结构类型。处理完后再将Unstructured转换成PodList。过程类似于Go语言的interface{}断言转换过程。另外,Unstructured结构类型是通过map[string]interface{}转换的。

2.4.1 代码练习

2.5 DiscoveryClient客户端

DiscoveryClient是发现客户端,主要用于发现Kubenetes API Server所支持的资源组、资源版本、资源信息。 kubectl的api-versions和api-resources命令输出也是通过DiscoveryClient实现的。其同样是在RESTClient的基础上进行的封装。DiscoveryClient还可以将资源组、资源版本、资源信息等存储在本地,用于本地缓存,减轻对kubernetes api sever的访问压力,缓存信息默认存储在:~/.kube/cache和~/.kube/http-cache下。

2.5.1 代码练习

2.5.2获取Kubernetes API Server所支持的资源组、资源版本及资源信息

DiscoveryClient通过RESTClient分别请求/api和/apis接口,从而获取Kubernetes API Server的信息,其核心实现位于ServerGroupsAndResources —> ServerGroups中。

源码路径:k8s.io\client-go\discovery\discovery_client.go

2.5.3 本地缓存的DiscoveryClient

DiscoveryClient可将资源相关信息存储在本地,默认每10分钟与kubernetes api server同步一次。 DiscoveryClient第一次获取资源组,资源版本,资源信息时,首先会查询本地缓存,如果数据不存在(没有命中)则请求Kubernetes API Server接口(回源),Cache将Kubernetes API Server响应的数据存储在本地一份并返回给DiscoveryClient。当下一次DiscoveryClient再次获取资源信息时,会将数据直接从本地缓存返回(命中)给DiscoveryClient。本地缓存的默认存储周期为10分钟。

流程如图所示:

源码路径:k8s.io\client-go\discovery\cached\disk\cached_discovery.go

通过源码可知,DiscoveryClient是通过创建的Client是DiscoveryClient还是CachedDiscoveryClient来决定是从缓存中读取还是从api-server中进行读取。

Last updated

Was this helpful?