目录

Client-go简单教程(二)-RESTClient

RESTClient是最基础的版本,其他三种都是基于RESTClient封装的.

RESTClient 简介

RESTClientclient-go 最基础的客户端,主要是对 HTTP Reqeust 进行了封装,对外提供 RESTful 风格的 API ,并且提供丰富的 API 用于各种设置,相比其他几种客户端虽然更复杂,但是也更为灵活。

使用 RESTClientkubernetes 的资源进行增删改查的基本步骤如下:

  1. 确定要操作的资源类型(例如查找 deployment 列表),去官方API文档中找到对于的 path 、数据结构等信息,后面会用到。

  2. 加载配置 kubernetes 配置文件(和 kubectl 使用的那种 kubeconfig 完全相同)。

  3. 根据配置文件生成配置对象,并且通过API对配置对象就行设置(例如请求的 pathGroupVersion、序列化反序列化工具等)。

  4. 创建 RESTClient 实例,入参是配置对象。

  5. 调用 RESTClient 实例的方法向 kubernetesAPI Server 发起请求,编码用 fluent 风格将各种参数传入(例如指定 namespace、资源等),如果是查询类请求,还要传入数据结构实例的指针,改数据结构用于接受 kubernetes 返回的查询结果。

RESTClient 编码

新建main.go,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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)
	}
}

编码完成,执行go run main.go,即可获取指定namespace下所有pod的信息,控制台输出如下:

1
2
3
4
5
6
7
8
9
$ go run main.go
namespace        status          name
kube-system      Running         coredns-7f89b7bc75-j8sqm
kube-system      Running         coredns-7f89b7bc75-sq8gj
kube-system      Running         etcd-ops-k8s-node1
kube-system      Running         etcd-ops-k8s-node2
kube-system      Running         etcd-ops-k8s-node3
kube-system      Running         kube-apiserver-ops-k8s-node1
...

至此,RESTClient 客户端介绍完毕。