Client-go 四种客户端交互对象
Client-go 四种客户端交互对象

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、Versions、Resources
)。
以上 4 种客户端: RESTClient
、 ClientSet
、 DynamicClient
、 DiscoveryClient
都可以通过 kubeconfig
配置信息连接到指定的 Kubernetes API Server
。
RestClient 客户端对象
RESTClient
是最基础的客户端。其他的ClientSet
、DynamicClient
及DiscoveryClient
都是基于RESTClient
实现的。RESTClient
对HTTP Request
进⾏了封装,实现了RESTful
⻛格的API
。它具有很⾼的灵活性,数据不依赖于⽅法和资源,因此RESTClient
能够处理多种类型的调⽤,返回不同的数据格式。
类似于 kubectl
命令,通过 RESTClient
列出 kube-system
运⾏的 Pod
资源对象, RESTClient Example
代码⽰例 :
package main
import (
"context"
"flag"
"fmt"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"path/filepath"
)
func main() {
var kubeconfig *string
// home是家目录,如果能取得家目录的值,就可以用来做默认值
if home:=homedir.HomeDir(); home != "" {
// 如果输入了kubeconfig参数,该参数的值就是kubeconfig文件的绝对路径,
// 如果没有输入kubeconfig参数,就用默认路径~/.kube/config
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
// 如果取不到当前用户的家目录,就没办法设置kubeconfig的默认目录了,只能从入参中取
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}
flag.Parse()
// 从本机加载kubeconfig配置文件,因此第一个参数为空字符串
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
// kubeconfig加载失败就直接退出了
if err != nil {
panic(err.Error())
}
// 参考path : /api/v1/namespaces/{namespace}/pods
config.APIPath = "api"
// pod的group是空字符串
config.GroupVersion = &corev1.SchemeGroupVersion
// 指定序列化工具
config.NegotiatedSerializer = scheme.Codecs
// 根据配置信息构建restClient实例
restClient, err := rest.RESTClientFor(config)
if err!=nil {
panic(err.Error())
}
// 保存pod结果的数据结构实例
result := &corev1.PodList{}
// 指定namespace
namespace := "kube-system"
// 设置请求参数,然后发起请求
// GET请求
err = restClient.Get().
// 指定namespace,参考path : /api/v1/namespaces/{namespace}/pods
Namespace(namespace).
// 查找多个pod,参考path : /api/v1/namespaces/{namespace}/pods
Resource("pods").
// 指定大小限制和序列化工具
VersionedParams(&metav1.ListOptions{Limit:100}, scheme.ParameterCodec).
// 请求
Do(context.TODO()).
// 结果存入result
Into(result)
if err != nil {
panic(err.Error())
}
// 打印名称
fmt.Printf("Namespace\t Status\t\t Name\n")
// 每个pod都打印Namespace、Status.Phase、Name三个字段
for _, d := range result.Items {
fmt.Printf("%v\t %v\t %v\n",
d.Namespace,
d.Status.Phase,
d.Name)
}
}
运⾏以上代码,列出 kube-system
命名空间下的所有 Pod
资源对象的相关信息。⾸先加载 kubeconfig
配置信息,并设置 config.APIPath
请求的 HTTP
路径。然后设置 config.GroupVersion
请求的资源组/资源版本。最后设置 config.NegotiatedSerializer
数据的编解码器。
rest.RESTClientFor
函数通过 kubeconfig
配置信息实例化 RESTClient
对象, RESTClient
对象构建 HTTP
请求参数,例如 Get
函数设置请求⽅法为 get
操作,它还⽀持 Post
、Put
、Delete
、Patch
等请求⽅法。 Namespace
函数设置请求的命名空间。 Resource
函数设置请求的资源名称。 VersionedParams
函数将⼀些查询选项(如 limit、TimeoutSeconds
等)添加到请求参数中。通过 Do
函数执⾏该请求,并将 kube-apiserver
返回的结果( Result 对象
)解析到 corev1.PodList
对象中。最终格式化输出结果。
RESTClient
发送请求的过程对 Go
语⾔标准库 net/http
进⾏了封装,由 Do→request
函数实现,代码⽰例如下:
代码路径: vendor/k8s.io/client-go/rest/request.go
func (r *Request) Do(ctx context.Context) Result {
var result Result
err := r.request(ctx, func(req *http.Request, resp *http.Response) {
result = r.transformResponse(resp, req)
})
if err != nil {
return Result{err: err}
}return result
}
请求发送之前需要根据请求参数⽣成请求的 RESTful URL
,由 r.URL.String
函数完成。例如,在 RESTClient Example
代码⽰例中,根据请求参数⽣成请求的 RESTful URL
为 http://127.0.0.1:8080/api/v1/namespaces/kube-system/pods?limit=500
,其中 api
参数为 v1
,namespace
参数为 system
,请求的资源为 pods
, limit
参数表⽰最多检索出 500
条信息。
最后通过 Go
语⾔标准库 net/http
向 RESTful URL
(即 kube-apiserver
)发送请求,请求得到的结果存放在 http.Response
的 Body
对象中, fn 函数
(即 transformResponse
)将结果转换为资源对象。当函数退出时,会通过 resp.Body.Close
命令进⾏关闭,防⽌内存溢出。