
云原生后端【免费下载链接】client-goGo client for Kubernetes.项目地址https://gitcode.com/gh_mirrors/cl/client-go点击查看免费下载client-go 是 Kubernetes 官方维护的 Go 客户端库本指南以 examples/README.md 为骨架逐一拆解仓库中承载各类使用场景的示例程序认证插件加载、集群内外配置方式、Deployment 资源的增删改查、基于 workqueue 与 informer 的控制器编写、高可用场景下的 Leader Election以及使用 Fake Client 编写单元测试。读完本文你将掌握 client-go 各类典型使用模式的完整代码路径、运行方法与底层原理可直接将这些示例改造为生产级应用。Auth Plugins为客户端启用外部凭据插件client-go 的客户端配置通常从 kubeconfig 文件中加载其中包含服务器地址与凭据信息。对于需要从外部来源获取凭据的场景如云厂商托管集群、OIDC 身份提供方client-go 提供了若干认证插件但这些插件默认不会被加载。要在你的程序中启用这些插件需要在主包main package中通过空导入blank import方式引入。可以一次性加载全部插件import _ k8s.io/client-go/plugin/pkg/client/auth也可以按需加载特定插件import _ k8s.io/client-go/plugin/pkg/client/auth/azure import _ k8s.io/client-go/plugin/pkg/client/auth/gcp import _ k8s.io/client-go/plugin/pkg/client/auth/oidc从仓库源码结构看认证插件统一存放在 plugin/pkg/client/auth 目录下包含azure、gcp、oidc、exec等子目录plugins.go与plugins_providers.go负责插件的注册与提供者管理。之所以采用空导入是因为插件通过包初始化阶段init()向 client-go 的认证体系注册自身的凭据提供者程序只需产生“副作用”即可生效无需引用任何导出符号。值得注意的是各示例程序的main.go顶部都预留了加载认证插件的注释模板例如 create-update-delete-deployment/main.go 与 dynamic-create-update-delete-deployment/main.go按需取消注释即可启用。Configuration集群内与集群外的两种客户端配置方式集群内认证In-cluster当应用作为 Pod 运行在 Kubernetes 集群内部时推荐使用rest.InClusterConfig()自动构建配置。client-go 会读取 Pod 内挂载在/var/run/secrets/kubernetes.io/serviceaccount路径下的 Service Account Token 来认证 API Server。核心代码如下见 in-cluster-client-configuration/main.go// creates the in-cluster config config, err : rest.InClusterConfig() if err ! nil { panic(err.Error()) } // creates the clientset clientset, err : kubernetes.NewForConfig(config) if err ! nil { panic(err.Error()) }该示例通过clientset.CoreV1().Pods().List(...)每 10 秒轮询一次集群内所有命名空间的 Pod 数量并演示了标准的错误处理模式——使用errors.IsNotFound()判断资源不存在、或将错误断言为*errors.StatusError读取ErrStatus.Message获取详细状态信息。运行方式如下编译 Linux 平台二进制GOOSlinux go build -o ./app .使用提供的 Dockerfile 打包镜像该 Dockerfile 基于debian将./app复制进镜像并作为入口。若使用 Minikube可通过eval $(minikube docker-env)后docker build -t in-cluster .直接在节点上构建否则需推送到集群可拉取的镜像仓库。若集群开启了 RBAC先创建授权kubectl create clusterrolebinding default-view --clusterroleview --serviceaccountdefault:default运行kubectl run --rm -i demo --imagein-cluster程序会持续输出There are N pods in the cluster。清理kbdCtrl/kbdkbdC/kbd后执行kubectl delete deployment demo。集群外认证Out-of-cluster在集群外部如开发者工作站访问集群时通常从 kubeconfig 文件加载配置。各示例普遍采用clientcmd.BuildConfigFromFlags结合homedir工具解析默认 kubeconfig 路径例如var kubeconfig *string if home : homedir.HomeDir(); home ! { kubeconfig flag.String(kubeconfig, filepath.Join(home, .kube, config), (optional) absolute path to the kubeconfig file) } else { kubeconfig flag.String(kubeconfig, , absolute path to the kubeconfig file) } flag.Parse() config, err : clientcmd.BuildConfigFromFlags(, *kubeconfig) if err ! nil { panic(err) } clientset, err : kubernetes.NewForConfig(config) if err ! nil { panic(err) }该模式会自动回退到$HOME/.kube/config也可通过-kubeconfig标志显式指定路径。Basics使用 Typed Client 管理 Deployment 资源create-update-delete-deployment 示例演示了通过 Kubernetes API 对 Deployment 资源执行Create、Get、Update、List、Delete全生命周期操作这是管理其他类型资源的基础模板。运行步骤先确认集群可用kubectl get nodes然后编译运行cd create-update-delete-deployment go build -o ./app ./app # or specify a kubeconfig file with flag ./app -kubeconfig$HOME/.kube/config程序依次执行四个步骤每一步之间通过回车键Press Return key to continue交互式推进便于你中途用kubectl观察集群状态Create创建 2 副本的 Deployment可用kubectl get pods验证Update将副本数改为 1、镜像改为nginx:1.13可用kubectl describe deployment demo验证List列出default命名空间下的 Deployment 及副本数Delete删除 Deployment 及其依赖的 ReplicaSet可用kubectl get deployments验证。预期输出Creating deployment... Created deployment demo-deployment. - Press Return key to continue. Updating deployment... Updated deployment... - Press Return key to continue. Listing deployments in namespace default: * demo-deployment (1 replicas) - Press Return key to continue. Deleting deployment... Deleted deployment.若程序中途被终止可用kubectl delete deploy demo-deployment手动清理。源码中的关键实现构建 Deployment 对象时示例通过ptr.Toint32设置副本数、以metav1.LabelSelector定义 Pod 选择器、以apiv1.PodTemplateSpec定义 Pod 模板容器web镜像nginx:1.12暴露 TCP 80 端口完整代码见 create-update-delete-deployment/main.go。更新环节是重点main.go#L126-L138。源码注释明确指出两种 Update 策略直接修改deployment变量后调用Update(deployment)——等价于kubectl replace会覆盖甚至丢失其他客户端在Create与Update之间对对象的修改推荐做法先Get最新版本修改后调用Update并在冲突时用retry.RetryOnConflict重试从而保留其他客户端的并发修改。retryErr : retry.RetryOnConflict(retry.DefaultRetry, func() error { // Retrieve the latest version of Deployment before attempting update // RetryOnConflict uses exponential backoff to avoid exhausting the apiserver result, getErr : deploymentsClient.Get(context.TODO(), demo-deployment, metav1.GetOptions{}) if getErr ! nil { panic(fmt.Errorf(Failed to get latest version of Deployment: %v, getErr)) } result.Spec.Replicas ptr.Toint32 // reduce replica count result.Spec.Template.Spec.Containers[0].Image nginx:1.13 // change nginx version _, updateErr : deploymentsClient.Update(context.TODO(), result, metav1.UpdateOptions{}) return updateErr })retry.RetryOnConflict位于 util/retry/util.go采用指数退避策略retry.DefaultRetry避免对 apiserver 造成过载。删除时使用metav1.DeletePropagationForeground传播策略确保先终止依赖对象再删除main.go#L158-L163。Troubleshooting若运行时报panic: the server could not find the requested resource请用kubectl version确认集群版本为 v1.6 及以上。Advanced Concepts动态客户端与控制器模式使用 dynamic 包操作任意资源dynamic-create-update-delete-deployment 与 Typed 示例功能等价但改用dynamic包其 README 对两者差异做了清晰对比Typed Clients使用预生成的本地 API 对象编译期即可强制数据安全与部分校验编程体验接近 RPC 调用但程序与具体 API 版本和类型强耦合Dynamic 包以unstructured.Unstructured内部为嵌套的map[string]interface{}统一表示所有 API 对象数据绑定推迟到运行时失去编译期类型校验但换来的是与 API 版本的松耦合API 变化时无需重新编译。动态客户端的核心是先声明资源标识GroupVersionResource再用Resource(...).Namespace(...)链式调用deploymentRes : schema.GroupVersionResource{Group: apps, Version: v1, Resource: deployments} client, err : dynamic.NewForConfig(config) ... result, err : client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Create(context.TODO(), deployment, metav1.CreateOptions{})Deployment 对象以unstructured.Unstructured字面量构建main.go#L66-L105字段路径与 REST 载荷完全一致。更新时借助unstructured.SetNestedField修改嵌套字段副本数与镜像列出时用unstructured.NestedInt64读取嵌套值删除同样使用DeletePropagationForeground。该示例要求集群版本 v1.13 及以上。用 workqueue informer 编写无热循环的控制器workqueue 示例展示了如何组合 rate-limited workqueue 与 informer 框架编写一个不依赖轮询hotloop-free的控制器。其控制器结构体main.go#L40-L44由三部分组成type Controller struct { indexer cache.Indexer queue workqueue.TypedRateLimitingInterface[string] informer cache.Controller }工作流如下构建 ListWatchcache.NewListWatchFromClient(clientset.CoreV1().RESTClient(), pods, v1.NamespaceDefault, fields.Everything())创建 Pod 的列表/监听器创建队列workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[string]())创建带默认限速器的限速队列绑定 informercache.NewIndexerInformer将缓存与队列绑定在AddFunc/UpdateFunc/DeleteFunc回调中通过cache.MetaNamespaceKeyFunc删除场景用cache.DeletionHandlingMetaNamespaceKeyFunc计算对象的命名空间/名称 key 并queue.Add(key)启动同步controller.Run(ctx, workers)中先启动 informer再用cache.WaitForNamedCacheSyncWithContext等待缓存同步完成最后以wait.UntilWithContext启动多个 worker 循环调用processNextItem。关键设计点processNextItem中defer c.queue.Done(key)在业务逻辑完成后解除 key 的阻塞保证同一 key 不会被并行处理业务逻辑syncToStdout只负责从indexer.GetByKey(key)取对象并输出错误直接返回重试逻辑不混入业务逻辑handleErr实现错误退避成功则queue.Forget(key)清空限速历史失败且NumRequeues(key) 5时AddRateLimited(key)按限速器节奏重新入队超过 5 次则丢弃并调用runtime.HandleErrorWithLogger报告示例还展示了“预热缓存”indexer.Add(...)直接注入一个已知 Pod缓存同步后若该 Pod 已不存在控制器会收到删除通知。运行方式go run *.go -kubeconfig/my/config集群外。基于 Leader Election 实现高可用控制器leader-election 演示了leaderelection包的用法这是实现 HA高可用控制器的关键组件多个副本同时运行但同一时刻只有一个实例持有锁并执行控制循环避免重复操作。核心流程main.go#L119-L176lock : resourcelock.LeaseLock{ LeaseMeta: metav1.ObjectMeta{ Name: leaseLockName, Namespace: leaseLockNamespace, }, Client: client.CoordinationV1(), LockConfig: resourcelock.ResourceLockConfig{ Identity: id, }, } leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{ Lock: lock, // IMPORTANT: you MUST ensure that any code you have that // is protected by the lease must terminate **before** // you call cancel. ... ReleaseOnCancel: true, LeaseDuration: 60 * time.Second, RenewDeadline: 15 * time.Second, RetryPeriod: 5 * time.Second, Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(ctx context.Context) { // were notified when we start - this is where you would // usually put your code startedLeading.Store(true) run(ctx) }, OnStoppedLeading: func() { // we can do cleanup here, but note that this callback is always called // when the LeaderElector exits, even if it did not start leading. ... }, OnNewLeader: func(identity string) { // were notified when new leader elected ... }, }, })要点说明锁对象支持LeaseLock推荐、ConfigMap或已废弃的Endpoints示例选用LeaseLock因为 Lease 的修改频率更低、被 Watch 的对象更少可降低 apiserver 压力三个时间参数LeaseDuration租约有效期 60s、RenewDeadline续约截止 15s、RetryPeriod重试周期 5sReleaseOnCancel: true保证在调用cancel()释放租约前受租约保护的代码已终止避免“背景循环仍在运行、另一进程已当选”的竞态OnStoppedLeading在 LeaderElector 退出时总是被调用即使从未当选过因此示例用startedLeadingatomic.Bool判断是否真的开始过领导再决定是否执行清理程序监听os.Interrupt与syscall.SIGTERM收到信号后取消 context触发优雅退位。运行方式在三个终端分别执行id必须唯一# first terminal go run main.go -kubeconfig/path/to/kubeconfig -logtostderrtrue -lease-lock-nameexample -lease-lock-namespacedefault -id1 # second terminal go run main.go -kubeconfig/path/to/kubeconfig -logtostderrtrue -lease-lock-nameexample -lease-lock-namespacedefault -id2 # third terminal go run main.go -kubeconfig/path/to/kubeconfig -logtostderrtrue -lease-lock-nameexample -lease-lock-namespacedefault -id3在集群内运行时可以忽略-kubeconfig标志程序会自动回退到rest.InClusterConfig()见buildConfig函数。随后杀掉当前 Leader观察剩余两个进程之一被选举为新 Leader。三个默认标志-kubeconfigkubeconfig 路径、-id身份名默认随机 UUID、-lease-lock-name/-lease-lock-namespace锁资源名与命名空间必填。Testing用 Fake Client 编写不依赖真实集群的测试fake-client 展示了在测试中使用 fake client 与SharedInformerFactory配合的完整模式测试入口见 main_test.go。// Create the fake client. client : fake.NewSimpleClientset() // A catch-all watch reactor that allows us to inject the watcherStarted channel. client.PrependWatchReactor(*, func(action clienttesting.Action) (handled bool, ret watch.Interface, err error) { ... watch, err : client.Tracker().Watch(gvr, ns, opts) ... close(watcherStarted) return true, watch, nil })测试覆盖三个要点创建 fake clientfake.NewSimpleClientset()来自 kubernetes/fake在内存中模拟 apiserver 行为无需真实集群搭建真实 informer通过informers.NewSharedInformerFactory(client, 0)创建工厂、获取 Pod informer 并注册AddEventHandler注入事件通过client.CoreV1().Pods(test-ns).Create(...)向 fake client 写入 Pod验证 informer 能否通过 watch 通道收到 Add 事件。示例中的关键细节通过PrependWatchReactor(*)注册全局 watch 反应器并注入watcherStarted通道确保 informer 的 watcher 已建立后再注入事件否则事件可能在 informer 初次 LIST 之后、建立 watcher 之前被遗漏源码注释明确指出fake client 不支持 resource version并非为配合 informer 设计。若需测试 informer/controller 的复杂行为建议在集成/E2E 测试中使用真实 client用cache.WaitForCacheSync等待 informer 完成初始同步最后通过带超时的select断言 Pod 到达事件通道。运行方式go test -v k8s.io/client-go/examples/fake-client另注该包因没有非测试文件doc.go 用于避免go build时的包空警告。小结示例矩阵与进阶路径示例目录核心能力关键依赖包in-cluster-client-configuration集群内自动认证rest.InClusterConfigcreate-update-delete-deploymentTyped 客户端资源增删改查 冲突重试kubernetes、util/retrydynamic-create-update-delete-deployment动态客户端操作任意资源dynamic、unstructuredworkqueue事件驱动控制器 限速重试队列tools/cache、util/workqueueleader-election高可用选主与优雅退位tools/leaderelectionfake-client无集群的单元测试kubernetes/fake、informers关于 CRDCustom Resource Definitionexamples 目录 README 指出可参考 apiextensions-apiserver 仓库的 client-go 示例注册自定义资源类型、增删改查自定义资源并编写驱动集群状态的控制器。示例中informer框架对应k8s.io/client-go/tools/cache的NewInformer。所有示例源码都遵循“同一 release/branch 内代码方可匹配运行”的约定实际使用时应选择与所依赖 client-go 版本一致的示例代码。赞分享云原生后端【免费下载链接】client-goGo client for Kubernetes.项目地址https://gitcode.com/gh_mirrors/cl/client-go点击查看免费下载相关推荐Mosquitto 插件体系完全指南从 Dynamic Security 到 20 官方示例插件的实战解析Mosquitto 插件体系完全指南从 Dynamic Security 到 20 官方示例插件的实战解析 Eclipse Mosquitto 通过 plu后端消息队列消息路由Express 5 官方示例完全指南从认证、会话到路由组织的 24 个实战范例Express 5 官方示例完全指南从认证、会话到路由组织的 24 个实战范例 本指南以仓库中 examples/README.md https://link后端Web框架Rustls 官方示例程序全解析从 simple-client 到 ECH、0-RTT 与 Acceptor 的实战指南Rustls 官方示例程序全解析从 simple client 到 ECH、0 RTT 与 Acceptor 的实战指南 本指南以仓库中 examples/R网络安全密码学网络创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考