Kubernetes中自定义Controller

本文详细介绍了在Kubernetes中自定义Controller的过程,包括Controller的实现逻辑、code-generator的使用、CRD(CustomResourceDefinition)的创建和管理,以及如何开发和测试自定义Controller。通过实践操作,展示了如何创建数据库管理的Controller,实现数据库实例的创建、更新和删除功能。
摘要由CSDN通过智能技术生成

Kubernetes中自定义Controller

在Kubernetes中,Pod是最小的调度单元,它由各种各样的Controller管理,比如ReplicaSet Controller,Deployment Controller等。

Kubernetes内置了许多Controller,这些Controller能满足80%的业务需求,但是企业里也难免需要自定义Controller来适配自己的业务需求。

网上自定义Controller的文章很多,基本都差不多。俗话说:光说不练假把式,本篇文章主要是自己的一个实践归档总结,如果对你有帮助,可以一键三连!

本文主要从以下几个方面进行介绍,其中包括理论部分和具体实践部分。

Kubernetes中自定义Controller

Controller的实现逻辑

当我们向kube-apiserver提出创建一个Deployment需求的时候,首先是会把这个需求存储到Etcd中,如果这时候没有Controller的话,这条数据仅仅是存在Etcd中,并没有产生实际的作用。

所以就有了Deployment Controller,它实时监听kube-apiserver中的Deployment对象,如果对象有增加、删除、修改等变化,它就会做出相应的相应处理,如下

// pkg/controller/deployment/deployment_controller.go 121行 
..... 
    dInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ 
  AddFunc:    dc.addDeployment, 
  UpdateFunc: dc.updateDeployment, 
  // This will enter the sync loop and no-op, because the deployment has been deleted from the store. 
  DeleteFunc: dc.deleteDeployment, 
 }) 
...... 

其实现的逻辑图如下(图片来自网络):

Kubernetes中自定义Controller

可以看到图的上半部分都由client-go实现了,下半部分才是我们具体需要去处理的。

client-go主要包含Reflector、Informer、Indexer三个组件。

  • Reflector会List&Watch kube-apiserver中的特定资源,然后会把变化的资源放入Delta FIFO队列中。
  • Informer会从Delta FIFO队列中拿取对象交给相应的HandleDeltas。
  • Indexer会将对象存储到缓存中。

上面部分不需要我们去开发,我们主要关注下半部分。

当把数据交给Informer的回调函数HandleDeltas后,Distribute会将资源对象分发到具体的处理函数,这些处理函数通过一系列判断过后,把满足需求的对象放入Workqueue中,然后再进行后续的处理。

code-generator介绍

上一节说到我们只需要去实现具体的业务需求,这是为什么呢?主要是因为kubernetes为我们提供了code-generator【1】这样的代码生成器工具,可以通过它自动生成客户端访问的一些代码,比如Informer、ClientSet等。

code-generator提供了以下工具为Kubernetes中的资源生成代码:

  • deepcopy-gen:生成深度拷贝方法,为每个 T 类型生成 func (t* T) DeepCopy() *T 方法,API 类型都需要实现深拷贝
  • client-gen:为资源生成标准的 clientset
  • informer-gen:生成 informer,提供事件机制来响应资源的事件
  • lister-gen:生成 Lister**,**为 get 和 list 请求提供只读缓存层(通过 indexer 获取)

如果需要自动生成,就需要在代码中加入对应格式的配置,如

Kubernetes中自定义Controller

其中:

  • // +genclient表示需要创建client
  • // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object表示在需要实现k8s.io/apimachinery/pkg/runtime.Object这个接口

除此还有更多的用法,可以参考Kubernetes Deep Dive: Code Generation for CustomResources【2】进行学习。

CRD介绍

CRD全称CustomResourceDefinition,中文简称自定义资源,上面说的Controller主要就是用来管理自定义的资源。

我们可以通过下面命令来查看当前集群中使用了哪些CRD,如下:

