Skip to content

client-go 全景概览

什么是 client-go

client-go 是 Kubernetes 官方的 Go 语言客户端库,是所有 K8s 控制器、Operator、CLI 工具的基础。

client-go
├── Clientset(类型化客户端,最常用)
├── DynamicClient(动态客户端,处理 CRD)
├── RESTClient(底层 HTTP 客户端)
├── Informer(本地缓存 + Watch 机制)
├── WorkQueue(工作队列)
└── LeaderElection(领导者选举)

快速开始

go
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
    config, err := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
    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)
    }

    for _, pod := range pods.Items {
        fmt.Printf("Pod: %s, Status: %s\n", pod.Name, pod.Status.Phase)
    }
}

核心组件

Clientset(类型化客户端)

go
// 获取 Deployment
deploy, err := clientset.AppsV1().Deployments("default").Get(ctx, "my-app", metav1.GetOptions{})

// 创建 Service
svc := &corev1.Service{
    ObjectMeta: metav1.ObjectMeta{Name: "my-svc"},
    Spec: corev1.ServiceSpec{
        Selector: map[string]string{"app": "my-app"},
        Ports: []corev1.ServicePort{{Port: 80, TargetPort: intstr.FromInt(8080)}},
    },
}
_, err = clientset.CoreV1().Services("default").Create(ctx, svc, metav1.CreateOptions{})

// 更新 Deployment 副本数
deploy.Spec.Replicas = pointer.Int32(5)
_, err = clientset.AppsV1().Deployments("default").Update(ctx, deploy, metav1.UpdateOptions{})

// 删除 Pod
err = clientset.CoreV1().Pods("default").Delete(ctx, "my-pod", metav1.DeleteOptions{})

DynamicClient(动态客户端)

go
import "k8s.io/client-go/dynamic"

dynamicClient, err := dynamic.NewForConfig(config)

// GVR(Group/Version/Resource)
gvr := schema.GroupVersionResource{
    Group:    "apps",
    Version:  "v1",
    Resource: "deployments",
}

// 获取 Deployment(返回 unstructured.Unstructured)
obj, err := dynamicClient.Resource(gvr).Namespace("default").Get(ctx, "my-app", metav1.GetOptions{})

// 访问字段
replicas, found, err := unstructured.NestedInt64(obj.Object, "spec", "replicas")

Informer(本地缓存)

go
import (
    "k8s.io/client-go/informers"
    "k8s.io/client-go/tools/cache"
)

// 创建 SharedInformerFactory
factory := informers.NewSharedInformerFactory(clientset, 30*time.Second)

// 获取 Pod Informer
podInformer := factory.Core().V1().Pods().Informer()

// 注册事件处理器
podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc: func(obj interface{}) {
        pod := obj.(*corev1.Pod)
        fmt.Printf("Pod Added: %s\n", pod.Name)
    },
    UpdateFunc: func(oldObj, newObj interface{}) {
        pod := newObj.(*corev1.Pod)
        fmt.Printf("Pod Updated: %s\n", pod.Name)
    },
    DeleteFunc: func(obj interface{}) {
        pod := obj.(*corev1.Pod)
        fmt.Printf("Pod Deleted: %s\n", pod.Name)
    },
})

// 启动 Informer
stopCh := make(chan struct{})
factory.Start(stopCh)
factory.WaitForCacheSync(stopCh)

// 从缓存读取(不访问 API Server)
pod, err := factory.Core().V1().Pods().Lister().Pods("default").Get("my-pod")

项目结构

k8s.io/client-go
├── kubernetes/          # Clientset(类型化客户端)
├── dynamic/             # DynamicClient
├── rest/                # RESTClient
├── tools/
│   ├── cache/           # Informer 缓存
│   ├── clientcmd/       # kubeconfig 加载
│   ├── leaderelection/  # 领导者选举
│   └── record/          # 事件记录
├── util/
│   ├── workqueue/       # 工作队列
│   └── retry/           # 重试机制
└── informers/           # SharedInformerFactory

依赖管理

bash
go get k8s.io/client-go@v0.29.0
go get k8s.io/apimachinery@v0.29.0
go get k8s.io/api@v0.29.0

⚠️ 版本对应关系:client-go v0.29.x 对应 K8s 1.29

本站内容由 褚成志 整理编写,仅供学习参考