Kubernetes client-go 客戶端類型與初始化指南
在 Kubernetes 的 client-go
庫中,存在多種客戶端用于與 API 服務器交互。以下介紹主要客戶端類型,包括用途、初始化方式及 Demo。
1. RESTClient
用途
RESTClient
是底層 REST 客戶端,直接與 Kubernetes API 服務器的 HTTP 端點交互,適合需要自定義請求的場景。
初始化方式
通過 rest.Config
配置初始化,依賴 k8s.io/client-go/rest
包。
Demo
獲取 default
命名空間中的 Pod 列表。
package mainimport ("context""fmt""k8s.io/client-go/rest""k8s.io/client-go/tools/clientcmd"
)func main() {// 加載 kubeconfig 文件kubeconfig := "/path/to/kubeconfig"config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)if err != nil {panic(err)}// 創建 RESTClientrestClient, err := rest.RESTClientFor(config)if err != nil {panic(err)}// 獲取 Pod 列表result := restClient.Get().AbsPath("/api/v1/namespaces/default/pods").Do(context.TODO())if result.Error() != nil {panic(result.Error())}// 輸出原始響應data, err := result.Raw()if err != nil {panic(err)}fmt.Printf("Raw Pod list: %s\n", string(data))
}
說明
RESTClient
直接操作 HTTP 端點,返回原始 JSON 數據。- 適合需要低級控制的場景,但解析響應需自行處理。
2. Clientset
用途
Clientset
是一個高級客戶端,包含所有 Kubernetes 核心資源(如 Pod、Service、Deployment 等)的類型化方法,適合大多數 CRUD 操作。
初始化方式
通過 rest.Config
初始化,依賴 k8s.io/client-go/kubernetes
包。
Demo
列出 default
命名空間中的所有 Pod。
package mainimport ("context""fmt"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/clientcmd"
)func main() {// 加載 kubeconfig 文件kubeconfig := "/path/to/kubeconfig"config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)if err != nil {panic(err)}// 創建 Clientsetclientset, err := kubernetes.NewForConfig(config)if err != nil {panic(err)}// 獲取 Pod 列表pods, err := clientset.CoreV1().Pods("default").List(context.TODO(), metav1.ListOptions{})if err != nil {panic(err)}// 輸出 Pod 名稱for _, pod := range pods.Items {fmt.Printf("Pod: %s\n", pod.Name)}
}
說明
Clientset
提供類型化的方法,操作直觀,適合核心資源管理。- 自動解析響應為 Go 結構體,無需手動處理 JSON。
3. Dynamic Client
用途
DynamicClient
用于處理任意 Kubernetes 資源(包括自定義資源 CRD),不依賴類型化的 Go 結構體,適合動態或未知類型的資源。
初始化方式
通過 rest.Config
初始化,依賴 k8s.io/client-go/dynamic
包。
Demo
列出 default
命名空間中的自定義資源 myresources.example.com
。
package mainimport ("context""fmt"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/runtime/schema""k8s.io/client-go/dynamic""k8s.io/client-go/tools/clientcmd"
)func main() {// 加載 kubeconfig 文件kubeconfig := "/path/to/kubeconfig"config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)if err != nil {panic(err)}// 創建 DynamicClientdynamicClient, err := dynamic.NewForConfig(config)if err != nil {panic(err)}// 定義自定義資源的 GVRgvr := schema.GroupVersionResource{Group: "example.com", Version: "v1", Resource: "myresources"}// 獲取自定義資源列表list, err := dynamicClient.Resource(gvr).Namespace("default").List(context.TODO(), metav1.ListOptions{})if err != nil {panic(err)}// 輸出資源名稱for _, item := range list.Items {fmt.Printf("Custom Resource: %s\n", item.GetName())}
}
說明
DynamicClient
使用unstructured.Unstructured
處理資源,適合 CRD 或動態場景。- 需要明確指定
GroupVersionResource
(GVR)。
4. Discovery Client
用途
DiscoveryClient
用于查詢 Kubernetes API 服務器支持的資源和版本(如 API 組、資源類型),適合動態發現集群的 API 能力。
初始化方式
通過 rest.Config
初始化,依賴 k8s.io/client-go/discovery
包。
Demo
列出集群支持的所有 API 資源。
package mainimport ("fmt""k8s.io/client-go/discovery""k8s.io/client-go/tools/clientcmd"
)func main() {// 加載 kubeconfig 文件kubeconfig := "/path/to/kubeconfig"config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)if err != nil {panic(err)}// 創建 DiscoveryClientdiscoveryClient, err := discovery.NewDiscoveryClientForConfig(config)if err != nil {panic(err)}// 獲取所有 API 資源apiResources, err := discoveryClient.ServerPreferredResources()if err != nil {panic(err)}// 輸出資源信息for _, apiGroup := range apiResources {for _, resource := range apiGroup.APIResources {fmt.Printf("Resource: %s, Group: %s, Version: %s\n", resource.Name, apiGroup.GroupVersion, resource.Kind)}}
}
說明
DiscoveryClient
不直接操作資源,僅查詢元信息。- 常用于版本兼容性檢查或 CRD 發現。
5. Informer 和 Controller
用途
Informer
和 Controller
用于監聽和處理 Kubernetes 資源變化,基于緩存機制,適合控制器或 Operator 開發。
初始化方式
通過 k8s.io/client-go/informers
和 k8s.io/client-go/tools/cache
包初始化。
Demo
監聽 default
命名空間中 Pod 的變化事件。
package mainimport ("fmt""time""k8s.io/client-go/informers""k8s.io/client-go/kubernetes""k8s.io/client-go/tools/cache""k8s.io/client-go/tools/clientcmd"
)func main() {// 加載 kubeconfig 文件kubeconfig := "/path/to/kubeconfig"config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)if err != nil {panic(err)}// 創建 Clientsetclientset, err := kubernetes.NewForConfig(config)if err != nil {panic(err)}// 創建 InformerFactoryinformerFactory := informers.NewSharedInformerFactoryWithOptions(clientset, time.Second*30, informers.WithNamespace("default"))// 獲取 Pod InformerpodInformer := informerFactory.Core().V1().Pods().Informer()// 添加事件處理podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{AddFunc: func(obj interface{}) {fmt.Println("Pod added")},UpdateFunc: func(oldObj, newObj interface{}) {fmt.Println("Pod updated")},DeleteFunc: func(obj interface{}) {fmt.Println("Pod deleted")},})// 啟動 InformerstopCh := make(chan struct{})defer close(stopCh)informerFactory.Start(stopCh)informerFactory.WaitForCacheSync(stopCh)// 保持運行<-stopCh
}
說明
Informer
提供高效的資源緩存和事件通知。- 適合控制器開發,需結合工作隊列處理事件。
配置來源
所有客戶端的初始化依賴 rest.Config
,可通過以下方式生成:
- Kubeconfig 文件:通過
clientcmd.BuildConfigFromFlags
加載(集群外)。 - In-Cluster 配置:通過
rest.InClusterConfig()
獲取(集群內)。 - 手動配置:直接構造
rest.Config
。
In-Cluster 示例
config, err := rest.InClusterConfig()
if err != nil {panic(err)
}
總結
客戶端類型 | 用途 | 初始化包 | Demo 示例 |
---|---|---|---|
RESTClient | 低級 REST API 訪問 | k8s.io/client-go/rest | 獲取 Pod 列表(原始 JSON) |
Clientset | 類型化核心資源操作 | k8s.io/client-go/kubernetes | 列出 Pod 名稱 |
Dynamic Client | 動態資源操作(包括 CRD) | k8s.io/client-go/dynamic | 列出自定義資源 |
Discovery Client | 查詢 API 資源和版本 | k8s.io/client-go/discovery | 列出所有 API 資源 |
Informer | 資源監聽和控制器開發 | k8s.io/client-go/informers | 監聽 Pod 變化事件 |
選擇建議
- 簡單 CRUD:
Clientset
。 - 自定義資源或動態操作:
DynamicClient
。 - 控制器開發:
Informer
。 - API 發現:
DiscoveryClient
。 - 低級訪問:
RESTClient
。