2.2.2 Client-go主体结构
Client-go 共支持 4 种与 Kubernetes APIServer交互的客户端逻辑,如图 2-4所示。
(1) RESTClient:最基础的客户端,它主要对 HTTP请求进行了封装,并且支持JSON和Protobuf格式数据。
(2) DiscoveryClient:发现客户端,发现API- Server 支持的资源组、资源版本和资源信息。如 Kubectl Api-Versions 。
(3) ClientSet:Kubernetes自身内置资源的客户端集合,仅能操作已知类型的内置资源,如Pods、Service 等。
图2—4 Cient交互图
(4) DynamicClient:动态客户端,可以对任意的 Kubernetes 资源执行通用操作,包括 CRD。
1. RESTClient
RESTClient是所有客户端的父类,RESTClient提供的 RESTful方法(如 Get()、Put()、Post()、Delete() 等 )与KubernetesAPIServer进 行 交 互,ClientSet、DynamicClient和DiscoveryClient等也都是基于 RESTClient 二次开发实现的。因此,RESTClient可以操作Kubernetes自身内置的原生资源以及 CRD。
前面Example,目录中的out-of-cluster-client-configuration 示例,用RESTClient实现的代码见代码清单 2-10。
packagemain
import(
"context""fmt"
corev1"k8s.io/api/core/v1"
metav1"k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/client-go/kubernetes/scheme""k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
funcmain(){
//加载配置⽂件,⽣成 config对象
config,err:=clientcmd.BuildConfigFromFlags("","/root/.kube/config")
iferr!=nil{
panic(err.Error())
}
//配置 API路径和请求的资源组 /资源版本信息
config.APIPath="api"
config.GroupVersion=&corev1.SchemeGroupVersion
//配置数据的编解码器
config.NegotiatedSerializer=scheme.Codecs
//实例化RESTClient对象
restClient,err:=rest.RESTClientFor(config)
iferr!=nil{
panic(err.Error())
}
//预设返回值存放对象
result:=&corev1.PodList{}
//Get⽅法设置HTTP请求⽅法 ;Namespace⽅法设置操作的命名空间
//Resource⽅法设置操作的资源类型 ;VersionedParams⽅法设置请求的查询参数
//Do⽅法发起请求并⽤Into⽅法将APIServer返回的结果写⼊Result变量中
err=restClient.Get().
Namespace("default").Resource("pods").
VersionedParams(&metav1.ListOptions{Limit:100},scheme.ParameterCodec).Do(context.TODO()).
Into(result)
iferr!=nil{panic(err)
}
//打印Pod信息
for _,d:=rangeresult.Items{fmt.Printf(
"NAMESPACE:%v\tNAME:%v\tSTATUS:%v\n",
d.Namespace,d.Name,d.Status.Phase,
)
}
}
运行以上代码,会获得命名空间 Default下的所有 Pod 资源的相关信息,部分信息打印输出见代码清单 2-11。
# 运⾏输出
NAMESPACE:default NAME:nginx-deployment-6b474476c4-lpld7
STATUS:Running
NAMESPACE:default NAME:nginx-deployment-6b474476c4-t6xl4
STATUS:Running
RESTClient 实际上是对 KubernetesAPIServer的 RESTfulAPI 的访问进行了封装抽象,底层调用的是 Go语言 Net/Http库。
分析 RESTClient发起请求的过程如下。
(1) Get方法返回Request类型对象(见代码清单2-12)。
//GetbeginsaGETrequest.Shortforc.Verb("GET").func(c*RESTClient)Get()*Request{
returnc.Verb("GET")
}
(2) Request结构体对象用于构建访问 APIServer的请求, 示例中依次调用的Namespace、Resource、VersionedParams、Do等方法都是 Request结构体的方法,最终Do方法中r.request 发起请求,r.transformResponse将 APIServer 的返回值解析成corev1.PodList类型对象,即示例中的Result变量(见代码清单2-13)。
func(r*Request)Do(ctxcontext.Context)Result{varresultResult
err:=r.request(ctx,func(req*http.Request,resp*http.Response){result=r.transformResponse(resp,req)
})
//...
}