利用codegenerator收集k8s资源并实时监控资源变化

code-generator是用于实现kubernetes风格API类型的Golang代码生成器。可以利用该工程自动生成指定k8s资源的clientset、informers和listers API接口。这三种类型的API分别可以用于:

  • deepcopy-gen 为每个方法 func (t* T)提供一个深度拷贝函数,一般不直接调用,能生成这个文件zz_generated.deepcopy.go就行
  • clientset 有资源的Create、Update、UpdateStatus、Delete、Get、List、Watch、Patch等接口,可以方便的对指定资源进行CRUD操作。
  • informers 可以针对资源的Add事件、Update事件和Delete事件定义handler函数。典型的处理是把事件用key索引放入workqueue中,然后出队用syncHandler函数逐个处理事件。
  • lister 用于获取一系列或者一个具有某个属性值的资源。(这里和clientset的Get有啥区别呢?为GET和LIST请求提供只读缓存层?)

如何使用code-generator来生成API代码

可以参考工程:

bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" \
  k8s.io/sample-controller/pkg/generated k8s.io/sample-controller/pkg/apis \
  samplecontroller:v1alpha1 \
  --output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
  --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt

其中

  • k8s.io/sample-controller/pkg/generated是生成的文件目录名
  • k8s.io/sample-controller/pkg/apis是资源定义目录(是需要人工填写资源名称、字段等),
  • 一般k8s.io/sample-controller/pkg/apis是工程工作目录,注意这里的层级要和下面的output-base "$(dirname "${BASH_SOURCE[0]}")/../../.. 相一致,否则会把文件自动生成在基于output-base的generated目录下。
    以上面的例子来看,生成的generated的文件夹应该是在当前codegen.sh所在目录的../../../k8s.io/sample-controller/pkg下面,如果实在找不到自动生成的文件就到工程的根目录下用find命令查找。
    另外一个需要注意的地方是在填写pkg/apis目录下的types.go文件时,不要随意更改注释代码和空行,否则可能会无法生成预期代码。实际上code-gen就是靠这些tag生成代码的,这些分为globalTag和localTag
GlobalTag
globaltag在pkg/apis/<apigroup>/<version>/doc.go文件中定义:
// +k8s:deepcopy-gen=package,register
// +groupName=example.com
package v1
第一行表示It tells deepcopy-gen to create deepcopy methods by default for every type in that package. 如果不需要深拷贝,则如下定义
// +k8s:deepcopy-gen=false
第二行// +groupName=example.com defines the fully qualified API group name.

LocalTag
localtag 是直接写在API type上或写在其上的注释块里。例如:
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient:noStatus
// +genclient:nonNamespaced

// +genclient:noVerbs
// +genclient:onlyVerbs=create,delete
// +genclient:skipVerbs=get,list,create,update,patch,delete,deleteCollection,watch
// +genclient:method=Create,verb=create,result=k8s.io/apimachinery/pkg/apis/meta/v1.Status
第一行表示生成此类型的client,第二行表示用k8s1.8版本以上的runtime.Object 来实现深拷贝。第三行表示不生成UpdateStatus 方法。第四行表示是cluster-wide 资源。后面的几行都是关于client提供的HTTP methods,最后一行的意思是写这个标记的类型将只被创建,不会返回API类型本身,而是返回metav1.Status。对于CustomResources来说,这没有多大意义,但是对于用golang编写的用户提供的API服务器来说,这些资源可以存在,并且它们在实践中确实存在,例如,在OpenShift API中。

github上sample-controller这个例子给出了编译方法,监控资源变化的函数编写以及资源创建的示例,还有资源status修改的方法,基本上你想要用到的功能,这个例子都给出了。
最后,要注意的是,创建crd资源时,kubebuilder新版生成的yaml是以apiextensions.k8s.io/v1打头的资源类型,按照这个模板生成的资源,无法用sample-controller中的updateStatus示例更新资源状态。而以apiextensions.k8s.io/v1beta1打头的crd资源模板是可以更新资源状态的。可以按照sample-controller/artifacts/examples目录下的示例来填写资源模板。

参考文献

原文地址:https://www.cnblogs.com/janeysj/p/15598436.html