k8s的client-go的使用
学习地址:https://github.com/kubernetes/client-go
如果你要安装最新的需要的环境是: go1.16+ ,使用下面的命令安装:
go get k8s.io/client-go@latest
client-go 是用 Golang 语言编写的官方编程式交互客户端库,提供对 Kubernetes API server 服务的交互访问。它是 Kubernetes 的核心处理框架,k8s源码中已经集成了client-go的源码,无需单独下载。源码路径为:vendor/k8s.io/client-go。
k8s开发者使用client-go做二次开发,所以应该熟练掌握。
1、client-go源码结构
其源码目录结构如下:
-
discovery: 提供 DiscoveryClient 发现客户端。
-
dynamic: 提供 DynamicClient 动态客户端。
-
informers: 每种 K8S 资源的 Informer 实现。
-
kubernetes: 提供 ClientSet 客户端。
-
listers: 为每一个 K8S 资源提供 Lister 功能,该功能对 Get 和 List 请求提供只读的缓存数据。
-
plugin: 提供 OpenStack,GCP 和 Azure 等云服务商授权插件。
-
rest: 提供 RESTClient 客户端,对 K8S API Server 执行 RESTful 操作。
-
scale: 提供 ScaleClient 客户端,用于扩容或缩容 Deployment, Replicaset, Replication Controller 等资源对象。
-
tools: 提供常用工具,例如 SharedInformer, Relector, DealtFIFO 及 Indexers。 提供 Client 查询和缓存机制,以减少想 kube-apiserver 发起的请求数等。主要子目录为 /tools/cache。
-
transport: 提供安全的 TCP 连接,支持 HTTP Stream,某些操作需要在客户端和容器之间传输二进制流,例如 exec,attach 等操作。该功能由内部的 SPDY 包提供支持。
-
util: 提供常用方法。例如 WorkQueue 工作队列,Certificate 证书管理等。
这章我们只简单介绍下RESTClient、DiscoveryClient、DynamicClient、ClientSet这4中客户端。
2、Client客户端对象
client-go 支持4种Client客户端对象 与 k8s api server 交互的方式,Client交互对象如下图所示:
RESTClient 是最基础的客户端。RESTClient 对 HTTP Request 进行了封装,实现了RESTful风格的api。ClientSet、DynamicClient及DiscoveryClient客户端都是基于RESTClient 实现的。
-
RESTClient 客户端
RESTful Client 是最基础的客户端,它主要是对 HTTP 请求进行了封装,并且支持 JSON 和 Protobuf 格式数据。
-
DynamicClient 客户端
DynamicClient 与 ClientSet 最大的不同之处是,ClientSet 仅能访问k8s自带的资源,不能直接访问CRD自定义资源。DynamicClient 能处理k8s中的所有的资源对象,包括内置资源与CRD自定义资源。
-
ClientSet 客户端
ClientSet 客户端在 RESTClient 的基础上封装了对资源(Resource)和版本(Version)的管理方法。每个资源(Resource)可以理解为一个客户端,而 ClientSet 则是多个客户端的集合,每一个资源(Resource)和版本(Version)都以函数的方式暴露给开发者。ClientSet 只能处理k8s内置资源。
-
DiscoveryClient 客户端
DiscoveryClient 发现客户端,用于发现 kube-apiserver 所支持的资源组、资源版本、资源信息(即Group、Versions、Resources)
以上4种客户端:RESTClient 、DynamicClient 、ClientSet 、DiscoveryClient 都可以通过kubeconfig配置信息连接到指定的 kubernetes api server。
3、kubeconfig配置管理
kubeconfig 用于管理访问 kube-apiserver 的配置信息,k8s的其他组件都使用 kubeconfig 配置信息来连接 kube-apiserver组件,例如:kubectl 访问 kube-apiserver 时,会默认加载 kubeconfig 配置信息。
kubeconfig 中存储了集群、用户、命名空间和身份验证等信息,在默认情况下,kubeconfig 存在在$HOME/.kube/config路径下。配置信息如下:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1URXhOakE0TXpJeU5Gb1hEVE14TVRFeE5EQTRNekl5TkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS0krClAyV3A1RDlTSk1NZllTNU1QMnFsQWx0MTh3OVptSkhjUlRxQ3R5Mms1NVloaVNrTzBXYzFaVEd2ZHZId0FqWjMKWnRFUVRwUFp0bXBaL3BUUEtNUkx5U1ZObU9PMjZhb2d0dTZJclpKbzMrQzVhTk9zQzVtTUZIUDRCcGE2aUk4Mwp0VWlORVRCRjhBbTlGdW9SVGhkZlVTelVNdUF6ZlJ5ZXU4L0NKcW4rVXJ5UjRhSE9ncHJxNmptNXZubDVqbUxoCnVMQjN5VTRMRVJUZDBmRWJIa09uRnR3cG42OEpOVnZLck1vajc3aHJ3RGdaTEVQQ0dQU0dxNEJ5dkRKQjhIWEoKb3JhUFBJVWNiNDlFcmx2TzJHOXFnODZDUWV4NEpBWEpSTldjcjlsblJtaEdoTkJwc1VXZ3VFRm1iMUxINjREdwpsMWVqbENURXJqblNqNjRZLzJzQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFJbDhJaStKWW1YOWdlVjVxaDUvWStIRFRhbjAKR2VldldQamtvdnFza0dReW1PT0hIak4rRHdPK2dZemVodGNUSUtPWVQvczhjOFlEUm1GTng4ZUI4RWVTRkJNaQpBWnMzaUE4b0NFTkdQUGF3QWdDbEFBTGp0SmNLOXR4RHdGdm5WcUsrUGk3bW52cmJtUVhxQzJRS1JRcEQ1VnlpCjZFeWRQdGlFZWRvSm93ZC9rdHh2UVlDSitGZFRBZHl3VVlxQzk1UDBLczhUanpEUDNaRVZnYkJER05kT0hIWVcKUXNOeG5DaDB0ZlpEbkl6ZCtCZ25SSDNLL1c0bWVCOXpYTzFrWVNLK2NGbFduWG40OUo1QmlEMkI3ZHk3eWt1Kwo0MUdvdGVrSjc3NXIySFlyR2dmaG9mYWtCenZnZEV2U1J0Y243OVkwTkZ6dmhUeFZIRWp5VExqTEY4TT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://127.0.0.1:16443
name: cluster-10.9.244.32
contexts:
- context:
cluster: cluster-10.9.244.32
user: kubernetes-admin
name: kubernetes-admin@cluster-10.9.244.32
current-context: kubernetes-admin@cluster-10.9.244.32
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lJQ3p5OXR6SzhhclV3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TVRFeE1UWXdPRE15TWpSYUZ3MHlNakV4TVRZd09ETXlNalphTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXZ2UnhDaHVzblo1MU1zYU0KN01FZkVaUzdFb3ZlZUZTRTJ2MVZtOWt2U3dpVzVUclhqOG1LdWFjVWszZVdBMDdmVHdjMkJ3ZjNjVEFNazAxTQpHbU41bzEvcFdkam40TjdsdmxkeEZKclVVVkZGK3k4SUxySkVVdUhWdEtLUHZkM29jakxBTktwbGRCcWtrTTZVCmlKL0JKa3lvOXpPUWpBN0dUVmtBdTlQaFNDRktQUVhibjZHUUIrZW1LN1cxTFRkM1diQ2tacGE2NjVpUWhLRzMKKzhRMXJlMHFzcm9kQzNnV0Vna0N5TjNRUzIwRGowa0drMzJvWkp3Zkx5cUJOaUFNVzZ2azRpVjJqaEFTWDRYSwpEZ3pQVUNOUDFSSFkxZitkTEtBNzhoNXMremhTUi93VkxXajVPUlIvZ1hhcFRtZG80dy84NEpKbExwTWVScXJGCjQ0Y1Rhd0lEQVFBQm95Y3dKVEFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFKNWZQMHVScWJhbkJLTnl5eVErVzVmaExQejYzK0hEVGNiTgptUTlKdFlNUk1MN3hkWkxRVXM1T1N1cWo4QWNiMWNXSXFNNkRhUmJVc2dlTFh6SEg3WDJjUzF5T1gvSFJ5L0ZPClBKdFcwRlhkbVhWWE1PbU5JWldwVWRmT08vYkx2eURhY2N4RkZ6alFkVksvdmg5Q2VqNkYvWnpVWXdkVlQ1eXQKenVYZ2llV2VxTFpzT1hZMlhyWmN5Vzg4Ky9VYUVaczdYR01xVEhSYjlUQi9iTTlxL0FnWHRscThlZEZvS1JkZwpYd2hFY0RzOWZuS2RwSG13QlVkV1lDcDFNNmVzamtObk9mMVU4Rk9OeXdUNm5xVG52VkgzQ1UzTkQxMSs5Y2IyCm1qSmVXK0QrRUd1VXZTR2tSamdLY1VYS1NCWXhwVWFoOWFWWGN3RjNnakhxa1RaaHZ0VT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBdnZSeENodXNuWjUxTXNhTTdNRWZFWlM3RW92ZWVGU0UydjFWbTlrdlN3aVc1VHJYCmo4bUt1YWNVazNlV0EwN2ZUd2MyQndmM2NUQU1rMDFNR21ONW8xL3BXZGpuNE43bHZsZHhGSnJVVVZGRit5OEkKTHJKRVV1SFZ0S0tQdmQzb2NqTEFOS3BsZEJxa2tNNlVpSi9CSmt5bzl6T1FqQTdHVFZrQXU5UGhTQ0ZLUFFYYgpuNkdRQitlbUs3VzFMVGQzV2JDa1pwYTY2NWlRaEtHMys4UTFyZTBxc3JvZEMzZ1dFZ2tDeU4zUVMyMERqMGtHCmszMm9aSndmTHlxQk5pQU1XNnZrNGlWMmpoQVNYNFhLRGd6UFVDTlAxUkhZMWYrZExLQTc4aDVzK3poU1Ivd1YKTFdqNU9SUi9nWGFwVG1kbzR3Lzg0SkpsTHBNZVJxckY0NGNUYXdJREFRQUJBb0lCQUdKYURwclJOREFldkdpQgpvWFlUNWdldEhrbG9KeGE5R1l5ZGJPbVBqRzlPSmtJODgyZ0l1MTN4ODRRYzFQUXhQSTA4dnBRU2cxMFdEWFFWCkhQeCtmZGtxL2txYmtKcmUwMkFkTTQ0VVRRVHhJbVZFalNkWUJCN1lXTFRvQWJjZVE2b0YvNzlnZ0U2enBrMDcKU1greElNKzBMbGJjaFRmT0tFOFFaM05XcHpMNXBWTEh2eEFyYWNNMWg0K1d4NDZnNHJRN3JwS1BUa2VFa1loYwo3amE2TWl6UjEvZDFUNERqa2JGUnU3SVNSNVpvWithL0o2dGkzSStoc0lqaU0yeE5sQ0Y0MXVZa0lDSkhnMkZYCnlyZkYwZm1YS2c1T1oweWFHTUhTdUNpbE9UUUlnYndMN3RMMWR0bU5YaTBvTzdZbXF5MHFaSVdlV1BRVitJUWkKOXREdXFVa0NnWUVBOXg2TzJCaVBqdzAyUENYQ0xhcHZpVHNCeFRmNVFCbVpkZlEvNFJubGY1T3IwZ2ZmdmgzbApNUDBYYUZraWdaUW83NmJvZlFRd0VNZWdnRkFXNkhFSkVOQTd4Z2NsVlFxTHVST2pUTVNkRVUraUl1eXZ0VFZmClJZYTUxODdCTEFwWThnRHQzQjhjVlN6RGQvdlIrVmJ4MFNJVGdTbVFGSUdtdC9TWmdnMFp4cjhDZ1lFQXhkRXUKeXIwaUxHNWtyRHN3VmxVc3RsU2lHQmxBZEhOMld1eEFncmw5UTdSWEt0V3B0allqTnhMdVJoU1dLOEYzYjBlQwoyaUQxWTljMkgyNmJYelA1OEorTkZyMmNzYmJKdFNmWi9xcXE3Q3V0K2liUng1Q0IyQm1UZDVpWWhqWTNRUjQzCnlOWFhhR2dzUzFQQWt6Q1dVcmVuVHh6bzFBNzRnN05PZjhLVGFsVUNnWUFOaDNyQ2tmV3FHMHNRMS9CZGw2c3IKbEROd25MUGtzb0lZVnhyNE0vYkFtVkVhMnB1QlNSbTNLT1FUTG00Wk1nZGJ0NE9hOUpPOUYzRE9GWlJyZldURgpxdURhNHFGRW1xTXpxc09SL0dHdEJQTVhmbVhRUWUvSldxcnFDY1BCcVg5ZElIZmxTVDYvMndlSWxoelV6ZEhIClpWbzBCQmFEU09YYnhHUnpIa3grK1FLQmdDeXZOL2FzQ3BBbXo2N29IOThnbGwwSmVTUWdjQ0xlQWhvL3k4SzcKeThRRGRMMUVUblhPZk4zdjlNcjMwNFJHeTRmamkzZGlnb3Z2RFZiRVVXeUwvU1dScFBsQ0U2ZEJOd2NvM1dGZApoQWFkUjB0K2dWeW5FKzJRdVhNR2tVMmY2Wk5ZRkJuVjFEYk5jVlFDc3ptTWZDaHJPK3Z2QjlqL0dMd0hRUEF6Ckw4R1JBb0dCQVBVSnZ5NHlsRG1TdkJheFZrdGdXRjRYc096cytCR0sweFI0VEdZa0JNODhRTHFLTVU1RFZCV3MKdjVQQ2xFMVcxOHVJWkZMTzdGUXd5U1ZwZ0cwZ3NOcVBDRjdwVVZmRjg0VkFiWmxCdGJNSWdCcFRIMjU0M2FHegpQMGZNdnFEaU91bksxa0VaWDh4YkdMTHFXZjBBTGgwUkVmbDBTL3pmZ1RDUDBzTTZtKzdJCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
kubeconfig配置信息通常包含3个部分,分别介绍如下:
- clusters:定义kubernetes集群信息,例如kube-apiserver 的服务地址及集群的证书信息等。
- users:定义kubernetes集群用户身份验证的客户端凭据,例如 client-certificate、client-key等信息。
- contexts:定义kubernetes集群用户信息和命名空间等,用于将请求发送到指定的集群。
client-go会读取 kubeconfig 配置信息并生成config对象,用于与kube-apiserver通讯,代码如下:
config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
if err != nil {
panic(err.Error())
}
在上述代码中,clientcmd.BuildConfigFromFlags 函数会读取kubeconfig配置信息并实例化 rest.Config 对象。
4、RESTClient客户端
RESTClient是最基础的客户端,其他的客户端都是基于它实现的。RESTClient对HTTP Request 进行了封装,实现了Restful 风格的api。
类似于kubectl命令,通过RESTClient列出所有运行pod资源对象,代码如下:
package main
import (
"flag"
"fmt"
"context"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
"k8s.io/client-go/kubernetes/scheme"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
config.APIPath = "api"
config.GroupVersion = &corev1.SchemeGroupVersion
config.NegotiatedSerializer = scheme.Codecs
restClient, err := rest.RESTClientFor(config)
if err != nil {
panic(err.Error())
}
result := &corev1.PodList{}
err = restClient.Get().
Namespace("whalebase").
Resource("pods").
VersionedParams(&metav1.ListOptions{Limit: 500}, scheme.ParameterCodec).
Do(context.TODO()).
Into(result)
for _, d := range result.Items {
fmt.Printf("namespace:%v \t name:%v \t status:%+v\n", d.Namespace, d.Name, d.Status.Phase)
}
}
运行以上代码,列出 whalebase 命名空间下所有 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 对象中。最终格式化输出结果。
5、ClientSet 客户端
RESTClient 最基础的客户端,使用时需要指定 Resource 和 Version 等信息,编写代码时需要提前知道 Resource 所在的 Group 和对应的 Version 信息。相比 RESTClient ,ClientSet 使用起来更加便捷,一般情况下,开发者对kubernetes进行二次开发时通常使用 ClientSet。
ClientSet 在 RESTClient 的基础上封装了对 Resource 和 Version 的管理方法。每一个 Resource 可以理解为一个客户端, 而ClientSet 则是多个客户端的集合,每一个 Resource 和 Version 都以函数的形式暴露给开发者。例如 ClientSet 提供的 RbacV1、CoreV1、NetworkingV1 等接口函数,多个 ClientSet 多资源集合如下图:
与 api-server 交互,示例代码如下:
package main
import (
"context"
"flag"
"fmt"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
// create the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
// 获取mysql的pod
namespace := "whalebase"
pod := "mysql-0"
mysqlPod, err := clientset.CoreV1().Pods(namespace).Get(context.TODO(), pod, metav1.GetOptions{})
if errors.IsNotFound(err) {
fmt.Printf("Pod %s in namespace %s not found\n", pod, namespace)
} else if statusError, isStatus := err.(*errors.StatusError); isStatus {
fmt.Printf("Error getting pod %s in namespace %s: %v\n",
pod, namespace, statusError.ErrStatus.Message)
} else if err != nil {
panic(err.Error())
} else {
fmt.Printf("Found pod %s in namespace %s\n", pod, namespace)
bytes, _ := json.Marshal(mysqlPod)
fmt.Println("pod信息:",string(bytes))
}
fmt.Println("--------------------------------")
// 获取mysql的StatefulSets
sts, _ := clientset.AppsV1().StatefulSets(namespace).Get(context.TODO(), "mysql", metav1.GetOptions{})
bytes, _ := json.Marshal(sts)
fmt.Println("sts信息:",string(bytes))
fmt.Println("--------------------------------")
//创建pod
var nginxPod *v1.Pod = &v1.Pod {
TypeMeta: metav1.TypeMeta{Kind:"Pod",APIVersion:"v1"},
ObjectMeta: metav1.ObjectMeta{Name:"nginx-pod"},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "nginx",
Image: "nginx:1.8",
},
},
},
}
_, err = clientset.CoreV1().Pods("default").Create(context.TODO(), nginxPod, metav1.CreateOptions{})
if err != nil {
fmt.Println(err)
}
}
6、DynamicClient 客户端
DynamicClient 是一种动态客户端,它可以与任意 kubernetes 资源进行 RESTful 操作,包括 CRD 自定义资源。DynamicClient 与 ClientSet 操作类似,同样封装了RESTClient,同样提供了Create、Update、Get、List、Watch、Patch 等方法。
DynamicClient 与 ClientSet 最大的不同之处是,ClientSet 仅能访问 kubernetes 自带的资源,不能访问 CRD 自定义资源。 ClientSet 需要预先 实现每种 Resource、Version 的操作,其内部都是结构化数据(即已知数据结构)。而 DynamicClient 内部实现了 Unstructured,用于处理非结构化数据结构(即无法预先提前预知数据结构),这也是 DynamicClient 能够处理CRD自定义资源的关键。
DynamicClient 的处理过程将 Resource (例如PodList)转换成 Unstructured 结构类型, kubernetes 的所有 Resource 都可以转化成该结构类型。处理完成后,再将 Unstructured 转换成 PodList 。整个过程类似于Go语言的interface{}断言转换过程,另外, Unstructured 结构类型是通过 map[string]interface{} 转换的。
package main
import (
"context"
"flag"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/clientcmd"
"path/filepath"
"k8s.io/client-go/util/homedir"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
panic(err.Error())
}
gvr := schema.GroupVersionResource{Version: "v1",Resource: "pods"}
unstructuredList, err := dynamicClient.Resource(gvr).Namespace("whalebase").List(context.TODO(), metav1.ListOptions{Limit: 500})
if err != nil {
panic(err.Error())
}
podList := &corev1.PodList{}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructuredList.UnstructuredContent(),podList)
if err != nil {
panic(err.Error())
}
for _, d := range podList.Items {
fmt.Printf("namespace:%v \t name:%v \t status:%+v\n", d.Namespace, d.Name, d.Status.Phase)
}
}
dynamicClient.Resource(gvr) 函数用于设置请求的资源组、资源版本、资源名称。Namespace 函数用于设置请求的命名空间。List 函数用于获取 pod 列表。得到的pod列表为 unstructured.UnstructuredList 指针类型,然后通过 runtime.DefaultUnstructuredConverter 函数将 unstructured.UnstructuredList 转换成 PodList 类型。
7、DiscoveryClient客户端
DiscoveryClient 是发现客户端,它主要用于发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息,开发者在开发过程中很难记住所有的信息,此时可以通过 DiscoveryClient 查看所支持的资源组、资源版本、资源信息。
kubectl api-versions 和 api-resources 命令输出也是通过 DiscoveryClient 实现的。另外, DiscoveryClient 同样在 RESTClient 的基础上进行了封装。
DiscoveryClient 除了可以发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息,还可以将这些信息存储到本地,用于本地缓存(Cache),以减轻对 Kubernetes API Server 访问的压力。在运行 Kubernetes 组件的机器删,缓存信息默认存储于~/.kube/cache 和 ~/.kube/http-cache 下。
类似于kubectl命令,通过 DiscoveryClient 列出 Kubernetes API Server 所支持的资源组、资源版本、资源信息,代码如下:
package main
import (
"flag"
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
"path/filepath"
)
func main() {
var kubeconfig *string
if home := homedir.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()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
if err != nil {
panic(err.Error())
}
_, APIResourceList, err := discoveryClient.ServerGroupsAndResources()
if err != nil {
panic(err.Error())
}
for _, list := range APIResourceList{
gv, err := schema.ParseGroupVersion(list.GroupVersion)
if err != nil {
panic(err.Error())
}
for _, resource := range list.APIResources {
fmt.Printf("name: %v, group: %v, version: %v\n", resource.Name, gv.Group, gv.Version)
}
}
}
运行以上代码,列出 Kubernetes API Server 所支持的资源组、资源版本、资源信息。首先加载 kubeconfig 配置信息,discovery.NewDiscoveryClientForConfig 通过 kubeconfig 配置信息实例化 discoveryclient 对象,该对象是用于发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息的客户端。
discoveryClient.ServerGroupsAndResources 函数会返回 Kubernetes API Server 所支持的 资源组、资源版本、资源信息(即APIResourceList),通过遍历 APIResourceList 输出信息。