client-go 支持4种 Client 客户端对象与 Kubernetes API Server 进行交互

准备开始

你必须拥有一个可以访问的 Kubernetes 集群。
你必须拥有对 Kubernetes 集群一定的了解。

一、client-go 是什么?

client-go 是访问 Kubernetes 集群的客户端库。编程语言是 golang。
client-go github 地址:点击这里
官方支持的各种编程语言 Kubernetes 客户端库:点击这里
client-go 源码目录结构说明如下所示:

~/go/src/github.com/kubernetes $  tree vendor/k8s.io/client-go/ -L 1
vendor/k8s.io/client-go/
├── discovery
├── dynamic
├── informers
├── kubernetes
├── listers
├── plugin
├── rest
├── scale
├── tools
├── transport
└── util
  • discovery:提供 DisconveryClient 发现客户端。
  • dynamic:提供 DynamicClient 发现客户端。
  • informers:每种 Kubernetes 资源的 Informer 实现。
  • kubernetes:提供 ClientSet 客户端。
  • listers:为每一个 Kubernetes 资源提供 Lister 功能,提供只读缓存数据。
  • plugin:提供云服务商授权插件。
  • rest:提供 RESTClient 发现客户端。
  • scale:提供 ScaleClient 发现客户端。
  • tools:提供常用工具。
  • transport:提供安全的 TCP 连接。
  • util:提供常用方法。

二、Client 客户端对象

client-go 支持4种 Client 客户端对象与 Kubernetes API Server 进行交互,Client 交互对象如下所示:
client客户端对象
由上图可以看出,RESTClient 是最基础的客户端。ClientSet、DynamicClient、DiscoveryClient 客户端都是基于 RESTClient 进行实现的。

1. RESTClient 客户端

RESTClient 对 HTTP Request 进行了封装,实现了 RESTful 风格的 API。
以 Pods 资源为例,通过 RESTClient 查询所有运行的 Pod 资源对象。
代码示例如下:

package main

import (
	"context"
	"fmt"
	"os"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 连接本地 k8s 集群,kubeconfig 文件在 /root/.kube/config 目录下
	//config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
	// 连接远端 k8s 集群,kubeconfig 文件在本地项目目录下
	projectDir, _ := os.Getwd()
	config, err := clientcmd.BuildConfigFromFlags("", projectDir+"/kubeconfig")

	if err != nil {
		panic(err)
	}

	config.APIPath = "api"
	config.GroupVersion = &corev1.SchemeGroupVersion
	config.NegotiatedSerializer = scheme.Codecs

	restClient, err := rest.RESTClientFor(config)
	if err != nil {
		panic(err)
	}

	result := &corev1.PodList{}
	err = restClient.Get().
		Namespace("default").
		Resource("pods").
		VersionedParams(&metav1.ListOptions{Limit: 500}, scheme.ParameterCodec).
		Do(context.TODO()).
		Into(result)
	if err != nil {
		panic(err)
	}

	for _, item := range result.Items {
		fmt.Printf("namespace: %v\t name: %v\t status: %+v\n", item.Namespace, item.Name, item.Status.Phase)
	}
}

go.mod 如下

require (
	k8s.io/api v0.25.4
	k8s.io/apimachinery v0.25.4
	k8s.io/client-go v0.25.4
)

执行:go mod tidy,更新第三方依赖

运行以上代码,列出default命名空间下的所有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对象中。最终格式化输出结果。

2. ClientSet 客户端(最常用)

ClientSet 客户端对象是开发者进行二次开发时最常用的客户端对象。

ClientSet 客户端对象是在 RESTClient 客户端对象的基础上封装了对 Resource 和 Version 的管理方法。每一个Resource可以理解为一个客户端,而ClientSet则是多个客户端的集合,每一个 Resource和Version都以函数的方式暴露给开发者。

