目录

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

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

RESTClient 简介

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

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

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

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

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

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

  5. 调用 RESTClient 实例的方法向 kubernetes 的 API 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 客户端介绍完毕。