K8s: Kubernetes扩展之自定义资源

发布于:2024-05-06 ⋅ 阅读:(31) ⋅ 点赞:(0)

自定义资源

  • 自定义资源是 K8s 的扩展,有时候需要对K8s进行一个扩展
  • 在默认的K8s集群里面提供的资源对象是一个有限的集合
  • 比如常用的pod, deployment, service,这些都是K8s原生的资源
  • 之所以它资源,是因为它能够对外提供API接口变成一个resource进行访问
  • 通过 kubectl 创建,也能把这些资源创建出来
  • 当有限的K8s的资源,不能满足你的需求的情况下
  • 就需要通过 Custom Resource 来实现自定义的这个资源
  • 实现了自定义资源之后,就可以使用 kubectl 来访问和创建其中的对象
  • 为什么需要有这个应用场景
    • 比如K8s提供了这个job类型的这个资源
    • 它能够去按照这个任务的一次性的任务的方式去执行或者多次任务去执行某一个任务
    • 它是没有提供一个 CronJob,类似于这样的一个定时任务的这么一个资源对象
    • 那么在这个时候就需要我们自行来扩展K8s对象
    • 自己去创建一个叫 CustomerResource 这种类型的资源,去满足我们自己的业务需求
    • 所以, 这样的业务需求,在企业落地开发的时候是非常常见的
  • 什么时候应该使用自定义资源
    • 你希望使用 K8s 客户端库和 CLI 来创建和更改新的资源
    • 你希望 kubectl 能够直接支持你的资源;例如,kubectl get my-object object-name
    • 你希望构造新的自动化机制,监测新对象上的更新事件
    • 并对其他对象执行 CRUD 操作,或者监测后者更新前者
    • 你希望编写自动化组件来处理对对象的更新
    • 你希望使用 K8s API 对诸如 .spec、.status 和 .metadata 等字段的约定
    • 你希望对象是对一组受控资源的抽象,或者对其他资源的归纳提炼
  • 这个看起来似乎有些像 ConfigMap, 我们来看下何时使用 ConfigMap
    • 存在一个已有的,文档完毕的配置文件格式约定,如 mysql.cnf 或 pom.xml
    • 你希望将整个配置文件放到某 configMap 中的一个主键下面
    • 配置文件的主要用途是针对运行在集群中 Pod 内的程序,供后者依据文件数据配置自身行为
    • 文件的使用者期望以 Pod 内文件或者 Pod 内环境变量的形式来使用文件数据, 而不是通过 K8s API
    • 你希望当文件被更新时通过类似 Deployment 之类的资源完成滚动更新操作

创建一个 CRD


1 )概述

  • 当你创建新的 CustomResourceDefinition(CRD)时
  • Kubernetes API 服务器会为你所指定的每一个版本生成一个 RESTful 的 资源路径
  • CRD 可以是命名空间作用域的,也可以是集群作用域的取决于 CRD 的 scope 字段设置
  • 和其他现有的内置对象一样,删除一个命名空间时,该命名空间下的所有定制对象也会被删除
  • CustomResourceDefinition 本身是不受命名空间限制的,对所有命名空间可用

2 )创建

  • $ vi rd-demo1.yaml
    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: crontabs.stable.example.com
    spec:
      group: stable.example.com
      versions:
      - name: v1
        # Each version can be enabled/disabled by Served flag.
        served: true
        # One and only one version must be marked as the storage version.
        storage: true
        schema:
          openAPIV3Schema:
            type: object
            properties:
              spec:
                type: object
                properties:
                  cronSpec:
                    type: string
                  image:
                    type: string
                    pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' # 数据校验
                  replicas:
                    type: integer
                    minimum: 1
                    maximum: 10
    scope: Namespaced
    names:
      plural: crontabs
      singular: crontab
      kind: CronTab
      shortNames:
      - ct
    
  • 在这里面,它是基于这个 openAPIV3Schema 这个版本的schema去定义比如类型,属性
  • 相当于有一个类似于面向对象的这么一个定义方式描述这个对象应该长成什么样,有什么字段
  • 这里面值得一提的就是说在这个 scope 字段, 它的scope 可以被限定在 namespace 的这么一个范围
  • 也就是说,如果你scope设置了 namespace 之后, 当你删除某一个namespace名字空间的时候
  • 空间下所有的定制对象也会被删除, 如果你不定义的话,那个 custom resource 不受命名名间的限制
  • 在所有命名空间生效,这里声明一个名字叫 crontabs 的对象,这个版本的版本是 v1
  • group 是这个网站: stable.example.com, metadata 名称叫 crontabs.stable.example.com
  • schema 下的 cronSpec 就是定时任务的一个规范,可以输入一些正则表达式
  • 还定义了的镜像字段,副本数字段,有了这样的文件后,可进行创建
  • 可定制资源是通过OpenAPI v3模式定义来执行合法性检查的
  • 模式定义是在 CustomResourceDefinition 中设置的
  • 在下面的例子中, CustomResourceDefinition 对定制对象执行
  • 以下是合法性检查:
    • spec.cronSpec 必须是一个字符串,必须是正则表达式所描述的形式
    • spec.replicas 必须是一个整数,且其最小值为 1、最大值为 10
  • 执行 $ kubectl apply -f rd-demo1.yaml
    customresourcedefinition.apiextensions.k8s.io/crontabs.stable.example.com created
    
  • $ kubectl get crd 获取资源类型
    NAME                            CREATED AT
    crontabs.stable.example.com     2024-04-30T13:05
    
  • 现在定义好了资源,我们还要创建这个资源的对象
    • 在创建了 CustomResourceDefinition 对象之后
    • 你可以创建定制对象(Custom Objects)定制对象可以包含定制字段
    • 这些字段可以包含任意的 JSON 数据
    • 在下面的例子中,在类别为 CrontTab 的定制对象中,设置了cronSpec 和 image 定制字段
    • 类别 CronTab 来自你在上面所创建的 CRD 的规约
  • 创建对象 $ vi my-crontab.yaml
    apiVersion: "stable.example.com/v1"
    kind: CronTab
    metadata:
      name: my-new-cron-object
    spec:
      cronSpec: "* * * * */5"
      image: my-awesome-cron-image # 这个可以是任意的镜像
    
  • $ kubectl apply -f my-crontab.yaml
    crontabs.stable.example.com/my-new-cron-object created
    
  • $ kubectl get crontab 获取实例
    NAME                  AGE
    my-new-cron-object    8s
    
  • $ kubectl get crontab -o yaml 可以输出实例,可以看到很多细节
  • 所以通过简单的定义就发现,通过 K8s 我能自己实现一个 crontab 这么一个类型的一个任务
  • 然后有这个对象之后,就能实现 crontab 的这个命令
  • 这就是一个最简单的 chrome type 任务的一个定义
  • 有了这样的能力之后,对 K8s 进行一个很好的扩展