# kubectl get crd 
NAME                                                 CREATED AT 
ackalertrules.alert.alibabacloud.com                 2021-06-15T02:19:59Z 
alertmanagers.monitoring.coreos.com                  2019-12-12T12:50:00Z 
aliyunlogconfigs.log.alibabacloud.com                2019-12-02T10:15:02Z 
apmservers.apm.k8s.elastic.co                        2020-09-14T01:52:53Z 
batchreleases.alicloud.com                           2019-12-02T10:15:53Z 
beats.beat.k8s.elastic.co                            2020-09-14T01:52:53Z 
chaosblades.chaosblade.io                            2021-06-15T02:30:54Z 
elasticsearches.elasticsearch.k8s.elastic.co         2020-09-14T01:52:53Z 
enterprisesearches.enterprisesearch.k8s.elastic.co   2020-09-14T01:52:53Z 
globaljobs.jobs.aliyun.com                           2020-04-26T14:40:53Z 
kibanas.kibana.k8s.elastic.co                        2020-09-14T01:52:54Z 
prometheuses.monitoring.coreos.com                   2019-12-12T12:50:01Z 
prometheusrules.monitoring.coreos.com                2019-12-12T12:50:02Z 
servicemonitors.monitoring.coreos.com                2019-12-12T12:50:03Z 

但是仅仅是创建一个CRD对象是不够的,因为它是静态的,创建过后仅仅是保存在Etcd中,如果需要其有意义,就需要Controller配合。

创建CRD的例子如下:

apiVersion: apiextensions.k8s.io/v1 
kind: CustomResourceDefinition 
metadata: 
  # name 必须匹配下面的spec字段:<plural>.<group> 
  name: students.coolops.io 
spec: 
  # group 名用于 REST API 中的定义:/apis/<group>/<version> 
  group: coolops.io 
   # 列出自定义资源的所有 API 版本 
  versions: 
  - name: v1    # 版本名称,比如 v1、v1beta1 
    served: true    # 是否开启通过 REST APIs 访问 `/apis/<group>/<version>/...` 
    storage: true   # 必须将一个且只有一个版本标记为存储版本 
    schema:         # 定义自定义对象的声明规范 
      openAPIV3Schema: 
        type: object 
        properties: 
          spec: 
            type: object 
            properties: 
              name: 
                type: string 
              school: 
                type: string 
  scope: Namespaced    # 定义作用范围:Namespaced(命名空间级别)或者 Cluster(整个集群) 
  names: 
    plural: students   # plural 名字用于 REST API 中的定义:/apis/<group>/<version>/<plural> 
    shortNames:        # shortNames 相当于缩写形式 
    - stu 
    kind: Student      # kind 是 sigular 的一个驼峰形式定义,在资源清单中会使用  
    singular: student  # singular 名称用于 CLI 操作或显示的一个别名 

具体演示

本来准备根据官方的demo【3】进行讲解,但是感觉有点敷衍,而且这类教程网上一大堆,所以就准备自己实现一个数据库管理的一个Controller。

因为是演示怎么开发Controller,所以功能不会复杂,主要的功能是:

  • 创建数据库实例
  • 删除数据库实例
  • 更新数据库实例

开发环境说明

本次实验环境如下:

Kubernetes中自定义Controller

创建CRD

CRD是基础,Controller主要是为CRD服务的,所以我们要先定义好CRD资源,便于开发。

apiVersion: apiextensions.k8s.io/v1 
kind: CustomResourceDefinition 
metadata: 
  name: databasemanagers.coolops.cn 
spec: 
  group: coolops.cn 
  versions: 
    - name: v1alpha1 
      served: true 
      storage: true 
      schema: 
        openAPIV3Schema: 
          type: object 
          properties: 
            spec: 
              type: object 
              properties: 
                deploymentName: 
                  type: strin 
                replicas: 
                  type: integer 
                  minimum: 1 
                  maximum: 10 
                dbtype: 
                  type: string 
            status: 
              type: object 
              properties: 
                availableReplicas: 
                  type: integer 
  names: 
    kind: DatabaseManager 
    plural: databasemanagers 
    singular: databasemanager 
    shortNames: 
      - dm 
  scope: Namespaced 

创建CRD,检验是否能创建成功。

# kube
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值