Golang中如何在K8s测试的fakeClient内注册JivaVolume等自定义CRD?
报错原因
no kind is registered for the type v1alpha1.JivaVolume in scheme 报错的核心原因是client-go的scheme没有完成自定义CRD类型与对应GVK(组/版本/Kind)的绑定:K8s官方提供的fake clientset默认仅内置了原生K8s资源的类型注册规则,自定义CRD的类型需要手动注册才能被识别。
另外你当前代码中JivaVolume对象的TypeMeta为空,也是导致识别失败的常见原因。
修复步骤
1. 补全TypeMeta配置
给模拟的JivaVolume对象补全正确的APIVersion和Kind配置,替换为你实际使用的CRD组版本:
var jv1 = v1alpha1.JivaVolume{ TypeMeta: metav1.TypeMeta{ APIVersion: "openebs.io/v1alpha1", Kind: "JivaVolume", }, ObjectMeta: metav1.ObjectMeta{ Name: "pvc-1", Namespace: "openebs", Labels: map[string]string{"nodeID": "worker-node-1"}, }, // 其余自定义字段 }
2. 手动注册CRD类型到scheme
CRD代码生成工具默认会自动生成AddToScheme方法,你可以通过该方法将自定义类型注册到fake客户端使用的scheme中,有两种实现方式可选:
方式一:使用全局scheme注册
初始化阶段直接将CRD类型注册到client-go全局scheme:
import ( "k8s.io/client-go/kubernetes/scheme" jivav1alpha1 "your-project-path/pkg/apis/openebs/v1alpha1" // 替换为你实际的JivaVolume API包路径 "k8s.io/client-go/kubernetes/fake" ) func init() { // 注册JivaVolume类型到全局scheme _ = jivav1alpha1.AddToScheme(scheme.Scheme) } // 后续创建fake客户端逻辑不变 fakeClient := fake.NewSimpleClientset(&jivaPV1, &jv1)
方式二:自定义scheme(更安全,不污染全局)
单独构造scheme实例传给fake客户端,避免影响其他逻辑的scheme配置:
import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" jivav1alpha1 "your-project-path/pkg/apis/openebs/v1alpha1" "k8s.io/client-go/kubernetes/fake" ) // 构造自定义scheme customScheme := runtime.NewScheme() // 注册K8s原生资源类型 _ = scheme.AddToScheme(customScheme) // 注册自定义JivaVolume类型 _ = jivav1alpha1.AddToScheme(customScheme) // 用自定义scheme创建fake客户端 fakeClient := fake.NewSimpleClientsetWithScheme(customScheme, &jivaPV1, &jv1)
特殊场景兼容
如果你的CRD没有自动生成的AddToScheme方法,可以手动调用AddKnownTypeWithName完成注册:
gvk := schema.GroupVersionKind{ Group: "openebs.io", Version: "v1alpha1", Kind: "JivaVolume", } customScheme.AddKnownTypeWithName(gvk, &v1alpha1.JivaVolume{})
内容的提问来源于stack exchange,提问作者Abhishek Kumar
相关产品推荐
相关产品推荐

