kubebuilder是一个快速实现kubernetes Operator的框架,通过kubebuilder我们能够快速定义CRD资源和实现controller逻辑。我们可以简单地将operator理解为:operator=crd+controller。
kubebuilder自身携带了两个工具:controller-runtime与controller-tools,我们可以通过controller-tools来生成大部分的代码,从而我们可以将我们的主要精力放置在CRD的定义和编写controller的reconcile逻辑上。所谓的reconcile,即调谐,是指将资源的status通过一系列的操作调整至与定义的spec一致。
从整体来看,通过kubebuilder来实现operator大致可分为以下步骤:
我们以创建一个mysql的operator来作为最佳实践的例子。我们期望这个mysql-operator能够实现deployment创建和更新,以及mysql实例数的扩缩容。
确保实践环境中拥有以下组件:
curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
kubebuilder init --domain tutorial.kubebuilder.io
创建kubebuilder项目之前必须要先有go project,否则会报错。
创建完成之后,我们可以看到此时项目中多了许多的代码,其中:
kubebuilder create api --group batch --version v1 --kind Mysql
Create Resource [y/n]
y
Create Controller [y/n]
y
编写CRD资源的定义主要是在mysql_types.go文件中,编写controller逻辑主要是在mysql_controller.go文件中。
我们首先编写CRD的定义。我们简单地用一个yaml文件来描述我们所期望的定义:
apiVersion: batch.tutorial.kubebuilder.io/v1
kind: Mysql
metadata:
name: mysql-sample
spec:
replicas: 1
image: flyer103/mysql:5.7
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
我们需要在mysql_types.go文件中定义我们的spec和status。
// MysqlSpec defines the desired state of Mysql
type MysqlSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
Name string `json:"name,omitempty"`
Image string `json:"image,omitempty"`
Command []string `json:"command,omitempty" protobuf:"bytes,3,rep,name=command"`
// +optional
//+kubebuilder:default:=1
//+kubebuilder:validation:Minimum:=1
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
}
我们在这里针对code重新定义了string类型。
type MySqlCode string
const (
SuccessCode MySqlCode = "success"
FailedCode MySqlCode = "failed"
)
// MysqlStatus defines the observed state of Mysql
type MysqlStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Code MySqlCode `json:"code,omitempty"`
Replicas int32 `json:"replicas"`
ReadyReplicas int32 `json:"readyReplicas"`
}
像 //+kubebuilder:object:root
这样的以//+
开头的注释在kubebuilder
中被称为元数据标记,这些标记的作用就是告诉controller-tools生成额外的信息。
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.labelSelector
//+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.code",description="The phase of game."
//+kubebuilder:printcolumn:name="DESIRED",type="integer",JSONPath=".spec.replicas",description="The desired number of pods."
//+kubebuilder:printcolumn:name="CURRENT",type="integer",JSONPath=".status.replicas",description="The number of currently all pods."
//+kubebuilder:printcolumn:name="READY",type="integer",JSONPath=&