ClientSet 客户端对象仅能访问 Kubernetes 内置资源,不能直接访问 CRD 资源。如果需要访问 CRD 资源,请使用 DynamicClient 客户端对象。

注:ClientSet 的命名,Client -> 客户端,Set -> 集合,ClientSet -> 多个客户端的集合。(个人理解)

以 Pods 资源为例,通过 ClientSet 查询所有运行的 Pod 资源对象。
代码示例如下:

package main

import (
	"context"
	"fmt"
	"os"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 连接本地 k8s 集群,kubeconfig 文件在 /root/.kube/config 目录下
	//config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
	// 连接远端 k8s 集群,kubeconfig 文件在本地项目目录下
	projectDir, _ := os.Getwd()
	config, err := clientcmd.BuildConfigFromFlags("", projectDir+"/kubeconfig")

	if err != nil {
		panic(err)
	}

	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}

	result, err := clientset.CoreV1().Pods("default").List(context.TODO(), metav1.ListOptions{Limit: 500})
	if err != nil {
		panic(err)
	}

	for _, item := range result.Items {
		fmt.Printf("namespace: %v\t name: %v\t status: %+v\n", item.Namespace, item.Name, item.Status.Phase)
	}
}

运行以上代码,列出default命名空间下的所有Pod 资源对象的相关信息。首先加载kubeconfig配置信息, kubernetes.NewForConfig通过kubeconfig配置信息实例化clientset对象,该对象用于管理所有Resource的客户端。

clientset.CoreV1().Pods函数表示请求core核心资源组的v1资源版本下的Pod资源对象,其内部设置了APIPath请求的HTTP路径,GroupVersion请求的资源组、资源版本,NegotiatedSerializer数据的编解码器。

其中,Pods函数是一个资源接口对象,用于Pod资源对象的管理,例如,对Pod资源执行Create、Update、Delete、Get、List、Watch、Patch等操作,这些操作实际上是对RESTClient进行了封装,可以设置选项(如Limit、TimeoutSeconds等)。podClient.List函数通过RESTClient获得Pod列表。

通过clientcmd.BuildConfigFromFlags 方法来构造restConfig,通过restConfig构造clientset,进而访问Kubernetes集群。

BuildConfigFromFlags 源码,点击这里

