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 main
import (
"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)
}
// 创建 RESTClient
restClient, 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 main
import (
"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)
}
// 创建 Clientset
clientset, 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 main
import (
"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)
}
// 创建 DynamicClient
dynamicClient, err := dynamic.NewForConfig(config)
if err != nil {
panic(err)
}
// 定义自定义资源的 GVR
gvr := 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 main
import (
"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)
}
// 创建 DiscoveryClient
discoveryClient, 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 main
import (
"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)
}
// 创建 Clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
// 创建 InformerFactory
informerFactory := informers.NewSharedInformerFactoryWithOptions(clientset, time.Second*30, informers.WithNamespace("default"))
// 获取 Pod Informer
podInformer := 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")
},
})
// 启动 Informer
stopCh := 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
。