如何在Kubernetes中编写自定义控制器

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
接下来一起来看看: 声明式API对象的编程范式
API对象的组织方式

API对象在Etcd里的完整资源路径是由 Group(API组)、Version(API版本)和Resource(API资源类型)三部分组成。

Kubernetes创建资源对象的流程:

首先Kubernetes读取用户提交的yaml文件
然后Kubernetes去匹配yaml文件中API对象的组
再次Kubernetes去匹配yaml文件中API对象的版本号
最后Kubernetes去匹配yaml文件中API对象的资源类型

因此我们需要根据需求先进行自定义资源(CRD - Custom Resource Definition),它将包括API对象组、版本号、资源类型:
在这里插入图片描述
在上面的yaml文件中指定group: spursyyversion: v1API的组和版本号信息、也指定了CR资源类型叫做MyResource,复数是myresources、同时还声明该资源是Namespaced的对象。

然后我们就可以使用刚才定义的资源对象:

  • 资源类型指定为MyResource
  • 资源组为spursy
  • 资源的版本号为v1

如果只定义资源对象,而不定义相应的控制,资源对象并不能发挥任何效用。接下来我们一起看看如何自定义资源控制器。

a. 控制器如何与APIServer通信

Informer是APIServer与Kubernetes相互通信的桥梁,它通过Reflector实现ListAndWatch方法来“获取”和“监听”对象实例的变化
每当APIServer接收到创建、更新和删除实例的请求,Refector都会收到“事件通知”,然后将变更的事件推送到先进先出的队列中
Informer会不断从上一队列中读取增量,然后根据增量事件的类型创建或者更新本地对象的缓存
Informer会根据事件类型触发事先定义好的ResourceEventHandler(具体为AddFunc、UpdatedFunc和DeleteFunc,分别对应API对象的“添加”、“更新”和“删除”事件)
同时每隔一定的时间Informer也会对本地的缓存进行一次强制更新

b. WorkQueue同步Informer跟控制循环(Control Loop)交互的数据

c. Controller Loop 扮演这Kubernetes控制器的角色,确保期望与实际的运行的状态是一致的

在这里插入图片描述
综上所述,如何使用控制器模式,同 Kubernetes 里 API 对象的“增、删、改、查”进行协作,进而完成用户业务逻辑的编写过程。这就是“Kubernetes 编程范式”。

了解了Kubernetes的控制器模型和API的编程范式,接下来我将介绍 如何自定义控制器

Operator

Operator 是由 CoreOS 开发的,用来扩展 Kubernetes API,特定的应用程序控制器,它用来创建、配置和管理复杂的有状态应用,如数据库、缓存和监控系统。接下来我将使用Operator SDK,自定义用来控制Pod数量的特定资源。简而言之就是实现类似Kubernetes ReplicaSet类型的资源。

在使用Operator SDK自定义资源前,我们需要明确两点:

  1. Operator SDK的工作流

使用 SDK 创建一个新的 Operator 项目
通过添加自定义资源(CRD)定义新的资源 API
指定使用 SDK API 来 watch 的资源
定义 Operator 的协调(reconcile)逻辑
使用 Operator SDK 构建并生成 Operator 部署清单文件

  1. 明确第一资源和第二资源

像上述我们即将实现类ReplicaSet自定义资源中,第一资源是ReplicaSet自身(明确指定运行的Docker镜像和ReplicaSet中Pod的数量)、第二资源是运行的Pod。当ReplicaSet中属性发生变化(如自定的Docker镜像,或者指定Pod副本的数量)或者Pod的发生变化(如Pod的实际运行数量减少),Controller控制器通过前文讲的控制循环一旦发现上述变化,就会通过变更Pod中镜像的版本或者伸缩Pod的数量调谐(reconcile)集群中ReplicaSet资源的状态。

了解了Operator 的原理,接下来我将通过一个demo演示如何通过 Operator SDK创建资源

如果小伙伴想了解更多关于Operator SDK的相关知识可参照github官方仓库 https://github.com/operator-framework/operator-sdk

使用SDK生成go项目框架
operator-sdk new podset-operator

生成的项目文件结构如下图:
在这里插入图片描述
为刚才生成代码添加自定义API
operator-sdk add api --api-version=app.example.com/v1alpha1 --kind=PodSet

添加自定义控制器
operator-sdk add controller --api-version=app.example.com/v1alpha1 --kind=PodSet

修改 */podset-operator/pkg/apis/app/v1alpha1/podset_types.go文件中的PodSetSpec 和 PodSetStatus

在这里插入图片描述

需要特别注意:我们一旦对Operator SDK生成的框架做任何修改,都需要执行operator-sdk generate k8s,重新生成相应的pkg/apis/app/v1alpha1/zz_generated.deepcopy.go文件

最后我们需要实现控制器中自动伸缩的代码
代码修改是在控制器Reconcile的函数中/podset-operator/pkg/controller/podset/podset_controller.go

我需要明确一下逻辑:

PodSet或者归属于PodSet的Pod一旦发生变化都会触发reconcile函数
无论是增加还是删除Pod,Reconcile函数每次都只能增删一个Pod,然后返回,等待下一次触发Reconcile函数
确保归属于PodSet第一资源的Pod使用controllerutil.SetControllerReference()函数,这样当第一资源删除时,系统会自动将相应的Pod删除

控制器的实现逻辑可参见 https://github.com/spursy/podset-operator/blob/master/pkg/controller/podset/podset_controller.go#L86

接下来 将使用Operator SDK生成部署文件
将Operator项目打包成镜像

operator-sdk build spursyy/podset-operator

推送到docker hub

docker push spursyy/podset-operator

修改operator.yaml文件

sed -i “” ‘s|REPLACE_IMAGE|spursyy/podset-operator|g’ deploy/operator.yaml

最后是将 上一步生成的文件部署到集群中
创建service account
create -f deploy/service_account.yaml

为service account做RBAC认证
kubectl create -f deploy/role.yaml
kubectl create -f deploy/role_binding.yaml

部署CRD和Operator文件

kubectl create -f deploy/crds/app_v1alpha1_podset_crd.yaml
kubectl create -f deploy/operator.yaml

以上我们定义了CRD,并将Operator SDK生成的控制器代码部署到集群后,我们就可以实现在集群中部署自定义的资源

echo “apiVersion: app.example.com/v1alpha1
kind: PodSet
metadata:
name: example-podset
spec:
replicas: 3” | oc create -f -

以上完整代码在我的github 仓库中 https://github.com/spursy/podset-operator

本次交流的内容我已经发布到知识分享平台平台 https://juejin.im/post/5e015ac46fb9a0160a313f68

更多技术文章请关注公众号:架构师Plus,
扫码添加
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值