// BuildConfigFromFlags is a helper function that builds configs from a master
// url or a kubeconfig filepath. These are passed in as command line flags for cluster
// components. Warnings should reflect this usage. If neither masterUrl or kubeconfigPath
// are passed in we fallback to inClusterConfig. If inClusterConfig fails, we fallback
// to the default config.
func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config, error) {
	if kubeconfigPath == "" && masterUrl == "" {
		klog.Warning("Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.")
		kubeconfig, err := restclient.InClusterConfig()
		if err == nil {
			return kubeconfig, nil
		}
		klog.Warning("error creating inClusterConfig, falling back to default config: ", err)
	}
	return NewNonInteractiveDeferredLoadingClientConfig(
		&ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
		&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig()
}

BuildConfigFromFlags 是一个辅助函数,它从主 url 或 kubeconfig 文件路径构建配置。这些作为集群组件的命令行标志传入。警告应该思考这种用法。如果 masterUrl 或 kubeconfigPath 都没有传入,我们将回退到 inClusterConfig。如果 inClusterConfig 失败,我们将回退到默认配置。

2.1 通过 kubeconfig 字节构造 ClientSet 客户端对象

针对一些场景,只有 kubeconfig 字节(或字符串),没有 /root/.kube/config 文件,该如何构造 ClientSet 客户端对象,进而访问 Kubernetes API Server 呢?

答:通过 clientcmd.RESTConfigFromKubeConfig 方法来构造 restConfig,通过restConfig构造clientset,进而访问Kubernetes集群。

RESTConfigFromKubeConfig 源码,点击这里

// RESTConfigFromKubeConfig is a convenience method to give back a restconfig from your kubeconfig bytes.
// For programmatic access, this is what you want 80% of the time
func RESTConfigFromKubeConfig(configBytes []byte) (*restclient.Config, error) {
	clientConfig, err := NewClientConfigFromBytes(configBytes)
	if err != nil {
		return nil, err
	}
	return clientConfig.ClientConfig()
}

RESTConfigFromKubeConfig 是一种从 kubeconfig 字节返回 restconfig 的便捷方法。对于程序化访问,这是您 80% 的时间想要的。

通过 kubeconfig 字符串或 kubeconfig 文件路径构造 restConfig,进而构造 ClientSet 连接 Kubernetes 集群,获取集群中 namespace 列表数据。
代码示例如下:

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

// 全局变量,记录 kubeConfig,替换为你自己集群的 kubeconfig
var kubeConfig string = `apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM2VENDQWRHZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQ0FYRFRJeU1EWXdPVEF5TXpjeU5sb1lEekl4TWpJd05URTJNREl6TnpJMldqQVZNUk13RVFZRApWUVFERXdwcmRXSmxjbTVsZEdWek1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCnZrYmJyQkc1dkpSZ1FZRmRONzVQcURZcGxVUjNoNUlYdExoTXR5RUVIclk1MHNjSEpnNnZ4WEdTM0lwcFZzSUEKRGVRS2lVWWsyOWtQMmhtMDBmSWZVTHJqYkRGWnl3aDNkV29aMlp2ZE8vOTNJbityTG42ZitXZzl1a3VKV0d6NwpacFBRdVZKZVNESGZWYjM4U2FVeDV2S0JobVV3SUc5RGJyc3N4OVRYNnFRQmFGYm0yUEt4SlZ0ZERjU3ZpalZQCjlXSXRWQVRSMFk5UVhtbEdSRXVaekhQNDBJN0MvYlpiOW5zM3hWR1dwMW9QQ1dCaEtxY0pLa2tPbDBOUWM5a20KU1RKekllNU44QnZtNmtDZzFDRi81dmxpNkVtVHVZMkQwTlc1UjhzS3JhZGNtT1VhaGlwbFRvUjllSTJVSk4wYgptOGlnQ2R4NFhDeUlSSUFjaG1TdGJ3SURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WURWUjBUCkFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVUzOXpoSzVHcW5SV284cGJxUW96T0pmb1pqQjh3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFLeGYrSUd4KzFQdnB4N0p4dXd0bW0rZzE1NVB5ajBXdDE2WVZVWTJqdUFwSjIwZwp4L1JtRjNqck1Gc1hXMm8xczRNZ1hJd2ZxU09pdUFKUHNXSExLbExZelRWRUFWSHhzK0J2bWhDRU5VTEx0VlZICk8vVEJXTGVIc2lvM2hkaWNjbThZZ05MQ1hnNjhMRmpWV2FLN0NWRDlzaTAvalBhOXZ2eTBIcGQvS3NtSnBwZFgKWEdmWFlRdmxENFhqcjV1ejkvNXR3VXRGS0M4U2U5L09OZ1hLS1h0ek9PSXgrUUtmMGlQUk1PMGpJTTlKZGtqMAplNmlXYWZGVDNwVWNKeVFncEIzMFdxQ3lQUUhJSU5IWk1wSDRzZzhTeXd2YVB6OTRFeklSdEFBbFdobGZReGVtCkVvc0NCZGVQK2UxUnhTbVpJSUYxd3p5ald4OVIxWW53NzhJazE3az0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
    server: https://10.27.141.58:8445
  name: cluster.local
contexts:
- context:
    cluster: cluster.local
    user: kubernetes-admin
  name: kubernetes-admin@cluster.local
current-context: kubernetes-admin@cluster.local
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURGVENDQWYyZ0F3SUJBZ0lJYitxalJHUDVxeDh3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWdGdzB5TWpBMk1Ea3dNak0zTWpaYUdBOHlNVEl5TURVeE5qQXlNemN5T0ZvdwpOREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhHVEFYQmdOVkJBTVRFR3QxWW1WeWJtVjBaWE10CllXUnRhVzR3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRE5TSWlEZGRrd3IrRC8KKzkwSDIvdkxYYVhkVUt6aWpaeGM5SXU1bmd1cTIwY2NMZDFKNzBWaDk1RWFCK1ZYbEdaTll2dmwydVRTbXM1SApBb0t0allWOGh5OW1TWHlDR2p3Skd4TGluc0JzODhScDYvOFF5b2xMTWphRFpOZllmdFd6VlhJQW1hSVhRWWw0CjdtODlaUkdPaUlVUVQyVytRd1YxZUkrakRxejlWa001ckpFVFdiY0tJdW1SeWdZSXJWeC9uZEdQRXVoeEhDaEoKSzFjb1ArSi9JeFAxdlBQQmlkaCt0NDViQVNnUmpGRnFiTHNSTWRSemhCaGxhd2FqWjdMVlFiSWZkUERpaVhBYgpQZTBpcHNJMjFjRWxMUmx3cmFBK0swZDZyVzR6Q2tvcGJYVDBscXRZM2hRbGhMdzh5Z3NENTVZWW1BUHB5b0N5CkRWcFovaTNUQWdNQkFBR2pTREJHTUE0R0ExVWREd0VCL3dRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQWZCZ05WSFNNRUdEQVdnQlRmM09FcmthcWRGYWp5bHVwQ2pNNGwraG1NSHpBTkJna3Foa2lHOXcwQgpBUXNGQUFPQ0FRRUFhamJnNXpqc1NrQU9vZlBaRFVxc2o4djRCU0R1c3RBYjJpckYwUUJzOVFhaWFpNm9LOUg0Ci95WnpoU29oRStZZWdWY1NHV0EwRlpySkJ1b3FITFJ4ZjRmeXlVRFBtRVZacnZLcXk1WTZWL2pGK3AzS3JjaFkKZTJTSkNrL3dqeE9QZ2tmRUZtaXRwU1BqekFkSmtJMFhYSkhKYlhLTm9WSllHY0JzaExJSVl3TzcrQmY0NFpURwpSYzdEQmRCaXl5U3pBMkpwL01Dc1NLd0xGdGNlUnpVYWJmczc2dVdTaHlYbG9GM3EvdmdZTHBKL2trdG5QWmlKClFJQWhLZjhOUmdaQWxyQTlCOHp3YkJESWhHanVEMU9yaVBOVlJzRmZBeHJvbkpXY3VWcE9MQVJDWkVVNmFjZUoKOXh3YVUwRzVzV003UVY0dHpQTlFvanlMTmJ3dzRGQnZWUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBelVpSWczWFpNSy9nLy92ZEI5djd5MTJsM1ZDczRvMmNYUFNMdVo0THF0dEhIQzNkClNlOUZZZmVSR2dmbFY1Um1UV0w3NWRyazBwck9Sd0tDclkyRmZJY3Zaa2w4Z2hvOENSc1M0cDdBYlBQRWFldi8KRU1xSlN6STJnMlRYMkg3VnMxVnlBSm1pRjBHSmVPNXZQV1VSam9pRkVFOWx2a01GZFhpUG93NnMvVlpET2F5UgpFMW0zQ2lMcGtjb0dDSzFjZjUzUmp4TG9jUndvU1N0WEtEL2lmeU1UOWJ6endZbllmcmVPV3dFb0VZeFJhbXk3CkVUSFVjNFFZWldzR28yZXkxVUd5SDNUdzRvbHdHejN0SXFiQ050WEJKUzBaY0syZ1BpdEhlcTF1TXdwS0tXMTAKOUphcldONFVKWVM4UE1vTEErZVdHSmdENmNxQXNnMWFXZjR0MHdJREFRQUJBb0lCQUhnUDVoZk5BendnZ1ozMQo5cTQwRVM0K0ZWWTlhd0FPQnRldkIxR0dpQmhqcTFGbDJiajJRa1FzQVNlU1dxWkFXeDBEdVlRVDVDVHcrWmc2CmRhZC8wQVNuSkNmVTd3ZEF4TUFtbjRML2lsZXVzcitva1VPRzBZbXpVb0xDcGlNdSsxbXByY1dBRlhjNGsyaXgKTzBwVEpGT1NzUkI2LzJ5cDBqV0VUNjMwVldUTTFLVllaa1BUaGwyczJGbURGZzVxanNpenpFaXNCbXlXTnNVcQpsTUxOT0tIMGVwMi9iUUJJQ2wwSFRvNEJ1cWUwYjhaV1JvUTF0eGhjRzBhcFY4cWxqRmpZMCsxRmlHVm43dXZ3ClFXY1NCQ0ZOd3VldjA2MUhneDVrSXgyemZxMEZKUFl6SU0vMlZxczlvTkowQTZjK2hlQWdDbm5aSVZkUjhEb2EKdmI2QjdHRUNnWUVBM0liZ3NNcDcydGJWbGxYUzV2STJHbTF4d2ZFL3ozTWJ1Qmhjd3R4c2FrWGhtblo5Z245aAo3ZGdVUGgxY25Dd3ZYZGZQbEhlSytNRE1peFVKcnRCZDVyN3FFYVdIR0w0NGU3KzlPWTArVk03UFp0OEdwRy9iCjR4Rlp0NTh0bnZEMlZIa3lGbUtYOCtqWlpQQWF4TDJzZXpDUXJvN01lYnllam5aOVdXcHl3VXNDZ1lFQTdrM3cKVzhuTDRTSjljSGpKWDg4ZVRSOXJScjJTNFVLRnVicVZHZ1lxZFdraXVLMXBaTloxbGxTQTlkUEVrdUxEc0ZvSAp4NHN2RWpYWFlzTy9GWklCRGYzUFN3Mmc2MnlRMUNxUTBMVTNhUFo0ek1RenFKK04xdFg0ejJNOFozcVZDUDZnCnAycHkxS2RVbWw3QUdLNldacnVrdkZPdmpDWi9aUXFxdTc5NCtKa0NnWUVBeGVlTk1Wc2x0NGpnK1I5Z083M1cKYS9VWUI5SzNUemFnQTZCcGJyNWQxU21OZ3c4Zko4T2xZTXR2cnlhdWU4RHphU1pKdFpWcWRENmgwWmM1cjFaegpUcWE2Yk1lOTY2aWFEQVJRanB1QStwNzJaZjEwZXBHZ0piRG1jUEU3QWM2QlllRzUzM2p2b1Fhd1FmTndNbXQ5CnBMZzZ2MHlMbUJ4N3RxSURjQUVscHUwQ2dZRUFoejl1dWZsMm44amVYcFgrM0VTRmt3blE3YTRzRFhLZXlNRlAKWEJ6QnZpODBTSklLN2ZNVmU0TnNTWml0eVJ1d0tvZCtRTThLb1JBenROY1p2UmxIUmZTVjBLZmtlNWo3UFo4RwozNXpwM01WOTIrRkMzR0hwczFOdlNleXRYS0Zpc2w4cE9Mc2VmdmlVK0tQcjdGWXlBQTVoT1kxWlpYWjMrUldyCnZyQzE3SWtDZ1lCRjVuekhtbHd6K0tFeG44QTVKbnY1TjlKOUpxVW1GRlppRkF4aytmdzliNHdVR1FDaUxWYU8KYzhobE9oYWxvcVhuQ3R0WStxTVNFbEpWQ2ZKcVk3NGhuM3FacStLU3lXNHlKbUhtUW5kRG8wSy9qNlFhbjMySQpiMkl6VHhnbm5DQmRWMkRsUFE3Sm1IazlMN29GVWVSanZ1RS81OFhyOS9JeVI1bjZRZkhqdnc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
`

// RestConfigByKubeconfigStr 通过 kubeconfig 构造 rest.Config
func RestConfigByKubeconfigStr() (*rest.Config, error) {
	// get restConfig
	restConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kubeConfig))
	if err != nil {
		fmt.Printf("get rest.KubeConfig by kubeconfig error: %v", err)
	}

	return restConfig, err
}

