Kubernetes operator 如何根據自定義類型生成響應的代碼的?
是如何利用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 如何根據自定義類型生成響應的代碼的?