你必须拥有一个可以访问的 Kubernetes 集群。
你必须拥有对 Kubernetes 集群一定的了解。
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
client-go 支持4种 Client 客户端对象与 Kubernetes API Server 进行交互,Client 交互对象如下所示:
由上图可以看出,RESTClient 是最基础的客户端。ClientSet、DynamicClient、DiscoveryClient 客户端都是基于 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请求参数。
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 失败,我们将回退到默认配置。
针对一些场景,只有 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: [email protected]
current-context: [email protected]
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())
}
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类型。
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 二次开发。