// RestConfigByKubeconfigPath 通过本地文件路径构造 rest.Config
func RestConfigByKubeconfigPath() (*rest.Config, error) {
	// 你需要在该路径下有 kubeconfig 文件
	kubePath := "./kube.config"
	// get restConfig
	restConfig, err := clientcmd.BuildConfigFromFlags("", kubePath)
	if err != nil {
		fmt.Printf("get rest.KubeConfig by kubeconfigPath error: %v", err)
	}

	return restConfig, err
}

func main() {
	// 通过 kubeconfig 构造 rest.Config
	restConfig, err := RestConfigByKubeconfigStr()
	// 通过本地文件路径构造 rest.Config
	//restConfig, err := RestConfigByKubeconfigPath()
	if err != nil {
		fmt.Printf("get restConfig by KubeConfig error: %v", err)
	}

	// get clientSet
	clientSet, err := kubernetes.NewForConfig(restConfig)
	if err != nil {
		fmt.Printf("get clientSet by rest.KubeConfig error: %v", err)
	}

	// get namespaceList
	namespaceList, err := clientSet.CoreV1().Namespaces().List(context.TODO(), metaV1.ListOptions{})
	if err != nil {
		fmt.Printf("get namespaceList error: %v", err)
	}

	// 将 namespaceList 通过 json 格式化输出
	namespaceListEncode, err := json.Marshal(namespaceList)
	if err != nil {
		fmt.Printf("get namespaceListEncode by json.Marshal error: %v", err)
	}

	var namespaceListBuffer bytes.Buffer
	err = json.Indent(&namespaceListBuffer, namespaceListEncode, "", "    ")
	if err != nil {
		fmt.Printf("get namespaceListBuffer by json.Indent error: %v", err)
	}

	fmt.Printf("namespaceList=%v\n", namespaceListBuffer.String())
}

