是如何利用kubernetes来自定义类型,如SparkApplication,从而使用脚本,生成响应的代码的
这些代码是专门为自定义的类型SparkApplication对象服务的
0、最终效果如下:
1、测试环境说明
VMware + Centos 7
2、我们需要编写的文件,我测试需要3个(可能测试不够充分)
doc.go
register.go
types.go
3、创建Go工程,利用k8s的特性自定义类型
types.go的主要内容,如下(你需要根据自己的实际情况去自定义类型)
我这里仅仅截图了一部分:
doc.go的内容:
// +k8s:deepcopy-gen=package,register // Package v1beta1 is the v1beta1 version of the API. // +groupName=sparkoperator package v1beta1
register.go的内容:
package v1beta1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "xingej-go/xingej-k8s-spark/SparkOperatorOnK8sForApp/pkg/apis/spark" ) var ( SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) AddToScheme = SchemeBuilder.AddToScheme ) // SchemeGroupVersion is the group version used to register these objects. var SchemeGroupVersion = schema.GroupVersion{Group: spark.GroupName, Version: spark.Version} func init() { SchemeBuilder.Register(addDefaultingFunc) } // Resource takes an unqualified resource and returns a Group-qualified GroupResource. func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &SparkApplication{}, &SparkApplicationList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func addDefaultingFunc(scheme *runtime.Scheme) error { return RegisterDefaults(scheme) }
说明,你在编写声明函数addKnownTypes时,会抛异常,不用担心,是因为缺少文件导致的(根本原因应该是你自定义的类型,并没有添加到schema里),
生成代码后,会自动消失的
编写好上面的文件后,就可以利用脚本来生成代码了
4、我自己根据git上参考的实例,编写了一个脚本,如下update-codegen.sh
具体说明:
四个参数:
第一个 参数:all, 是说,要生成所有的模块,如clientset,informers,listers等
第二个参数:xingej-go/xingej-k8s-spark/spark-operator-on-k8s-for-app/pkg/client 这个是你要生成代码的目录,目录的名称是client, 也有叫generated的
第三个参数:xingej-go/xingej-k8s-spark/spark-operator-on-k8s-for-app/pkg/apis 这个目录就是你自己创建的,里面至少包括types.go那个目录
第四个参数:"spark:v1beta1": 这个就是目录,spark是apis下的目录,v1beta1是spark下面的目录
脚本思路:
就是进入vendor下的code-generator目录,利用里面的generate-groups.sh脚本,生成代码。
其实跟git 上 参考实例中的脚本 思路大体一样的。
另外:
运行generate-groups.sh后,会在gopath目录的bin目录下,生成5个工具,如client-gen,deepcopy-gen等
就是利用这几个工具,来生成代码的。
5、如果要生成zz_generated.defaults.go文件的话,需要做两件事:
a、在自定义的类型上,多添加一个tag, 如// +k8s:defaulter-gen=true
b、修改generate-groups.sh脚本,添加对应的模块,如下面的形式:
其实,也是根据上面的if语句,参考写的。
当然,生成之后,zz_generated.defaults.go文件的内容,好像是不符合要求的,如下所示:
// Code generated by defaulter-gen. DO NOT EDIT. package v1beta1 import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // RegisterDefaults adds defaulters functions to the given scheme. // Public to allow building arbitrary schemes. // All generated defaulters are covering - they call all nested defaulters. func RegisterDefaults(scheme *runtime.Scheme) error { return nil }
生成的函数中,什么也没有做。
如果你觉得不能满足要求,也可以在函数RegisterDefaults中,自己添加必要的逻辑
6、遇到的主要问题:
Error: Failed executing generator: some packages had errors:
type k8s.io/apimachinery/pkg/runtime.Object in k8s.deepcopy-gen:interfaces tag of type k8s.io/apimachinery/pkg/runtime.Object is ont an interface, but: ""
问题描述,标签 k8s.io/apimachinery/pkg/runtime.Object 类型有问题,不是一个接口;
就是下面声明的地方
解决措施:
是因为路径问题,少添加了一个vendor
具体原因,也没有搞清楚(也不需要花费太多的时间),因为这是我第三次生成代码,前两次用的环境已经删除了,
添加上venddor就可以了,如下图所示:
,但是,会造成另一个问题,就是生成的文件zz_generated.deepcopy.go 中,导入包会报异常:
希望对其他人有所帮助
Kubernetes operator 如何根据自定义类型生成响应的代码的?
原文地址:http://blog.51cto.com/xingej/2120654