k8s.io/client-go的代碼目錄:
rest
|
提供RESTClient客戶端
|
restmapper
|
???還沒看
|
kubernetes
|
提供ClientSet客戶端
|
dynamic
|
提供DynamicClient客戶端
|
discovery
|
提供DiscoveryClient客戶端
|
scale
|
提供ScaleClient客戶端
|
tools
|
提供常用工具,如SharedInformer、Reflector、DealtFIFO、Indexer、events、leaderelection、clientcmd
|
informers
|
每種資源的informer實現
|
listers
|
為每種資源提供Lister功能
|
plugin/pkg/client/auth
|
提供OpenStack、GCP、Azure等雲服務商授權插件
|
transport
|
提供安全的TCP連接,支持Http Stream
|
util
|
提供常用方法,如WorkQueue、Certificate證書管理
|
pkg
|
???還沒看
|
metadata
|
???還沒看
|
examples
|
client-go的使用用例
|
client-go支持5種客戶端對象與apiserver交互的方式,它們都是通過kubeconfig配置信息連接到指定的apiserver。
首先都要讀取kubeconfig文件並實例化config對象:
config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config") //第一個參數是apiserver地址,可省略
讀取時是調用tools/clientcmd/api/loader.go中的Load函數讀取配置文件。
不管是根據路徑還是環境變量讀取,最后都是LoadFromFile函數讀取數據並把讀取到的數據反序列化到Config對象中
-
RESTClient
RESTClient是最基礎的客戶端,其它客戶端都是基於它實現的。RESTClient對HTTP Request(Go語言標准庫net/http)進行了封裝,實現了RESTful風格的API。
使用時需要指定Group、Version等信息以生成restClient對象:
config.APIPath= "api" //設置請求的HTTP路徑 config.GroupVersion = &corev1.SchemeGroupVersion //設置請求的資源版本和資源組 config.NegotiatedSerializer = scheme.Codecs //設置config.NegotiatedSerializer數據的編解碼器 restClient, err :=rest.RESTClientFor(config) //通過config對象實例化restClient對象
用法:
result := &corev1.PodList{} err = restClient.Get(). Namespace("cns-test"). Resource("pods"). VersionedParams(&metav1.ListOptions{Limit:500}, scheme.ParameterCodec). Do(context.TODO()). Into(result)
metav1.ListOptions結構體,用於存放list操作時的參數,如Limit表示最多檢索多少條信息;同理也有metav1.GetOptions等
通過Do函數執行該請求,會調用rest/request.go的request函數,由r.URL.String生成實際請求的Restful URL
result是corev1.PodList結構體,用於存放結果。result.Items是[]Pod切片,可以遍歷讀取:
for _, d := range result.Items{ //讀取d.Namespace、d.Name、d.Status.Phase等即可 }
-
ClientSet
ClientSet在RESTClient的基礎上封裝了對Resource和Version的管理方法。每一個Resource可以理解為一個客戶端,而ClientSet則是多個客戶端的集合,每一個Resource和Version都以函數的方式暴露給開發者。
生成clientset對象:
clientset, err := kubernetes.NewForConfig(config)
List所有Pod列表:
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
請求core核心資源組的v1資源版本的Pod資源對象,其內部設置了APIPath請求的HTTP路徑、GroupVersion請求的資源組、資源版本、NegotiatedSerializer數據的編解碼器
Get一個Pod:
namespace := "xxxx" pod := "xxxx" _, 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) }
ClientSet內部的數據都是結構化數據(即已知數據結構),已經預先實現每種Resource和Version的操作,因此只能夠處理Kubernetes內置資源(即Client集合內的資源),要訪問CRD需要通過client-gen代碼生成器自動生成CRD操作相關的接口。
-
DynamicClient
DynamicClient是一種動態客戶端,它內部實現了Unstructured,用於處理非結構化數據結構(即無法提前預知數據結構)。它同樣封裝了RESTClient,同樣提供了Create、Update、Delete、Get、List、Watch、Patch等方法。因此可以對任意Kubernetes資源進行RESTful操作,包括CRD自定義資源。
生成dynamicClient對象:
dynamicClient, err := dynamic.newForConfig(config)
處理過程將Resource(內置資源或自定義資源)轉換成Unstructured結構類型(通過map[string]interface{}轉換):
gvr := schema.GroupVersionResource{Version:"v1",Resource:"pods"} unstructObj, err := dynamicClient.Resource(gvr).Namespace(corev1.NamespaceDefault).List(context.TODO(),metav1.ListOptions{Limit:500})
FromUnstrucured函數將unstructured.UnstructuredList轉換成PodList類型:
PodList := &corev1.PodList{} err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.UnstructuredContent(),PodList)
注意:DynamicClient不是類型安全的,因此在訪問CRD自定義資源時需要特別注意。例如,在操作指針不當的情況下可能會導致程序崩潰。
-
DiscoveryClient
DiscoveryClient發現客戶端,用於發現kube-apiserver所支持的資源組、資源版本、資源信息(即Group、Versions、Resources)。
通過RESTClient分別請求/api和/apis接口,從而獲取Kubernetes API Server所支持的資源組、資源版本、資源信息
kubectl api-resources命令使用的就是DiscoveryClient
生成discoveryClient對象:
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) ServerGroupsAndResources返回APIResourceList(TypeMeta、GroupVersion、[]APIResource) _, APIResourceList, err := discoveryClient.ServerGroupsAndResources()
遍歷APIResourceList獲得資源信息:
for _, list := range APIResourceList{ gv, err := schema.ParseGroupVersion(list.GroupVersion) //把形如group/version的字符串轉換成結構體 if err != nil{ panic(err) } for _, resource := range list.APIResources{ fmt.Println(resource.Name, ",", gv.Group, ",", gv.Version) } }
除了可以發現Kubernetes API Server所支持的資源組、資源版本、資源信息,還可以將這些信息存儲到本地,用於本地緩存(Cache),以減輕對Kubernetes API Server訪問的壓力。
在運行Kubernetes組件的機器上,緩存信息默認存儲於~/.kube/cache和~/.kube/http-cache下。
-
ScaleClient
用於擴縮容Deployment、ReplicaSet、Replication Controller等資源對象