3. DynamicClient 客户端

DynamicClient 是一种动态客户端,可以对任意 Kubernetes 资源进行 RESTful 操作,包括 CRD 自定义资源。DynamicClient 内部实现了 Unstructured,用于处理非结构化数据结构,这是 DynamicClient 能够处理 CRD 自定义资源的核心。

以 Pods 资源为例,通过 DynamicClient 查询所有运行的 Pod 资源对象。
代码示例如下:

package main

import (
	"context"
	"fmt"
	"os"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 连接本地 k8s 集群,kubeconfig 文件在 /root/.kube/config 目录下
	//config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
	// 连接远端 k8s 集群,kubeconfig 文件在本地项目目录下
	projectDir, _ := os.Getwd()
	config, err := clientcmd.BuildConfigFromFlags("", projectDir+"/kubeconfig")

	if err != nil {
		panic(err)
	}

	dynamicClient, err := dynamic.NewForConfig(config)
	if err != nil {
		panic(err)
	}

	gvr := schema.GroupVersionResource{
		Version:  "v1",
		Resource: "pods",
	}
	unstructObj, err := dynamicClient.Resource(gvr).Namespace("default").List(context.TODO(), metav1.ListOptions{Limit: 500})
	if err != nil {
		panic(err)
	}

	result := &corev1.PodList{}
	err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.UnstructuredContent(), result)
	if err != nil {
		panic(err)
	}

	for _, item := range result.Items {
		fmt.Printf("namespace: %v\t name: %v\t status: %+v\n", item.Namespace, item.Name, item.Status.Phase)
	}
}

