参考文档:

  1. client-go官方库
  2. 从内部访问api-server
  3. 从外部访问api-server

代码结构

  1. [root@77DDE94FF07FCC1-wsl /ACode/client-go] tree -d -L 1 -I "testing|examples|*_test*|Godeps|third_party|metadata|deprecated|restmapper"
  2. .
  3. ├── discovery # 定义DsicoveryClient客户端。作用是用于发现k8s所支持GVR(Group, Version, Resources)。
  4. ├── dynamic # 定义DynamicClient客户端。可以用于访问k8s Resources(如: Pod, Deploy...),也可以访问用户自定义资源(即: CRD)。
  5. ├── informers # k8s中各种Resources的Informer机制的实现。
  6. ├── kubernetes # 定义ClientSet客户端。它只能用于访问k8s Resources。每一种资源(如: Pod等)都可以看成是一个客端,而ClientSet是多个客户端的集合,它对RestClient进行了封装,引入了对Resources和Version的管
  7. | # 理。通常来说ClientSet是client-gen来自动生成的。
  8. ├── listers # 提供对Resources的获取功能。对于Get()和List()而言,listers提供给二者的数据都是从缓存中读取的。
  9. ├── pkg
  10. ├── plugin # 提供第三方插件。如:GCP, OpenStack等。
  11. ├── rest # 定义RestClient,实现了Restful的API。同时会支持Protobuf和Json格式数据。
  12. ├── scale # 定义ScalClient。用于Deploy, RS, RC等的扩/缩容。
  13. ├── tools # 定义诸如SharedInformer、Reflector、DealtFIFO和Indexer等常用工具。实现client查询和缓存机制,减少client与api-server请求次数,减少api-server的压力。
  14. ├── transport
  15. └── util # 提供诸如WorkQueue、Certificate等常用方法。
  16. 12 directories

代码简单示例

图例:
client-go概述 - 图1

获取kubeconfig及context

  1. func main() {
  2. var kubeconfig *string
  3. // 默认会从~/.kube/config路径下获取配置文件
  4. if home := homeDir(); home != "" {
  5. kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional)absolute path to the kubeconfig file")
  6. } else {
  7. kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
  8. }
  9. flag.Parse()
  10. // 使用k8s.io/client-go/tools/clientcmd生成config的对象
  11. if config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig); err != nil {
  12. panic(err.Error())
  13. }
  14. }

创建clientSet客户端

  1. // 使用k8s.io/client-go/kubernetes生成一个ClientSet的客户端,客户端生成后,就可以使用这个客户端与k8s API server进行交互了,如获取资源列表、Create/Update/Delete资源等
  2. clientset, err := kubenetes.NewForConfig(config)
  3. if err != nil {
  4. panic(err.Error())
  5. }

使用clientSet客户端获取集群中的pods—RestClient

  1. for {
  2. // 使用ClientSet客户端获取集群中所有的Pods。其中:ListOptions的结构如下:
  3. // type ListOptions struct {
  4. // TypeMeta `json:",inline"`
  5. // LabelSelector string `json:"labelSelector,omitempty"`
  6. // FieldSelector string `json:"fieldSelector,omitempty"`
  7. //}
  8. pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
  9. if err != nil {
  10. panic(err.Error())
  11. }
  12. fmt.Printf("Number of pods are: %d\n", len(pods.Items))
  13. }

使用clientSet客户端获取集群中指定的pod

  1. for {
  2. // 在这里我们从default这个namespace中获取了名为my-pod的Pod对象
  3. pod, err := clientset.CoreV1().Pods("default").Get("my-pod", metav1.GetOptions{})
  4. if err != nil {
  5. painc(err.Error())
  6. }
  7. fmt.Printf("%v\n\n\n\n", pod.spec)
  8. }

各种clients详解

client-go中比较重要的client有:

其中,RestClient是所有客户端的基础,后三者都是对RestClient的封装。
RestClient它通过kubeconfigk8s-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的一个缺点。

其他client-go组件

client-go概述 - 图2
看不懂!
simple controller