crd demo

创建

1
2
3
4
5
6
7
8
mkdir -p crddemo
cd crddemo
go mod init crddemo
# domain for groups (default "my.domain") => go
kubebuilder init --domain my.domain
#  groups ("webapp.my.domain") 
kubebuilder create api --group webapp --version v1 --kind Guestbook
 

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.
├── Dockerfile
├── Makefile
├── PROJECT
├── README.md
├── api
│   └── v1
├── bin
│   └── controller-gen
├── config
│   ├── crd
│   ├── default
│   ├── manager
│   ├── prometheus
│   ├── rbac
│   └── samples
├── controllers
│   ├── guestbook_controller.go
│   └── suite_test.go
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
└── main.go

配置使用

config/ 目录下获得启动配置,它只包含在集群上启动控制器所需的Kustomize YAML 定义,一旦我们开始编写controller,它还将保存我们的 CustomResourceDefinitions、RBAC 配置和 WebhookConfigurations

config/default 包含 Kustomize base 用于标准配置中启动controller。

Each other directory contains a different piece of configuration, refactored out into its own base:

  • config/manager: 启动controllers as pods in the cluster
  • config/rbac: 通过RABC service account控制controllers在集群里面的权限

main

main方法主要功能

  • set up some basic flags for metrics(传参)
  • 实例化manager, 跟踪所有controllers,shared caches,clients to the API server(we tell the manager about our Scheme)
  • The manager 会一直运行直到收到 graceful shutdown signal,让controllers and webhooks运行。

create api

go schema 对应CRD,controllers管理操作CR(CRD 的实例化),这种情况下, api/v1/ 目录被创建

我们为种类的 Spec 和 Status 定义类型。Kubernetes 通过协调所需状态 ( Spec) 与实际集群状态(其他对象的 Status)和外部状态来发挥作用,然后记录它观察到的内容 ( Status)。因此,每个功能对象都包含规范和状态。一些类型,比如 ConfigMap不遵循这种模式,因为它们不编码所需的状态,但大多数类型都这样做。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// CronJobSpec defines the desired state of CronJob
type CronJobSpec struct {
    // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
    // Important: Run "make" to regenerate code after modifying this file
}

// CronJobStatus defines the observed state of CronJob
type CronJobStatus struct {
    // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
    // Important: Run "make" to regenerate code after modifying this file
}

接下来,我们定义对应于实际 Kinds 的类型,CronJob并且CronJobList. CronJob是我们的根类型,并描述了CronJob种类。像所有 Kubernetes 对象一样,它包含 TypeMeta(描述 API 版本和种类),还包含ObjectMeta,它包含名称、命名空间和标签等内容。

一般来说,我们从不修改其中任何一个——所有修改都在 Spec 或 Status 中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

// CronJob is the Schema for the cronjobs API
type CronJob struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   CronJobSpec   `json:"spec,omitempty"`
    Status CronJobStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// CronJobList contains a list of CronJob
type CronJobList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata,omitempty"`
    Items           []CronJob `json:"items"`
}

最后,我们将 Go 类型添加到 API 组。这允许我们将此 API 组中的类型添加到任何Scheme中。

1
2
3
func init() {
    SchemeBuilder.Register(&CronJob{}, &CronJobList{})
}

int32 and int64 for integers, and resource.Quantity for decimals.

我们使用另一种特殊类型:metav1.Time. 它的功能与 相同time.Time,只是它具有固定的、可移植的序列化格式。

controllers

controllers通过RABC控制集群权限。

Reconcile actually performs the reconciling for a single named object. 我们的请求只有一个名称,但我们可以使用client从缓存中获取该对象。

我们返回一个空的结果并且没有错误,这向控制器运行时表明我们已经成功地协调了这个对象并且不需要再试一次,直到有一些变化。

webhook

  • set unset field in spec (–defaulting)
  • reject objects (–programmatic-validation)
1
2
kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --programmatic-validation