kubernetescode-generator使用

博客 动态
0 126
优雅殿下
优雅殿下 2022-06-20 22:00:45
悬赏:0 积分 收藏

kubernetes code-generator使用

目录
  • Overview
    • Prerequisites
    • CRD
    • code-generator
    • 编写代码模板
    • code-generator Tag说明
  • 开始填写文件内容
      • type.go
      • doc.go
      • register.go
      • 生成所需文件

Overview

Kubernetes中提供了多种自定义控制器的方式:

  • code-generator
  • kubebuilder
  • Operator

Controller 作为CRD的核心,这里将解释如何使用 code-generator 来创建自定义的控制器,作为文章的案例,将完成一个 Firewalld Port 规则的控制器作为描述,通过 Kubernetes 规则来生成对应节点上的 iptables规则。

Prerequisites

CRD

apiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata:  name: ports.firewalld.fedoraproject.orgspec:  group: firewalld.fedoraproject.org  scope: Namespaced  names:    plural: ports    singular: port    kind: PortRule    shortNames:     - fp  versions:  - name: v1    served: true    storage: true    schema:      openAPIV3Schema:        type: object        properties:          spec:            type: object            properties:              name:                type: string              port:                type: integer              host:                type: string              isPermanent:                type: boolean

code-generator

需要预先下载 code-generator 。因为这个工具不是必需要求的。

注意,下载完成后需要将代码库的的分支更改为你目前使用的版本,版本的选择与client-go类似,如果使用master分支,会与当前的 Kubernetes 集群不兼容。

git clone https://github.com/kubernetes/code-generatorcd code-generator; git checkout {version}  # ex. v0.18.0

编写代码模板

要想使用 code-generator 生成控制器,必须准备三个文件 doc.go , register.go , types.go

  • doc.go 中声明了这个包全局内,要使用生成器的tag
  • register.go 类似于kubernetes API,是将声明的类型注册到schema中
  • type.go 是需要具体声明对象类型

code-generator Tag说明

在使用 code-generator 时,就需要对 code-generator 的tag进行了解。code-generator 的tag是根据几个固定格式进行定义的,tag是 +k8s: + conversion 的组合,在仓库中 cmd 中的 *-gen* 文件夹就代表了 conversion 的替换位置。

  • 对于 client-gen的tag 参数可以在 code-generator\cmd\client-gen\generators\util\tags.go
  • 对于其他类型的使用方法,例如 deepcopy-gen ,可以在包 main.go中看注释说明
    • +k8s:openapi-gen=true:启用一个生成器

注:最终准备完成的文件( doc.go , register.go , types.go)应该为:apis/example.com/v1 这种类型的

需要遵循的是,将这些文件放在 <version> 目录中,例如 v1 。这里 v1, v1alpha1, 根据自己需求定义。

开始填写文件内容

type.go

package v1import (	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1")// +genclient// +genclient:noStatus// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Objecttype Port struct {	metav1.TypeMeta `json:",inline"`	// Standard object metadata.	// +optional	metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`	// Specification of the desired behavior of the Deployment.	// +optional	Spec PortSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`}// +k8s:deepcopy-gen=falsetype PortSpec struct {	Name        string `json:"name"`	Host        string `json:"host"`	Port        int    `json:"port"`	IsPermanent bool   `json:"isPermanent"`}// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Objecttype PortList struct {	metav1.TypeMeta `json:",inline"`	// +optional	metav1.ListMeta `json:"metadata,omitempty"`	Items []Port `json:"items"`}

doc.go

// +k8s:deepcopy-gen=package// +k8s:protobuf-gen=package// +k8s:openapi-gen=true// +groupName=firewalld.fedoraproject.orgpackage v1 // import "k8s.io/api/firewalld/v1"

register.go

这里是从 k8s.io/api 里任意一个复制的,例如 k8s.io/api/core/v1/register.go

package v1import (	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"	"k8s.io/apimachinery/pkg/runtime"	"k8s.io/apimachinery/pkg/runtime/schema")// GroupName is the group name use in this packageconst GroupName = "firewalld.fedoraproject.org"// SchemeGroupVersion is group version used to register these objectsvar SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}// Resource takes an unqualified resource and returns a Group qualified GroupResourcefunc Resource(resource string) schema.GroupResource {	return SchemeGroupVersion.WithResource(resource).GroupResource()}var (	// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.	// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.	SchemeBuilder      = runtime.NewSchemeBuilder(addKnownTypes)	localSchemeBuilder = &SchemeBuilder	AddToScheme        = localSchemeBuilder.AddToScheme)// Adds the list of known types to the given scheme.func addKnownTypes(scheme *runtime.Scheme) error {	scheme.AddKnownTypes(SchemeGroupVersion,		&Port{},		&PortList{},	)	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)	return nil}

生成所需文件

使用 code-generator 时,实际上就是使用这个库中的脚本 generate-groups.sh ,该脚本又四个参数

  • 第一个参数:使用那些生成器,就是 *.gen,用逗号分割,all表示使用全部
  • 第二个参数:client(client-go中informer, lister等)生成的文件存放到哪里
  • 第三个参数:api(api结构,k8s.io/api/) 生成的文件存放到哪里,可以和定义的文件为一个目录
  • 第四个参数:定义group:version
  • -output-base:输出包存放的根目录
  • -go-header-file:生成文件的头注释信息,这个是必要参数,除非生成失败

注:对于参数二,三,与-output-base,指定的路径,这里可以使用相对路径也可以使用go.mod中的定义的包名,对于使用相对路径而言,生成的文件中的import也将会为 "../../" 的格式

一个完整的示例

../code-generator/generate-groups.sh all \	../code-controller/client \	../code-controller/apis  \	firewalld:v1 \	--output-base ../code-controller/ \	--go-header-file ../code-generator/hack/boilerplate.go.txt

Reference

CRD Programming

posted @ 2022-06-20 21:38 Cylon 阅读(11) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员