ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

projectcalico/api 深入解读:Calico v3 API 定义、ClientSet 使用与新增 API 完整实践

2026/9/28 2:45:50 拓冰建站 浏览量
projectcalico/api 深入解读:Calico v3 API 定义、ClientSet 使用与新增 API 完整实践 网络云原生网络安全【免费下载链接】calicoCloud native networking and network security项目地址https://gitcode.com/gh_mirrors/cal/calico点击查看免费下载导读api/目录是 ProjectcalicoCalico 项目API 定义的权威来源canonical source它承载了 Calico 全部 v3 版 API 的类型定义、CRD 清单以及自动生成的 Go 客户端ClientSet、Informer、Lister、ApplyConfiguration 等。本文以 api/README.md 为主线结合仓库源码为你拆解三件事API 类型在仓库中的组织方式、如何用生成的 ClientSet 直接编程操作 Calico 资源以 GlobalNetworkPolicy 为例以及如何新增一个 API 类型并让整套生成代码与 CRD 保持同步。读完本文你将具备在 Kubernetes 生态中二次开发 Calico 控制面程序如策略控制器、IPAM 工具所需的完整知识链。一、定位为什么需要独立的 API 定义仓库从 api/README.md 可以看出api目录是Projectcalico 的 API 定义权威来源canonical source。它的核心职责是定义projectcalico.org/v3这一 API 组下的所有资源类型NetworkPolicy、IPPool、BGPConfiguration、FelixConfiguration、Tier 等通过代码生成器产出客户端、informer、lister、deepcopy 与 OpenAPI 定义供 calico 主仓库的其他组件如 felix、calicoctl、kube-controllers、operator复用通过go:embed将生成的 CRD YAML 直接嵌入 Go 二进制使程序在运行时无需依赖外部 CRD 文件即可拿到完整定义。这一点在 api/embed.go 中得到印证AllCRDs()函数使用//go:embed config/crd/*.yaml将 v3 的 CRD 定义嵌入并解析为apiextensions/v1的CustomResourceDefinition对象列表。这意味着任何依赖api包的组件都能以纯 Go 方式获得 CRD 定义这也是该目录被设计为独立、可镜像的仓库模块github.com/projectcalico/api参见 api/Makefile的原因。二、API 类型的组织与注册从类型文件到 Scheme2.1 目录布局所有 v3 API 类型都位于pkg/apis/apigroup/version下。在 api/pkg/apis/projectcalico/v3 中可以看到完整的资源清单每个资源一个.go文件例如globalnetworkpolicy.go— 全局网络策略networkpolicy.go/stagednetworkpolicy.go— 命名空间级网络策略与分层策略ippool.go— IP 池bgpconfiguration.go/bgppeer.go/bgpfilter.go— BGP 相关配置felixconfig.go/kubecontrollersconfig.go— 各组件配置ipamblocks.go/ipamhandle.go/blockaffinity.go— IPAM 数据面资源tier.go— 策略分层文件头部的k8s:deepcopy-gen、genclient、kubebuilder等标记marker是该类型进入代码生成流水线的入口。2.2 register.go类型如何进入 Scheme新类型必须登记到register.go才能被识别。api/pkg/apis/projectcalico/v3/register.go 定义了API 组名GroupName projectcalico.org版本v3AllKnownTypes列表所有已注册的runtime.ObjectNetworkPolicy、GlobalNetworkPolicy、IPPool、BGPConfiguration、Tier 等 30 余种含各自的 List 类型AddToGlobalScheme()将本地 SchemeBuilder 注册进 Kubernetes 全局scheme.Scheme通过sync.Once保证幂等Resource()将资源名解析为schema.GroupResource。理解 register.go 是理解新增 API三步流程中第二步第 2 步的关键类型定义完成后必须在AllKnownTypes中登记才能被客户端与序列化/反序列化Scheme机制感知。三、用 ClientSet 编程操作 Calico 资源How to useREADME 给出的第一种使用方式是直接导入 clientset 并使用它配套示例位于 examples/list-gnp/main.go。这是一个小而完整的可运行程序演示了完整的接入链路值得逐段拆解。3.1 完整示例代码package main import ( context flag fmt github.com/projectcalico/api/pkg/client/clientset_generated/clientset v1 k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/client-go/tools/clientcmd ) func main() { // Create a new config based on kubeconfig file. kubeconfig : flag.String(kubeconfig, , absolute path to the kubeconfig file) flag.Parse() config, err : clientcmd.BuildConfigFromFlags(, *kubeconfig) if err ! nil { panic(err.Error()) } // Build a clientset based on the provided kubeconfig file. cs, err : clientset.NewForConfig(config) if err ! nil { panic(err) } // List global network policies. list, err : cs.ProjectcalicoV3().GlobalNetworkPolicies().List(context.Background(), v1.ListOptions{}) if err ! nil { panic(err) } for _, gnp : range list.Items { fmt.Printf(%#v\n, gnp) } }3.2 调用链路逐层解读这段代码的调用链与仓库中的生成代码一一对应构建 REST 配置clientcmd.BuildConfigFromFlags(, *kubeconfig)读取 kubeconfig 文件--kubeconfig参数默认空字符串时使用默认加载规则。这是所有 Kubernetes 客户端程序的标准入口。构建 ClientSetclientset.NewForConfig(config)来自 api/pkg/client/clientset_generated/clientset/clientset.go。NewForConfig内部会为config.UserAgent填默认值、通过rest.HTTPClientFor创建共享 HTTP 客户端再分别构造projectcalicoV3客户端与 DiscoveryClient。若设置了QPS 0而未设置RateLimiter还会自动创建令牌桶限速器flowcontrol.NewTokenBucketRateLimiter此时要求Burst 0见同文件第 66-73 行。访问资源接口cs.ProjectcalicoV3()返回ProjectcalicoV3Interface从中取得GlobalNetworkPolicies()这个 Typed 客户端其List方法对应GET /apis/projectcalico.org/v3/globalnetworkpolicies请求。遍历结果list.Items是[]GlobalNetworkPolicy类型定义见 globalnetworkpolicy.go。由于 ClientSet 是 Typed 客户端list.Items中的元素直接是强类型结构体无需手动做 JSON 反序列化。想更贴近生产使用可参考同一目录下的其他生成代码informerapi/pkg/client/informers_generated/externalversions用于 Watch 监听listerapi/pkg/client/listers_generated/projectcalico/v3用于本地索引查询fake clientsetapi/pkg/client/clientset_generated/clientset/fake用于单元测试打桩。3.3 构建示例程序api/Makefile 中提供了examples目标它会将示例编译为bin/list-gnp可执行文件.PHONY: examples examples: bin/list-gnp bin/list-gnp: examples/list-gnp/main.go echo Building list-gnp example binary... $(call build_binary, examples/list-gnp/main.go, $)运行时只需./bin/list-gnp --kubeconfig /path/to/kubeconfig即可枚举集群中全部 GlobalNetworkPolicy包括其完整的 Spec 结构以%#v格式打印。四、新增一个 API三步走流程与代码生成机制README 给出新增 API 的标准流程这是本目录最核心的工程实践下面结合 Makefile 与生成代码逐一深化。4.1 第一步创建类型定义文件在pkg/apis/apigroup/version下新建一个.go文件例如仿照 globalnetworkpolicy.go 的结构定义一个资源// genclient // genclient:nonNamespaced // 集群级资源则加此行 // k8s:deepcopy-gen:interfacesk8s.io/apimachinery/pkg/runtime.Object // kubebuilder:resource:scopeCluster,shortName{xxx} type MyResource struct { metav1.TypeMeta json:,inline metav1.ObjectMeta json:metadata Spec MyResourceSpec json:spec }类型定义顶部的 marker 注释是代码生成器的指令genclient/genclient:nonNamespaced控制 client-gen 生成 Typed 客户端的方式与资源作用域k8s:deepcopy-gen声明需要 deepcopy 代码kubebuilder:resource:scopeCluster等影响 CRD 清单的生成作用域、短名 shortName。以GlobalNetworkPolicy为例其 Specglobalnetworkpolicy.go展示了丰富的验证标记用法kubebuilder:validation:MaxItems1024限制每个策略的规则数、kubebuilder:defaultdefault为Tier字段设默认值、kubebuilder:printcolumn定义 kubectl 输出的附加列以及多个XValidation自定义校验规则如preDNAT 策略不能包含 egress 规则preDNAT 与 doNotTrack 不能同时为真。这些标记最终都会落到生成的 CRD YAML 中成为运行时的 schema 约束。4.2 第二步注册到 register.go把新类型以及对应的 List 类型追加进 register.go 的AllKnownTypes列表AllKnownTypes []runtime.Object{ // ... 既有类型 MyResource{}, MyResourceList{}, }该列表通过addKnownTypes注册到SchemeGroupVersion见同文件第 113-117 行是类型被 Scheme、客户端和编解码器识别的唯一入口。4.3 第三步运行make build重新生成全部代码README 指出第三步是更新生成代码包括 clients、informers 等命令为make build在 api/Makefile 中build目标是gen-files examples第 57 行。gen-files第 63-85 行实际执行了以下工作理解它有助于排查为什么我的新类型没有生成代码清理过期产物clean-generated删除所有zz_generated*文件以及pkg/client/clientset_generated、pkg/client/informers_generated、pkg/client/listers_generated、pkg/client/applyconfiguration_generated、pkg/openapi目录见第 106-111 行保证全量重建而非增量修补生成 CRD YAML使用仓库内置的 Calico 定制版 controller-gen 执行crd:allowDangerousTypestrue,crdVersionsv1 paths./pkg/apis/... output:crd:dirconfig/crd/输出到 api/config/crd22 个 YAML 1 个 embed.go随后移除 YAML 首行分隔符、用 prettier 统一缩进并删除projectcalico.org_profiles.yamlProfile 由 Kubernetes Namespace 支撑无需 CRD见第 74-75 行生成 Go 产物通过build/codegen.sh生成 deepcopyzz_generated.deepcopy.go、OpenAPI 定义、客户端、informer、lister 与 applyconfiguration格式化fix目标对所有 Go 文件执行goimports -w -local规范化 import 分组。CI 中还有一个值得注意的守门目标check-generated-files第 147-154 行它运行生成后检查git describe --tags --dirty是否包含 dirty 标记若生成文件与源码不同步则 CI 直接失败。这保证了手改生成文件或忘了重新生成都不会悄悄混入代码库。4.4 单测与校验配套Makefile 还提供了两套测试目标可作为新增 API 的验证手段ut基于 kind 集群运行 ginkgo 测试ginkgo -r第 127-135 行ut-validation基于 envtestKUBEBUILDER_ASSETS运行 CRD 校验测试不需要 kind 集群第 138-144 行。ci目标第 159-161 行串联了clean check-generated-files build static-checks ut是新增 API 合入前需要跑通的完整流水线。仓库内的既有测试如 networkpolicy_test.go、conversion_test.go是编写新类型测试的现成范本。五、从类型到 CRD 的落地链路小结把上述环节串起来一次新增 API的完整生命周期是新建类型文件marker 注释声明生成规则 ↓ 注册到 register.go 的 AllKnownTypes ↓ make buildgen-files ├── controller-gen → config/crd/*.yamlCRD 清单 ├── codegen.sh → deepcopy / openapi / clientset / informers / lister / applyconfiguration └── go:embed → 编译进二进制的 CRD 定义embed.go 的 AllCRDs() ↓ 编写/运行单测与 CRD 校验ut / ut-validation ↓ check-generated-files 确保生成产物与源码同步在这条链路中api/embed.go 的//go:embed config/crd/*.yaml是一个容易被忽略但非常关键的环节它让api包的用户包括 operator、apiserver 等组件可以在运行时通过AllCRDs()直接获得完整的 CRD 对象列表无需额外读取文件系统。这也解释了为什么 README 强调该目录是canonical source——Calico 的 API 事实标准在这里定义其他一切组件都从这份定义派生。六、给二次开发者的实践建议优先复用生成客户端而非手写 REST 调用api目录已为全部 v3 资源生成 Typed 客户端、informer、lister 与 fake 实现api/pkg/client覆盖 List/Get/Create/Update/Delete/Watch 全套操作直接导入github.com/projectcalico/api/pkg/client/clientset_generated/clientset即可新增资源时严格按三步流程走新建类型 → 注册 register.go →make build。若生成的 CRD YAML 或客户端缺失优先检查 marker 注释是否齐全、类型是否已登记注意资源作用域命名空间级资源如 NetworkPolicy与集群级资源如 GlobalNetworkPolicy见genclient:nonNamespaced在客户端接口、CRD scope 与 informer 命名空间参数上均有差异定义时务必明确把 CI 校验当作红线check-generated-files会拒绝任何生成产物与源码不一致的提交因此手改 zz_generated 文件是无效且会被 CI 拦截的做法正确的姿势永远是修改源类型后重新生成善用既有测试范式新增类型后参考networkpolicy_test.go等文件补充单元测试并用make ut-validation在 envtest 环境中快速验证 CRD schema 是否符合预期。总而言之api/目录是 Calico 生态的API 中枢类型在此定义、客户端在此生成、CRD 在此落地并被嵌入二进制。理解它的组织方式、ClientSet 使用模式和代码生成流水线是进入 Calico 控制面二次开发策略管理、IPAM 工具、定制 operator最直接的入口。赞分享网络云原生网络安全【免费下载链接】calicoCloud native networking and network security项目地址https://gitcode.com/gh_mirrors/cal/calico点击查看免费下载相关推荐Wagtail API 完全指南v2 只读 API 与 v3 全新 API 的配置、使用与源码解析Wagtail API 完全指南v2 只读 API 与 v3 全新 API 的配置、使用与源码解析 Wagtail 内置了一套完整的 API 模块目前同时存CMS后端KubeEdge api 模块详解CRD 类型定义、clientset 与 API 文档的规范位置staging/src/github.com/kubeedge/apiKubeEdge api 模块详解CRD 类型定义、clientset 与 API 文档的规范位置staging/src/github.com/kubeed云原生边缘计算物联网容器编排边缘网关使用 ESLint Node.js API 构建自定义集成从入门实战到完整 API 参考使用 ESLint Node.js API 构建自定义集成从入门实战到完整 API 参考 本文以 ESLint 官方“集成指南”为骨架系统讲解如何通过 No开发工具Lint静态分析代码质量上一篇Learn Harness Engineering 项目 08把工作流画成图——从单循环到图工程的第一步实战下一篇[3.1.0] - 2018-06-21创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考