拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Kubernetes 社区实践:使用 client-gen 生成 Clientset 的完整指南与发布周期

Kubernetes 社区实践使用 client-gen 生成 Clientset 的完整指南与发布周期【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community导读本文基于 Kubernetes 社区仓库 contributors/devel/sig-api-machinery/generating-clientset.md 展开系统讲解client-gen这一自动化代码生成工具的使用方法如何通过// genclient系列注解标记 API 类型、如何在内外部仓库分别触发生成、如何用扩展接口expansion interface为客户端补充自定义方法以及生成产物的目录结构与官方发布渠道。读完本文你将掌握在k8s.io/kubernetes仓库内外使用 client-gen 生成 clientset 的完整流程并理解生成代码的底层组织约定。什么是 clientset 与 client-gen在 Kubernetes 的 API Machinery 体系中clientset是一组类型安全type-safe的 Go 客户端集合它为每个 API group 提供对应的 client 对象并以强类型方法封装对 API 资源的 CRUDcreate、update、delete、get、list、patch、watch等操作。社区最初在设计层面定义了高层级客户端集合high-level client sets这一概念client-gen正是基于这些 API 类型自动生成 clientset 的工具。关联阅读仓库 contributors/devel/sig-architecture/api_changes.md 将client-gen与lister-gen、informer-gen、defaulter-gen、deepcopy-gen、conversion-gen、openapi-gen等并列为 Kubernetes 核心代码生成器家族并指出client-gen针对的是顶层 API 对象top-level API objects——即那些独立存在、可被客户端直接操作的资源类型。使用 client-gen 的三步工作流生成 clientset 的整体流程分为三步标记 API 类型 → 运行生成工具 → 手动补充扩展方法。下面逐一展开。第 1 步用注解标记 API 类型在pkg/apis/${GROUP}/${VERSION}/types.go中为希望生成客户端代码的类型例如 Pod打上// genclient注解。若该资源不按命名空间作用域例如 PersistentVolume还需要追加// genclient:nonNamespaced注解。仓库 contributors/devel/sig-architecture/api_changes.md 补充了一个关键细节client-gen要求在每个导出的类型上都标注// genclient且这一要求同时适用于内部版本pkg/apis/group/types.go与每个具体版本化的 API 包staging/src/k8s.io/api/group/version/types.go两者缺一不可。核心注解Client Verb 控制注解作用// genclient生成默认客户端动词函数create、update、delete、get、list、update、patch、watch若该类型存在.Status字段还会额外生成updateStatus。// genclient:nonNamespaced所有动词函数均按非命名空间全局作用域生成。// genclient:onlyVerbscreate,get只生成列出的动词函数此处为 create 与 get。// genclient:skipVerbswatch生成全部默认动词函数但排除watch 动词。// genclient:noStatus即使类型中存在.Status字段也跳过updateStatus动词的生成。需要特别留意默认动词列表中update出现了两次这并非笔误而是指更新主资源这一常规操作本身即同时对应update动词结合onlyVerbs/skipVerbs的用法可以看出这些注解的取值以 API 动词verb为准patch、watch等均是可独立裁剪的单元。非标准动词sub-resource 场景注解某些场景需要为子资源sub-resource生成非标准动词方法此时使用// genclient:method注解// genclient:methodScale,verbupdate,subresourcescale,inputk8s.io/api/extensions/v1beta1.Scale,resultk8s.io/api/extensions/v1beta1.Scale该注解会在默认 client 上新增一个函数Scale(string, *v1beta.Scale) *v1beta.Scale函数体基于update动词生成可选的subresource参数让生成的客户端函数使用子资源scale可选的input与result参数允许用自定义类型覆盖默认的输入输出类型若未给出 import 路径生成器会假定该类型存在于当前同一包中。影响生成的附加注解注解作用// groupNamepolicy.authorization.k8s.io在 fake client 中用作完整 group 名称默认取包名。// groupGoNameAuthorizationPolicy提供一个 CamelCase 形式的 Go 标识符用于消除前缀不唯一的 group 之间的命名冲突例如policy.authorization.k8s.io与policy.k8s.io默认都会映射成 clientset 中的Policy()方法造成冲突此注解可显式指定不同标识符默认取 group 名称首段的大写形式。仓库 contributors/devel/sig-architecture/api_changes.md 对groupName注解给出了更具体的背景当 apiserver 以与文件系统group不同的名称承载 API 时通常是因为文件系统中的group省略了 k8s.io 后缀例如admissionvsadmission.k8s.io需要在内部pkg/apis/group/doc.go和版本化包staging/src/k8s.io/api/group/version/types.go的doc.go中同时添加// groupName注解client-gen 才会使用正确的 group 名称。第 2 步运行生成工具2a. 在 k8s.io/kubernetes 仓库内开发如果你在k8s.io/kubernetes仓库内开发只需运行hack/update-codegen.sh该脚本会统一驱动代码生成流程。根据 api_changes.md 的说明同一次hack/update-codegen.sh运行还会顺带调用lister-gen生成 listers与informer-gen生成监听 API 资源变化的 Informers两者都复用// genclient与// groupName注解因此无需额外添加注解。2b. 在 k8s.io/kubernetes 仓库之外使用 client-gen若在k8s.io/kubernetes仓库之外独立运行 client-gen需要使用命令行参数--input指定想要生成客户端的 API group 与 version。client-gen 会去查找pkg/apis/${GROUP}/${VERSION}/types.go并为其中打上genclient注解的类型生成客户端。例如要生成一个名为my_release的 clientset其中包含 api/v1 对象与 extensions/v1beta1 对象的客户端$ client-gen --inputapi/v1,extensions/v1beta1 --clientset-namemy_release两个关键参数--input逗号分隔的group/version列表决定生成范围--clientset-name生成的 clientset 名称此处为my_release它会直接影响输出目录的命名。常用生成器配套参数结合 api_changes.md 对代码生成器家族的介绍多数生成器基于gengo框架、共享通用 flags其中有两个与 client-gen 场景直接相关的实践要点--verify-only检查磁盘上已有文件与将要生成的内容是否一致不一致则失败退出适合作为 CI 校验手段--go-header-file指定生成 Go 文件顶部需要包含的文件头通常是版权声明生成代码的 boilerplate 后续会被repo-infra/verify/verify-boilerplate.sh校验。第 3 步添加扩展方法Expansion Methodsclient-gen 只生成通用方法CRUD 等。如果需要为某个资源补充额外方法可通过扩展接口手动添加。原文档给出的典型例子是staging/src/k8s.io/client-go/kubernetes/typed/core/v1/pod_expansion.go它为 Pod 的 client 添加了额外方法。社区约定扩展接口及其方法放在${TYPE}_expansion.go文件中例如pod_expansion.go。一个重要的实操技巧大多数情况下不要删除已有的扩展文件。为了让生活更轻松与其从零创建新 clientset不如复制并重命名一个已有 clientset这样所有扩展文件都会被一并复制过来然后再运行 client-gen。这样既保留了历史扩展逻辑又能利用生成器补齐新资源对应的客户端代码。client-gen 的输出结构client-gen 的生成产物分两部分clientset默认生成在pkg/client/clientset_generated/可通过--clientset-path命令行参数修改输出路径单个 typed client 与 group client生成在pkg/client/clientset_generated/${clientset_name}/typed/generated/${GROUP}/${VERSION}/。因此使用--clientset-namemy_release且不修改--clientset-path时输出目录大致为pkg/client/clientset_generated/my_release/typed/generated/${GROUP}/${VERSION}/每个${GROUP}/${VERSION}目录下会产出该 group 对应版本的 typed client 代码clientset 顶层则聚合各 group 的访问入口如CoreV1()、ExtensionsV1beta1()等这也是// groupGoName注解用于解决同名方法冲突的原因所在——多个 group 会映射为 clientset 上的多个方法命名必须唯一。已发布的 clientset 与发布周期在版本发布层面社区提供了两条使用路径为 k8s.io/kubernetes 贡献代码时优先使用仓库内已生成的 clientset位于pkg/client/clientset_generated/internalclientsetinternal clientset 对应内部版本 API。构建自己的项目、需要稳定的 Go 客户端时请直接参考独立的client-go仓库k8s.io/client-go它是社区对外发布的、经过版本化管理的稳定客户端库。此外社区当时正在推进将k8s.io/kubernetes自身也迁移到 client-go 上对应上游 issue #35159这也解释了为什么现代 Kubernetes 生态中几乎所有外部项目都通过 client-go 来访问集群——它在发布周期上独立演进比仓库内生成的 internal clientset 更适合对外消费。与兄弟生成器的协同进阶理解理解 client-gen 在代码生成流水线中的位置有助于判断生成客户端后还要做什么。根据 api_changes.md 的说明一次完整的 API 变更代码生成通常还包含lister-gen生成 listers缓存化的只读索引器避免反复深拷贝复用// genclient与// groupName注解informer-gen生成 Informerswatch API 资源变化并推送事件同样复用上述注解go-to-protobuf为 API 对象生成 Protobuf IDL 与 marshaler核心 API 对象需运行hack/update-generated-protobuf.shdeepcopy-gen/defaulter-gen/conversion-gen分别生成深拷贝、默认值与转换函数相关产物如zz_generated.deepcopy.go、zz_generated.defaults.go等可通过make generated_files或make update整体触发。实践中若只想校验生成结果而不实际写盘可使用各生成器共享的--verify-only标志若完整构建太慢也可以按上文所述单独运行 client-gen。总结环节关键要点类型标记// genclient必选命名空间/动词裁剪/子资源用nonNamespaced、onlyVerbs、skipVerbs、noStatus、method控制group 命名// groupName指定完整 group 名// groupGoName消除Policy()式命名冲突生成命令仓库内用hack/update-codegen.sh仓库外用client-gen --inputgroup/version --clientset-name...扩展方法手动编写${TYPE}_expansion.go复制既有 clientset 可保留扩展文件产物位置clientset 默认在pkg/client/clientset_generated/typed client 在其下typed/generated/${GROUP}/${VERSION}/对外使用稳定生产环境推荐 client-go为 kubernetes 贡献代码用 internalclientset如需进一步阅读本仓库内的关联资料可参考generating-clientset.md 原文、API 变更与代码生成总览、controller 编写指南 以及 strategic merge patch 详解。【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门