参考文档:
代码结构
[root@77DDE94FF07FCC1-wsl /ACode/client-go] tree -d -L 1 -I "testing|examples|*_test*|Godeps|third_party|metadata|deprecated|restmapper"
.
├── discovery # 定义DsicoveryClient客户端。作用是用于发现k8s所支持GVR(Group, Version, Resources)。
├── dynamic # 定义DynamicClient客户端。可以用于访问k8s Resources(如: Pod, Deploy...),也可以访问用户自定义资源(即: CRD)。
├── informers # k8s中各种Resources的Informer机制的实现。
├── kubernetes # 定义ClientSet客户端。它只能用于访问k8s Resources。每一种资源(如: Pod等)都可以看成是一个客端,而ClientSet是多个客户端的集合,它对RestClient进行了封装,引入了对Resources和Version的管
| # 理。通常来说ClientSet是client-gen来自动生成的。
├── listers # 提供对Resources的获取功能。对于Get()和List()而言,listers提供给二者的数据都是从缓存中读取的。
├── pkg
├── plugin # 提供第三方插件。如:GCP, OpenStack等。
├── rest # 定义RestClient,实现了Restful的API。同时会支持Protobuf和Json格式数据。
├── scale # 定义ScalClient。用于Deploy, RS, RC等的扩/缩容。
├── tools # 定义诸如SharedInformer、Reflector、DealtFIFO和Indexer等常用工具。实现client查询和缓存机制,减少client与api-server请求次数,减少api-server的压力。
├── transport
└── util # 提供诸如WorkQueue、Certificate等常用方法。
12 directories
代码简单示例
获取kubeconfig及context
func main() {
var kubeconfig *string
// 默认会从~/.kube/config路径下获取配置文件
if home := homeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional)absolute path to the kubeconfig file")
} else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}
flag.Parse()
// 使用k8s.io/client-go/tools/clientcmd生成config的对象
if config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig); err != nil {
panic(err.Error())
}
}
创建clientSet客户端
// 使用k8s.io/client-go/kubernetes生成一个ClientSet的客户端,客户端生成后,就可以使用这个客户端与k8s API server进行交互了,如获取资源列表、Create/Update/Delete资源等
clientset, err := kubenetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
使用clientSet客户端获取集群中的pods—RestClient
for {
// 使用ClientSet客户端获取集群中所有的Pods。其中:ListOptions的结构如下:
// type ListOptions struct {
// TypeMeta `json:",inline"`
// LabelSelector string `json:"labelSelector,omitempty"`
// FieldSelector string `json:"fieldSelector,omitempty"`
//}
pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("Number of pods are: %d\n", len(pods.Items))
}
使用clientSet客户端获取集群中指定的pod
for {
// 在这里我们从default这个namespace中获取了名为my-pod的Pod对象
pod, err := clientset.CoreV1().Pods("default").Get("my-pod", metav1.GetOptions{})
if err != nil {
painc(err.Error())
}
fmt.Printf("%v\n\n\n\n", pod.spec)
}
各种clients详解
client-go中比较重要的client有:
- RestClient
- ClientSet
- DiscoveryClient
- DynamicClient
其中,RestClient是所有客户端的基础,后三者都是对RestClient的封装。RestClient
它通过kubeconfig
与k8s-api-server
进行交互。详细结构如下图:
ClientSets使用预生成的API对象, 这样的好处是当本地的API对象与
k8s-api-server
进行交互时会变得比较方便,方便的同时,随之也带来了版本与类型强耦合的问题。DynamicClient则使用
unstructured.Unstructured
表示来自API Server的所有对象值。Unstructured
类型是一个嵌套的map[string]inferface{}
值的集合来创建一个内部结构,这一点类似于RESTful API
中的Json
数据,这样可以解决ClientSet
中出现的强耦合的问题。- 换句话说,当客户端的API发生变化时,
DynamicClient
无需重新编译。DynamicClient
使所有数据实现延时绑定,即只有到运行时才会实现绑定,这意味着程序运行之前,使用DynamicClient
的程序将不会对对象进行Validation
,这也是本client
的一个缺点。