50、K8S-自定义资源定义-CustomResourceDefinition

发布时间 2023-04-06 20:27:07作者: 小粉优化大师

1、基础知识

1.1、回顾

到目前位置,我们为了在k8s上能够正常的运行我们所需要的服务,需要遵循以下方式来创建相关资源:
1、合理的分析业务需求。
2、梳理业务需求的相关功能。
3、定制不同功能的资源配置文件。
4、应用资源配置文件,完善业务环境。

1.2、需求

我们在操作k8s资源的时候,发现一个有趣的特点,到现在位置,我们所有的操作,基本上都是在k8s限
制的资源对象中进行相关的操作,这些资源对象适用于通用的业务场景,而在我们的业务场景中,多多少少的会涉及到专用的资源对象。
比如:我们的监控场景需要监控的数据、日志场景需要收集的日志、流量场景需要传递的数据、等等。
 
为了高效的定制我们需要的环境,那么需要拥有一些专用的资源方便我们来使用,而在k8s之上却没有,提供了一个专用的接口,可以方便我们自己来定制需要的资源。

1.3、自定义资源控制-CRD-CustomResourceDefinition

1.3.1、使用场景

calico环境创建的时候,就用到了很多CRD对象,而且我们为了让CRD能够生效,该软件还提供了一个controller的CRD控制器。
这个控制器就是将CRD对象转换为真正有意义的现实的代码。

]# kubectl  get crd
NAME                                                  CREATED AT
bgpconfigurations.crd.projectcalico.org               2023-04-02T16:09:20Z
bgpfilters.crd.projectcalico.org                      2023-04-02T16:09:20Z
bgppeers.crd.projectcalico.org                        2023-04-02T16:09:20Z
blockaffinities.crd.projectcalico.org                 2023-04-02T16:09:20Z
caliconodestatuses.crd.projectcalico.org              2023-04-02T16:09:20Z
clusterinformations.crd.projectcalico.org             2023-04-02T16:09:20Z
felixconfigurations.crd.projectcalico.org             2023-04-02T16:09:20Z
globalnetworkpolicies.crd.projectcalico.org           2023-04-02T16:09:20Z
globalnetworksets.crd.projectcalico.org               2023-04-02T16:09:20Z
hostendpoints.crd.projectcalico.org                   2023-04-02T16:09:20Z
ipamblocks.crd.projectcalico.org                      2023-04-02T16:09:20Z
ipamconfigs.crd.projectcalico.org                     2023-04-02T16:09:20Z
ipamhandles.crd.projectcalico.org                     2023-04-02T16:09:21Z
ippools.crd.projectcalico.org                         2023-04-02T16:09:21Z
ipreservations.crd.projectcalico.org                  2023-04-02T16:09:21Z
kubecontrollersconfigurations.crd.projectcalico.org   2023-04-02T16:09:21Z
networkpolicies.crd.projectcalico.org                 2023-04-02T16:09:21Z
networksets.crd.projectcalico.org                     2023-04-02T16:09:21Z

1.3.2、简介

资源(Resource) 是 Kubernetes API 中的一个端点, 其中存储的是某个类别的 API 对象 的一个集合。 例如内置的 pods 资源包含一组 Pod 对象。

定制资源(Custom Resource) 是对 Kubernetes API 的扩展,不一定在默认的 Kubernetes 安装中就可用。定制资源所代表的是对特定 Kubernetes 安装的一种定制。 不过,很多 Kubernetes 核心功能现在都用定制资源来实现,这使得 Kubernetes 更加模块化。
定制资源可以通过动态注册的方式在运行中的集群内或出现或消失,集群管理员可以独立于集群 更新定 制资源。一旦某定制资源被安装,用户可以使用 kubectl 来创建和访问其中的对象,就像他们为 pods 这种内置资源所做的一样。 CRD 功能是在 Kubernetes
1.7 版本被引入的,用户可以根据自己的需求添加自定义的Kubernetes 对象资源。

1.3.3、CRD流程图

1.3.4、定制控制器

   就定制资源本身而言,它只能用来存取结构化的数据。 当你将定制资源与 定制控制器(Custom Controller) 相结合时,定制资源就能够 提供真正的 声明式 API(Declarative API)。
使用声明式 API, 你可以 声明 或者设定你的资源的期望状态,并尝试让 Kubernetes 对象的当前状态 同步到其期望状态。控制器负责将结构化的数据解释为用户所期望状态的记录,
并持续地维护该状态。

你可以在一个运行中的集群上部署和更新定制控制器,这类操作与集群的生命周期无关。 定制控制器可以用于任何类别的资源,不过它们与定制资源结合起来时最为有效。
Operator 模式就是将定制资源 与定制控制器相结合的。
你可以使用定制控制器来将特定于某应用的领域知识组织起来,以编码的形式构造对Kubernetes API 的扩展。

1.3.5、什么情况会用CRD

你希望使用 Kubernetes 客户端库和 CLI 来创建和更改新的资源。
你希望 kubectl 能够直接支持你的资源;例如,kubectl get my-object object-name。
你希望构造新的自动化机制,监测新对象上的更新事件,并对其他对象执行 CRUD 操作,或者监测后者更新前者。
你希望编写自动化组件来处理对对象的更新。
你希望使用 Kubernetes API 对诸如 .spec、.status 和 .metadata 等字段的约定。
你希望对象是对一组受控资源的抽象,或者对其他资源的归纳提炼。

