本章参考operator-sdk的tutorial编写一个memcache的operator
1 功能介绍
memcache operator创建成功后,可以通过如下yaml来创建进一个memcache 服务
apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
name: memcached-sample
spec:
size: 3
根据yaml创建memcached
kubectl create -f memcached.yaml
创建成功后,可以通过kubectl 查看memcached的状态信息
# 查看是否存在对应资源信息
tingshuai.yts@B-5BBCMD6M-2026 ~ % kubectl get memcached
NAME AGE
memcached-sample 34m
# 查看memcached详细信息
tingshuai.yts@B-5BBCMD6M-2026 ~ % kubectl get memcached memcached-sample -o yaml
apiVersion: cache.example.com/v1alpha1
kind: Memcached
metadata:
creationTimestamp: "2022-02-24T07:16:33Z"
generation: 2
name: memcached-sample
namespace: default
resourceVersion: "3385066472"
selfLink: /apis/cache.example.com/v1alpha1/namespaces/default/memcacheds/memcached-sample
uid: 12f26a9f-fc34-492e-a30f-bc17266052aa
spec:
size: 4
status:
nodes:
- memcached-sample-9b765dfc8-w6l26
- memcached-sample-9b765dfc8-7cwpl
- memcached-sample-9b765dfc8-kxnmd
- memcached-sample-9b765dfc8-hsrqd
memcached operator主要工作是根据yaml中的描述spec来创建deployment,如下所示:
tingshuai.yts@B-5BBCMD6M-2026 ~ % kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
memcached-sample 4/4 4 4 37m
2 整体流程
编写一个operator一般分为如下几个步骤:
- 开发环境搭建
- 通过operator sdk创建operator project
- 通过operator sdk创建API和controller 框架代码
- 编写API和controller业务代码
- 调试执行
3 环境搭建
开发controller依赖如下环境,由于篇幅有限,本文仅列举依赖的内容,安装方式读者自行百度即可
- golang
- operator-sdk
- kubectl 和k8s对应的config
4 创建operator project
通过operator-sdk init命令创建controller的project
mkdir -p $HOME/projects/memcached-operator
cd $HOME/projects/memcached-operator
# we'll use a domain of example.com
# so all API groups will be <group>.example.com
operator-sdk init --domain example.com --repo github.com/example/memcached-operator
operator-sdk init的帮助文档信息如下:
% operator-sdk init --help
Initialize a new project including the following files:
- a "go.mod" with project dependencies
- a "PROJECT" file that stores project configuration
- a "Makefile" with several useful make targets for the project
- several YAML files for project deployment under the "config" directory
- a "main.go" file that creates the manager that will run the project controllers
Usage:
operator-sdk init [flags]
Examples:
# Initialize a new project with your domain and name in copyright
operator-sdk init --plugins go/v3 --domain example.org --owner "Your name"
# Initialize a new project defining an specific project version
operator-sdk init --plugins go/v3 --project-version 3
Flags:
--component-config create a versioned ComponentConfig file, may be 'true' or 'false'
--domain string domain for groups (default "my.domain")
--fetch-deps ensure dependencies are downloaded (default true)
-h, --help help for init
--license string license to use to boilerplate, may be one of 'apache2', 'none' (default "apache2")
--owner string owner to add to the copyright
--project-name string name of this project
--project-version string project version (default "3")
--repo string name to use for go module (e.g., github.com/user/repo), defaults to the go package of the current working directory.
--skip-go-version-check if specified, skip checking the Go version
Global Flags:
--plugins strings plugin keys to be used for this subcommand execution
--verbose Enable verbose logging
5 创建API和controller框架代码
执行下面的命令会创建api和controller的框架代码,然后我们在框架代码的基础上按照需求填写业务逻辑代码即可:
- api代码会在api/v1alpha1/memcached_types.go
- controller代码会在controllers/memcached_controller.go
$ operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource --controller
6 编写API
6.1 api 定义
创建完api后代码,operator sdk生成的主要代码如下:
// MemcachedSpec defines the desired state of Memcached
type MemcachedSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of Memcached. Edit memcached_types.go to remove/update
Foo string `json:"foo,omitempty"`
}
// MemcachedStatus defines the observed state of Memcached
type MemcachedStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// Memcached is the Schema for the memcacheds API
type Memcached struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MemcachedSpec `json:"spec,omitempty"`
Status MemcachedStatus `json:"status,omitempty"`
}
一般来说,我们需要修改spec和status的定义,来满足我们的业务需求。
spec更改如下:
- 添加Size字段,用来定义memcache 副本的个数
- +kubebuilder:validation:Minimum=0 是marker comments;operator-sdk会根据marker comments的描述来生成代码。本例中marker comments的作用是生成api定义的校验代码,如果spec的小于0,则validation检查会失败(下一节会对marker comments进一步介绍)
// MemcachedSpec defines the desired state of Memcached
type MemcachedSpec struct {
//+kubebuilder:val