學習地址: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 輸出信息。