client-go 入门

2025-11-05T14:11:02+08:00 | 3分钟阅读 | 更新于 2025-11-05T14:11:02+08:00

@

client-go 简介

client-go 是 Kubernetes 官方提供的 Go 语言客户端库,是与 K8s API Server 交互的标准方式。无论是简单的运维脚本、复杂的控制器(Controller)、Operator,还是自定义的 CLI 工具,底层都大量依赖 client-go。

client-go 的源码仓库为 k8s.io/client-go,通常与 k8s.io/apimachineryk8s.io/api 等包一起使用。

client-go 整体架构

client-go 的核心模块包括:

模块作用
Clientset提供类型化的 REST 客户端,支持各类 K8s 资源的 CRUD
RESTClient底层 REST 调用封装,灵活但使用较繁琐
DynamicClient动态客户端,无需预先知道资源类型,适合处理 CRD
DiscoveryClient发现集群支持的 API 组、版本和资源
Informers基于 List-Watch 的本地缓存机制,高效监听资源变化
Workqueue事件队列,配合 Informer 实现可靠的事件处理
Lister只读本地缓存查询接口,性能高

理解这些模块的关系,是编写高效、稳定 K8s 程序的基础。

使用场景

client-go 常见的使用场景有:

  1. 运维脚本:批量查询、修改、删除资源。
  2. 自定义 CLI 工具:为团队封装内部使用的 kubectl 插件或独立工具。
  3. 控制器与 Operator:监听资源变化并调谐期望状态。
  4. 平台集成:将 K8s 能力集成到 PaaS、CICD 或 AIOps 平台。

Golang 命令行工具开发

使用 Go 开发命令行工具时,常用 cobra 框架。基本结构如下:

package main

import (
    "fmt"
    "github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
    Use:   "myctl",
    Short: "一个自定义的 K8s 运维工具",
}

var listCmd = &cobra.Command{
    Use:   "list",
    Short: "列出 Pod",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("列出所有 Pod...")
    },
}

func main() {
    rootCmd.AddCommand(listCmd)
    if err := rootCmd.Execute(); err != nil {
        panic(err)
    }
}

cobra 支持子命令、参数解析、配置文件读取,是构建 kubectl 插件风格工具的首选。

client-go 深度实战

创建 Clientset

import (
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
    if err != nil {
        panic(err)
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err)
    }
    // 使用 clientset 操作资源
}

调谐改查

操作示例方法
查询clientset.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{})
创建clientset.CoreV1().Pods(ns).Create(ctx, pod, metav1.CreateOptions{})
更新clientset.CoreV1().Pods(ns).Update(ctx, pod, metav1.UpdateOptions{})
删除clientset.CoreV1().Pods(ns).Delete(ctx, name, metav1.DeleteOptions{})

控制器与 Informer

控制器遵循 Kubernetes 的声明式控制循环:

观察(Watch) -> 分析(Diff) -> 执行(Act) -> 重试(Retry)

使用 Informer 监听资源变化,配合 Workqueue 实现异步处理:

informer := factory.Core().V1().Pods().Informer()
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc: func(obj interface{}) {
        key, _ := cache.MetaNamespaceKeyFunc(obj)
        workqueue.Add(key)
    },
    UpdateFunc: func(old, new interface{}) {
        key, _ := cache.MetaNamespaceKeyFunc(new)
        workqueue.Add(key)
    },
    DeleteFunc: func(obj interface{}) {
        key, _ := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
        workqueue.Add(key)
    },
})

选举机制

在高可用控制器部署中,通常需要 Leader Election 保证同一时刻只有一个实例执行 reconcile。client-go 提供了 tools/leaderelection 包,支持基于 Lease 或 ConfigMap/Endpoint 的选主:

lock := &resourcelock.LeaseLock{
    LeaseMeta: metav1.ObjectMeta{Name: "my-controller", Namespace: "default"},
    Client:    clientset.CoordinationV1(),
    LockConfig: resourcelock.ResourceLockConfig{
        Identity: hostname,
    },
}

基于 client-go 的基础设施自动化脚本

借助 client-go,可以将常见运维操作固化为 Go 程序。例如:

  • 批量给指定命名空间添加标签。
  • 定时清理 Evicted 状态的 Pod。
  • 根据注解自动为 Service 创建 Ingress。
  • 导出集群资源配置为 GitOps 仓库。

这类脚本比 Shell 更易于维护、测试和分发,也更容易与 AIOps 平台集成。

总结

client-go 是 Kubernetes 生态的编程入口。掌握 Clientset、Informer、Workqueue、Leader Election 等核心概念,是开发控制器、Operator 和 AIOps 工具的关键。下一篇笔记将结合 AIOps 场景,展示如何使用 client-go 实现智能运维脚本。

About Me

没什么想介绍的,一个很大众的码农…

喜欢代码,车,马,真的是 🐎

讨厌别人让我给自己的代码写注释 最厌烦别人的程序没有写注释

目标

学AI,加油!加油!