Kubernetes Operator 开发教程(一)
简介:以前开发Operator是以部分开发身份参与,因此想通过一个完整的实例来梳理Operator完整的开发逻辑,因此这次想采用“统一权限控制中心”来定义这个资源,主要控制了k8s的sa账号和harbor账号,以及预留其他口可供统一的权限控制。
1. 概述
我们将 CRD, Controller, Webhook 三者合起来叫 Operator。一个 Operator 工程一般必须包含 CRD 和 Controller,Admission 是可选的。这次我们主要采用KubeBuilder来构建实现Operator。
2. 名词解释
GVK:Group,Version,Kind
GVR: Group,Version,Resource
API Group & Versions(GV):
API Group是相关API功能的集合,每个Group拥有一或多个Versions,用于接口的演进。Kinds & Resources:
每个GV都包含多个API类型,称为Kinds,在不同的Versions之间同一个Kind定义可能不同, Resource是Kind的对象标识(resource type),一般来说Kinds和Resources是1:1的,比如pods Resource对应Pod Kind,但是有时候相同的Kind可能对应多个Resources,比如Scale Kind可能对应很多Resources:deployments/scale,replicasets/scale,对于CRD来说,只会是1:1的关系
- Scheme:
每一组Controllers都需要一个Scheme,提供了Kinds与对应Go types的映射。
Manager
Kubebuilder的核心组件,具有3个职责:
负责运行所有的Controllers
初始化共享caches,包含listAndWatch功能
初始化clients用于与Api Server通信;
Cache:
Kubebuilder的核心组件,负责在Controller进程里面根据Scheme同步Api Server中所有该Controller关心GVKs的GVRs,其核心是GVK -> Informer的映射,Informer会负责监听对应GVK的GVRs的创建/删除/更新操作,以触发Controller的Reconcile逻辑。
- Clients:
在实现Controller的时候不可避免地需要对某些资源类型进行创建/删除/更新,就是通过该Clients实现的,其中查询功能实际查询是本地的Cache,写操作直接访问Api Server。 - Index:
由于Controller经常要对Cache进行查询,Kubebuilder提供Index utility给Cache加索引提升查询效率。 - Finalizer:
在一般情况下,如果资源被删除之后,我们虽然能够被触发删除事件,但是这个时候从Cache里面无法读取任何被删除对象的信息,这样一来导致很多垃圾清理工作因为信息不足无法进行,K8s的Finalizer字段用于处理这种情况。在K8s中,只要对象ObjectMeta里面的Finalizers不为空,对该对象的delete操作就会转变为update操作,具体说就是update deletionTimestamp 字段,其意义就是告诉K8s的GC“在deletionTimestamp这个时刻之后,只要Finalizers为空,就立马删除掉该对象”。所以一般的使用姿势就是在创建对象时把Finalizers设置好(任意string),然后处理DeletionTimestamp不为空的update操作(实际是delete),根据Finalizers的值执行完所有的pre-delete hook(此时可以在Cache里面读取到被删除对象的任何信息)之后将Finalizers置为空即可。 - OwnerReference:
K8s GC在删除一个对象时,任何ownerReference是该对象的对象都会被清除,与此同时,Kubebuidler支持所有对象的变更都会触发Owner对象controller的Reconcile方法。
3. List-Watch机制
4. CRD规范
4.1 命名规范
CRD 的全名是必须符合如下的命名规范: ${Kind}.${Group}.${Organization}.kubeone.alibaba-inc.com
。其中:
${Organization}
为仓库的 git Group,即 团队名英文简称。如 jiayi${Group}
必须是一种功能类别,如ops
,apps
,auth
等。尽量用精简的单个英语单词的方式传达你的 CRD 属于的“类别”。组成的字母必须都是小写${Kind}
即为 CRD 真正的短名字,用精简的单个或多个英文单词的拼接来命名真正的 CRD 短名字。如AdvancedDeployment
,NoteBook
等。使用大驼峰命名法(首字母也是大写,即 UpperCamelCase)。- alipay.com 是固定的,即 Company Name Domain。
- 目前对于 CRD 版本转化不太友好,统一使用
v1
。
4.2 Spec, Status 规范
- 用命令在
apis
包下生成 CRD Types 之后,请不要随意修改apis
里的结构体、命名规则、以及注释。 - 只能、也只需要修改
${Kind}_types.go
文件里 Spec 和 StatusSpec 结构体里的内容。 - Spec 和 StatusSpec 里的字段都必须是 Public 的,也就是字段名首字母是大写。
- 每个字段,都应该写上 JSON Tag,JSON Tag 必须使用 小驼峰命名法,即 LowerCamelCase。
- 如果字段允许为空,JSON Tag 记得带上
omitempty
。StatusSpec 的字段一般都是允许为空的!例子:
5. kubebuilder的搭建和使用
5.1安装
# download kubebuilder and install locally.
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 completion <bash|fish|powershell|zsh>
5.2 创建项目
kubebuilder init --domain jiayi.com --repo jiayi.com/auth-center
5.3 创建api
kubebuilder create api --group auth --version v1 --kind AuthCenter
如果你按y创建资源[y/n]和创建控制器[y/n],那么这将创建文件api/v1/authcenter_types。去API定义的地方和内部/controllers/authcenter_controller。转到为这种类型(CRD)实现协调业务逻辑的地方。
参考资料
- kubebuilder2.0学习笔记——搭建和使用
- kubebuilder2.0学习笔记——进阶使用
- [Finalizers]: https://cloudnative.to/kubebuilder/reference/using-finalizers.html “使用 Finalizers”
[kubebuilder-标记注释]: https://blog.csdn.net/a1023934860/article/details/122859248 “kubebuilder-标记注释”