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: [email protected]
current-context: [email protected]
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 輸出資訊。