生成 CRD(自定义资源定义)
Kubebuilder 使用一个名为 controller-gen
的工具来生成实用代码和 Kubernetes 对象的 YAML,比如自定义资源定义(CustomResourceDefinitions)。
为此,它使用特殊的“标记注释“(以 // +
开头的注释)来指示有关字段、类型和包的附加信息。在自定义资源定义(CRD)的情况下,这些信息通常来自于你的 _types.go
文件。有关标记的更多信息,请参见 标记参考文档。
Kubebuilder 提供了一个 make
目标来运行 controller-gen 并生成 CRD:make manifests
。
当你运行 make manifests
时,应该可以在 config/crd/bases
目录下看到生成的 CRD。make manifests
还可以生成许多其他的构件—更多细节请查看 标记参考文档。
验证
CRD 支持使用 validation
部分中的 OpenAPI v3 架构 进行 声明式验证.
一般来说,验证标记可以附加到字段或类型上。如果您在定义复杂的验证、需要重用验证或需要验证切片元素,通常最好定义一个新类型来描述您的验证。
例如:
type ToySpec struct {
// +kubebuilder:validation:MaxLength=15
// +kubebuilder:validation:MinLength=1
Name string `json:"name,omitempty"`
// +kubebuilder:validation:MaxItems=500
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:UniqueItems=true
Knights []string `json:"knights,omitempty"`
Alias Alias `json:"alias,omitempty"`
Rank Rank `json:"rank"`
}
// +kubebuilder:validation:Enum=狮子;狼;龙
type Alias string
// +kubebuilder:validation:最小值=1
// +kubebuilder:validation:最大值=3
// +kubebuilder:validation:排除最大值=false
type Rank int32
附加打印机列
从 Kubernetes 1.11 开始,kubectl get
可以向服务器请求显示哪些列。对于自定义资源定义(CRD),这可以用于提供有用的特定类型信息,类似于内置类型所提供的信息。
显示的信息可以通过您的 CRD 上的 additionalPrinterColumns 字段 进行控制,该字段由 CRD 的 Go 类型上的 +kubebuilder:printcolumn
标记控制。
例如,在以下示例中,我们添加字段以显示有关骑士的信息,以及来自验证示例的等级和别名字段:
// +kubebuilder:printcolumn:name="别名",type=string,JSONPath=`.spec.alias`
// +kubebuilder:printcolumn:name="等级",type=integer,JSONPath=`.spec.rank`
// +kubebuilder:printcolumn:name="勇敢逃跑",type=boolean,JSONPath=`.spec.knights[?(@ == "罗宾爵士")]`,description="当危险抬起丑陋的头颅时,他勇敢地转身逃跑",priority=10
// +kubebuilder:printcolumn:name="年龄",type="日期",JSONPath=".metadata.creationTimestamp"
type Toy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ToySpec `json:"spec,omitempty"`
Status ToyStatus `json:"status,omitempty"`
}
子资源
从 Kubernetes 1.13 开始,CRDs 可以选择实现 /status
和 /scale
子资源。
一般建议您在所有具有状态字段的资源中使用 /status
子资源。
两个子资源都有相应的 标记.
状态
状态子资源是通过 +kubebuilder:subresource:status
启用的。当启用时,主资源的更新不会更改状态。同样,状态子资源的更新只能更改状态字段,不能更改其他内容。
例如:
// +kubebuilder:subresource:status
type Toy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ToySpec `json:"spec,omitempty"`
Status ToyStatus `json:"status,omitempty"`
}
规模
通过 +kubebuilder:subresource:scale
启用 scale 子资源。启用后,用户将能够使用 kubectl scale
命令来缩放您的资源。如果 selectorpath
参数指向标签选择器的字符串形式,则水平 Pod 自动扩缩器 (HorizontalPodAutoscaler) 将能够对您的资源进行自动扩缩。
例如:
type CustomSetSpec struct {
Replicas *int32 `json:"replicas"`
}
type CustomSetStatus struct {
Replicas int32 `json:"replicas"`
Selector string `json:"selector"` // this must be the string form of the selector
}
// +kubebuilder:subresource:status
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector
type CustomSet struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec CustomSetSpec `json:"spec,omitempty"`
Status CustomSetStatus `json:"status,omitempty"`
}
多个版本
从 Kubernetes 1.13 开始,您可以在 CRD 中定义多个版本的 Kind,并使用一个 webhook 在它们之间进行转换。
有关此过程的更多详细信息,请参见 多版本教程。
默认情况下,Kubebuilder 禁用了为 CRD 中的 Kind 不同版本生成不同的验证,以便与旧版本的 Kubernetes 兼容。
如果使用 v1beta CRD,您需要将 makefile 中的 CRD_OPTIONS ?= "crd:trivialVersions=true,preserveUnknownFields=false
这一行更改为 CRD_OPTIONS ?= crd:preserveUnknownFields=false
;如果使用 v1(推荐),则更改为 CRD_OPTIONS ?= crd
。
然后,您可以使用 +kubebuilder:storageversion
标记 来指示 API 服务器应该使用的用于存储数据的 GVK。
在内部实现上
Kubebuilder 自动生成用于运行 controller-gen
的 make 规则。该规则会使用 Go 模块通过 go install
自动安装 controller-gen,如果它不在您的路径中。
如果你想查看 controller-gen
的具体操作,也可以直接运行它。
每个 controller-gen 的“生成器“都由 controller-gen 的一个选项控制,使用与标记相同的语法。controller-gen 还支持不同的输出“规则“,以控制输出的方式和去向。请注意 manifests
制作规则(略微简化,仅生成 CRD):
# 为 CRD 生成清单
manifests: controller-gen
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=配置/CRD/基础
它使用 output:crd:artifacts
输出规则来指示与 CRD 相关的配置(非代码)工件应最终放在 config/crd/bases
中,而不是 config/crd
。
要查看包括生成器在内的所有 controller-gen
选项,请运行
$ controller-gen -h
或者,欲了解更多详情:
$ controller-gen -hhh