【kubernetes/k8s概念】code-generator 分析

    github: https://github.com/kubernetes/code-generator

WHY?

    client-go 封装了对 k8s 内置资源的一些常用操作,包括了 clients/listers/informer 等对象和函数,通过 Watch 或者 Get List 获取对应的 Object,通过 Cache,可以避免对 APIServer 请求的压力

    对于自己创建的 CRD,不能直接使用这些代码。

    通过 code-generator,提供自己的 CRD 相关的结构体,生成 client-go 中类似的代码,方便编写自己的控制器

    在 CustomResourceDefinition 上下文创建原生的,版本的 client informer lister

 

【kubernetes/k8s概念】code-generator 分析_第1张图片

      controller的详细设计引入:https://twitter.com/resouer/status/1009996649832185856

 

code-generator 生成器

     代码 code-generator/cmd 目录下,包括如下:

  • client-gen
  • conversinon-gen
  • deepcopy-gen
  • go-go-protobuf
  • import-boss
  • informer-gen
  • lister-gen
  • openapi-gen
  • register-gen
  • set-gen

 

1. 创建自定义 CRD

  其中 pkg/apis是固定的  

  apps是groupname,比如 apps.k8s.io/v1

  v1 是 version

  doc.go types.go register.go 都是自己写的,或者使用 operator-sdk 生成,在填充

    $ cat apis/apps/v1/doc.go 

// Package v1 contains API Schema definitions for the apps v1 API group
// +k8s:deepcopy-gen=package
// +groupName=apps.krome.io

 

    $ cat apis/apps/v1/statefulset_types.go 

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// Statefulset is the Schema for the statefulsets API
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=statefulsets,scope=Namespaced
type Statefulset struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   StatefulsetSpec   `json:"spec,omitempty"`
    Status StatefulsetStatus `json:"status,omitempty"`
}

 

  +[=value] 格式注释,可以控制代码生成器的一些行为

  • +genclient: 为这个 package 创建 client
  • +genclient:noStatus: 当创建 client 时,不存储 status
  • +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object: 为结构体生成 deepcopy 的代码,实现了 runtime.Object 的 Interface

 

    对于自定义资源结构还需要一些接口,例如 AddToScheme 和 Resource,这些函数负责将结构体注册到 schemes 中去。

   $ cat apis/apps/v1/register.go 

var (
	// SchemeGroupVersion is group version used to register these objects
	SchemeGroupVersion = schema.GroupVersion{Group: "apps.krome.io", Version: "v1"}

	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
	// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
	SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)

	// AddToScheme is a global function that registers this API group & version to a scheme
	AddToScheme = SchemeBuilder.AddToScheme
)

func Resource(resource string) schema.GroupResource {
	return SchemeGroupVersion.WithResource(resource).GroupResource()
}

func Kind(kind string) schema.GroupKind {
	return SchemeGroupVersion.WithKind(kind).GroupKind()
}

func addKnownTypes(scheme *runtime.Scheme) error {
	scheme.AddKnownTypes(
		SchemeGroupVersion,
		&Statefulset{},
		&StatefulsetList{},
	)

	// register the type in the scheme
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
	return nil
}

 

2. 生成代码

   执行 $GOPATH/src/k8s.io/code-generator/generate-groups.sh all \

            xxxxxxx/pkg/client \

            xxxxxxx/pkg/apis \

            apps:v1

   或者像 sample-controller 写一个脚本执行 hack/update-code-gen.sh

   可以生成如下代码:

【kubernetes/k8s概念】code-generator 分析_第2张图片roll

   在添加自己的 controller,可以使用 operator-sdk add controller 生成,在写文章分析

 

3. 生成器 tag

    3.1 client-gen

     在 pkg/apis/${GROUP}/${VERSION}/types.go 中使用,使用 // +genclient 标记生成客户端
     如果资源不是命名空间范围的(例如PersistentVolume),则附加 // + genclient:nonNamespaced标记 

  • // +genclient - 生成默认的客户端函数(create, update, delete, get, list, update, patch, watch以及是否生成updateStatus取决于.Status字段是否存在)
  • // +genclient:nonNamespaced - 在没有名称空间的情况下生成
  • // +genclient:onlyVerbs=create,get - 指定的函数被生成
  • // +genclient:skipVerbs=watch - 生成watch以外所有的函数.
  • // +genclient:noStatus - 即使.Status字段存在也不生成updateStatus函数

参考: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/generating-clientset.md

 

参考:

    https://github.com/kubernetes/code-generator

    https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/generating-clientset.md

你可能感兴趣的:(kubernetes)