2、CRD-CustomResourceDefinition-实践

2.1、基础知识

2.1.1、配置解析

apiVersion: apiextensions.k8s.io/v1    # API群组和版本
kind: CustomResourceDefinition         # 资源类别
metadata:
  name <string>              # 资源名称
spec:
  conversion <Object>        # 定义不同版本间的格式转换方式
    trategy <string>         # 不同版本间的自定义资源转换策略,有None和Webhook两种取值
    webhook <Object>         # 如何调用用于进行格式转换的webhook
  group <string>             # 资源所属的API群组
  names <Object>             # 自定义资源的类型,即该CRD创建资源规范时使用的
kind
  categories <[]string>      # 资源所属的类别编目,例如”kubectl get all”中的all
  kind <string>              # kind名称,必选字段
  listKind <string>          # 资源列表名称,默认为"`kind`List"
  plural <string>            # 用于API路径`/apis/<group>/<version>/.../<plural>`
  shortNames <[]string>      # 该资源的kind的缩写格式
  singular <string>          # 资源kind的单数形式,必须使用全小写字母
  preserveUnknownFields <boolean>   # 预留的非知名字段,kind等都是知名的预留字段
  scope <string>                    # 作用域,可用值为Cluster和Namespaced
  versions <[]Object>               # 版本号定义
  additionalPrinterColumns <[]Object>   # 需要返回的额外信息
  name <string>                         # 形如vM[alphaN|betaN]格式的版本名称,例如v1或v1alpha2
  schema <Object>                       # 该资源的数据格式(schema)定义,必选字段
    openAPIV3Schema <Object>            # 用于校验字段的schema对象,格式请参考相关手册
  served <boolean>                # 是否允许通过RESTful API调度该版本,必选字段
  storage <boolean>               # 将自定义资源存储于etcd中时是不是使用该版本
  subresources <Object>           # 子资源定义
    scale <Object>                # 启用scale子资源,通过autoscaling/v1.Scale发送负荷
    status <map[string]>          # 启用status子资源,为资源生成/status端点

2.1.2、配置示例【 calico的自定义资源对象】

# Source: calico/templates/kdd-crds.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: globalnetworksets.crd.projectcalico.org
spec:
  group: crd.projectcalico.org
  names:
    kind: GlobalNetworkSet
    listKind: GlobalNetworkSetList
    plural: globalnetworksets
    singular: globalnetworkset
  preserveUnknownFields: false
  scope: Cluster
  versions:
  - name: v1
    schema:
      openAPIV3Schema:
        description: GlobalNetworkSet contains a set of arbitrary IP sub-networks/CIDRs
          that share labels to allow rules to refer to them via selectors.  The labels
          of GlobalNetworkSet are not namespaced.
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: GlobalNetworkSetSpec contains the specification for a NetworkSet
              resource.
            properties:
              nets:
                description: The list of IP networks that belong to this set.
                items:
                  type: string
                type: array
            type: object
        type: object
    served: true
    storage: true
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: []
  storedVersions: []

]# kubectl get crd | grep -E 'NAME|networksets'
NAME CREATED AT
globalnetworksets.crd.projectcalico.org 2023-04-02T16:09:20Z
networksets.crd.projectcalico.org 2023-04-02T16:09:21Z

2.2、创建自定义资源

2.2.1、定义资源配置清单且应用

kubectl apply -f - <<EOF
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: users.auth.ilinux.io
spec:
  group: auth.ilinux.io
  names:
    kind: User
    plural: users
    singular: user
    shortNames: 
    - u
  scope: Namespaced
  versions:
  - served: true
    storage: true
    name: v1alpha1
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              userID:
                type: integer
                minimum: 1
                maximum: 65535
              groups:
                type: array
                items:
                  type: string
              email:
                type: string
              password:
                type: string
                format: password
            required: ["userID","groups"]
EOF

2.2.2、查询创建结束

master1 ~]# kubectl get crd users.auth.ilinux.io 
NAME                   CREATED AT
users.auth.ilinux.io   2023-04-06T12:05:18Z

2.2.3、查询自定义资源的帮忙

master1 ~]# kubectl explain users.auth.ilinux.io 
KIND:     User
VERSION:  auth.ilinux.io/v1alpha1
DESCRIPTION:
     <empty>
FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata     <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
   spec <Object>

master1 ~]# kubectl explain users.auth.ilinux.io.spec KIND: User VERSION: auth.ilinux.io/v1alpha1 RESOURCE: spec <Object> DESCRIPTION: <empty> FIELDS: email <string> groups <[]string> -required- password <string> userID <integer> -required-

2.3、创建自己定义的资源

2.3.1、定义资源配置清单

kubectl apply -f - <<EOF
apiVersion: auth.ilinux.io/v1alpha1
kind: User
metadata:
  name: admin
  namespace: default
spec:
  userID: 1
  email: cyc@example.com
  groups:
  - superusers
  - adminstrators
  password: cyc.example.com
EOF

2.3.2、查询创建资源结果

master1 ~]# kubectl get users
NAME    AGE
admin   3s

master1 ~]# kubectl get user
NAME    AGE
admin   2m53s

master1 ~]# kubectl get u
NAME    AGE
admin   2m58s

2.3.3、总结

虽然我们创建好了CRD,但是CRD本身没有太大的意义,他的意义在于,我们如何在 控制器或者operator 中如何使用它