怎么开发 Kubernetes Custom Resource Definitions (CRD)

Kubernetes 自定义控制器用于处理核心资源。然而,这些核心资源是不可编辑的。在许多情况下,您会希望引入您自己的资源,并且您可以完全控制它。 CRD(自定义资源定义)正是为此而设计的。创建的每个 CRD 资源都有很多样板代码。为了避免这种情况,可以使用 k8s.io/code-generator 自动生成 CRD 工作所需的所有informaer程序、listers程序等。

kubernetes/code-generator is synced from k8s.io/code-generator. Code changes are made in that location, merged into k8s.io/kubernetes and later synced back to kubernetes/code-generator.

下面我们演示怎么利用Kubernetes code-generator快速创建kubernetes CRD资源。

首先,假设我们要创建一个属于Group foo.com的 CRD,并且规范中有一个名为Kind “HelloType”的类型,其中包含“message”字段:hello world.如下所示:
# Definition
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:  
  name: hellotypes.foo.com
spec:  
  group: foo.com  
  version: v1
  scope: Namespaced  
  names:    
    kind: HelloType   
    shortNames: ht
    plural: hellotypes
    singular: hellotype# HelloType
---
apiVersion: foo.com/v1
kind: HelloType 
metadata: 
  name: superman-hello
spec:
  message: hello world
生成此 CRD 资源代码,涉及2个步骤:
   使用正确的代码生成器tag编写type定义代码
   运行代码生成器自动创建客户代码,其中包括客户资源的clientset, informers和listers。

1、定义CRD type

创建一个名为 code-generator-demo 目录。我们将创建的框架文件的布局如下:
pkg/
├── apis
    └── foo
        └── v1
            ├── doc.go
            ├── register.go
            └── types.go
foo 是正在定义的新资源组,其下所有类型都属于foo.com。
如果资源版本低于1.0.0,则v1下的所有代码都可以放在foo目录下。任何其他版本,按照约定,在 foo 下创建一个单独的目录,例如 v1、v1beta1、v2。在此示例中,我们将为自定义资源创建版本v1。
foo/v1/doc.go

// +k8s:deepcopy-gen=package
// +k8s:defaulter-gen=TypeMeta
// +groupName=foo.com

package v1

另外两个标签表示为 struct TypeMeta 生成默认值并将组名称设置为“foo.com”。
foo/v1/types.go

package v1

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

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

// HelloType is a top-level type
type HelloType struct {
    metav1.TypeMeta `json:",inline"`
    // +optional
    metav1.ObjectMeta `json:"metadata,omitempty"`
    
    // +optional
    Status HelloTypeStatus `json:"status,omitempty"`
    // This is where you can define
    // your own custom spec
    Spec HelloSpec `json:"spec,omitempty"`
}

// custom spec
type HelloSpec struct {
    Message string `json:"message,omitempty"`
}

// custom status
type HelloTypeStatus struct {
    Name string
}

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

// no client needed for list as it's been created in above
type HelloTypeList struct {
    metav1.TypeMeta `json:",inline"`
    // +optional
    metav1.ListMeta `son:"metadata,omitempty"`

    Items []HelloType `json:"items"`
}

创建自定义类型“HelloType”。我们还定义自定义状态和规格。任何自定义类型还必须具有复数结构。在本例中,我们有“HelloTypeList”。

+可选表示该字段是可选的。该字段的数据可以为空。

foo/v1/register.go

package v1

import (
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/apimachinery/pkg/runtime/schema"
)

// Define your schema name and the version
var SchemeGroupVersion = schema.GroupVersion{
    Group:   "foo.com",
    Version: "v1",
}

var (
    SchemeBuilder      runtime.SchemeBuilder
    localSchemeBuilder = &SchemeBuilder
    AddToScheme        = localSchemeBuilder.AddToScheme
)

func init() {
    // We only register manually written functions here. The registration of the
    // generated functions takes place in the generated files. The separation
    // makes the code compile even when the generated files are missing.
    localSchemeBuilder.Register(addKnownTypes)
}

// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
    return SchemeGroupVersion.WithResource(resource).GroupResource()
}

// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
    scheme.AddKnownTypes(
        SchemeGroupVersion,
        &HelloType{},
        &HelloTypeList{},
    )

    scheme.AddKnownTypes(
        SchemeGroupVersion,
        &metav1.Status{},
    )

    metav1.AddToGroupVersion(
        scheme,
        SchemeGroupVersion,
    )

    return nil
}

好了,上面代码准备就绪,执行Go Modules。

go mod init code-generator-demo
go mod tidy

generate-groups.sh all "code-generator-demo/pkg/client" "code-generator-demo/pkg/apis" foo:v1

准备Dockerfile文件:

上述选项之一完成代码生成后,您的 pkg 文件夹结构将类似于:
pkg/
├── apis
│   └── foo
│       ├── register.go
│       └── v1
└── client
    ├── clientset
    │   └── versioned
    ├── informers
    │   └── externalversions
    └── listers
        └── foo
新创建的client文件夹包含所有生成的代码,类型的深层复制代码也将驻留在类型旁边的 v1 中。
恭喜您,您可以使用生成的clientset、自定义控制器的informers,就像通​​常使用kubernetes内部核心资源一样使用。

Reference:

  1. Kubernetes Custom Resource
  2. kubernetes/code-generator
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值