运行以上代码,列出default命名空间下的所有Pod资源对象的相关信息。首先加载kubeconfig配置信息, dynamic.NewForConfig通过kubeconfig配置信息实例化dynamicClient对象,该对象用于管理Kubernetes的所有Resource的客户端,例如对Resource执行Create、Update、Delete、Get、List、Watch、Patch等操作。

dynamicClient.Resource(gvr)函数用于设置请求的资源组、资源版本、资源名称。Namespace函数用于设置请求的命名空间。List函数用于获取Pod列表。得到的Pod列表为unstructured.UnstructuredList指针类型, 然后通过 runtime.DefaultUnstructuredConverter.FromUnstructured 函数将unstructured.UnstructuredList转换成PodList类型。

4. DiscoveryClient 客户端

DiscoveryClient 客户端是发现客户端,主要用于发现 Kubernetes API Server 所支持的资源组、资源版本、资源信息。

通过 DiscoveryClient 列出 Kubernetes API Server 所支持的资源组、资源版本、资源信息。
代码示例如下:

package main

import (
	"fmt"
	"os"

	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 连接本地 k8s 集群,kubeconfig 文件在 /root/.kube/config 目录下
	//config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
	// 连接远端 k8s 集群,kubeconfig 文件在本地项目目录下
	projectDir, _ := os.Getwd()
	config, err := clientcmd.BuildConfigFromFlags("", projectDir+"/kubeconfig")

	if err != nil {
		panic(err)
	}

	discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
	if err != nil {
		panic(err)
	}

	_, APIResourceList, err := discoveryClient.ServerGroupsAndResources()
	if err != nil {
		panic(err)
	}

	for _, list := range APIResourceList {
		gv, err := schema.ParseGroupVersion(list.GroupVersion)
		if err != nil {
			panic(err)
		}
		for _, resource := range list.APIResources {
			fmt.Printf("name: %v\t group: %v\t 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输出信息。

总结

本文介绍了 client-go Client 客户端对象与 Kubernetes API Server 交互的 4 种方式,列举了 4 种客户端对象的特点及使用方式,并给出代码示例,方便用户学习参考使用,让用户更好的入手 client-go 二次开发。

参考

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Controller manager(控制器管理器)是Kubernetes控制面的一个基础组件,它是Kubernetes Master节点上的一个二进制程序,主要用于运行一些内置的控制器和用户自定义的控制器,并确保它们根据预期状态执行。Controller manager包含多个控制器,如节点控制器,Replication Controller管理器,Service控制器,证书授权控制器等,每个控制器都是负责一些特定的职责。 Client-go是Kubernetes官方提供的一个Golang编写的客户端库,它可以用于与Kubernetes API Server交互,通过Client-go我们可以直接对Kubernetes进行操作,例如获取集群状态,创建Pod,Service,Deployment等,这使得我们可以通过代码的方式实现各Kubernetes对象的CRUD操作。 Controller manager和Client-go密切相关,Controller manager可以使用Client-go与Kubernetes API Server进行通信,将自定义的控制器注册到Kubernetes API Server中,并通过Client-go获取各个组建的状态,根据状态的变化,Controller manager可以对所管理的资源进行增加,删除,调度等操作。这些操作可以保证其所管理的资源处于当前所期望的状态,并且可以自动处理更新失败的情况。 总之,Controller manager和Client-go是Kubernetes中两个非常重要的组件,Controller manager起到控制资源状态的作用,Client-go作为客户端库可以方便我们对Kubernetes资源进行增加,删除等操作。它们的协同工作有利于更好地管理Kubernetes集群的资源状态,并且可以通过代码自动处理这些操作,使得Kubernetes集群更加健壮和易于管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

k8s-open

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值