Kubernetes编程—— 使用自定义资源 —— 类型定义
使用自定义资源 —— 类型定义
CRD 也是 Kubernetes 中的一种资源,从属于 apiextension.k8s.io/v1beta1 API 组,由 Kubernetes API 服务器进程中的 apiextensions-apiserver 提供服务。
一、创建 CustomResourceDefinition
我理解意思是说: CRD(Custom Resource Definition [ˌdεfəˈnɪʃən])是 Kubernetes 中的一种机制,用于扩展 Kubernetes API 并定义自定义资源。
CRD 的 Schema 定义遵循 Kubernetes API 对象的规范,通常使用 JSON Schema 来描述 CRD 的结构、字段和验证规则。以下是一个 CRD 的 Schema 定义的示例:
{ "apiVersion": "apiextensions.k8s.io/v1", "kind": "CustomResourceDefinition", "metadata": { "name": "mycustomresources.example.com" }, "spec": { "group": "example.com", // 定义自定义资源所属的API组 "version": "v1", // 定义自定义资源的版本 "scope": "Namespaced", // 定义CRD的作用域,此处为命名空间级别 "names": { "plural": "mycustomresources", // 定义此CRD的复数名称 "singular": "mycustomresource", // 定义此CRD的单数名称 "kind": "MyCustomResource", // 定义此CRD的资源类型名称 "shortNames": [ "mcr" // 定义此CRD的缩写名称 ] }, "validation": { "openAPIV3Schema": { "type": "object", "properties": { "spec": { "type": "object", "properties": { "name": { "type": "string" // 定义spec部分的name字段,类型为字符串 }, "replicas": { "type": "integer", // 定义spec部分的replicas字段,类型为整数 "minimum": 1 // 定义replicas字段的最小值必须为1 } }, "required": [ "name" // 定义spec部分的name字段为必需字段 ] }, "status": { "type": "object", "properties": { "state": { "type": "string", "enum": [ "Running", "Failed", "Pending" // 定义status部分的state字段,只允许取值为"Running"、"Failed"或"Pending" ] } } } }, "required": [ "spec" // 定义整个CRD结构中的spec字段为必需字段 ] } } } }
创建 CRD 对象后,kube-apiserver 中的 apiextensions-apiserver 会检查其名字,确认是否与其他资源的名字发生冲突以及它自身内部的定义是否一致。
我理解意思是说: 当创建自定义资源定义(CRD)对象后,kube-apiserver 中的 apiextensions-apiserver 组件会执行一系列检查来确保CRD的名字没有与其他资源发生冲突,并确保其定义在内部是一致的。
首先,apiextensions-apiserver 会验证 CRD 的名称是否与现有资源的名称发生冲突。这包括验证 CRD 的名称是否与已经存在的 CRD、内置的 Kubernetes 资源或其他自定义资源名称冲突。如果发现冲突,创建请求将被拒绝,并返回适当的错误消息。
接下来,apiextensions-apiserver 会对 CRD 的定义进行验证。它会检查 CRD 的定义与其在 Kubernetes API 中注册的确切字段是否一致。这涉及到验证 CRD 的 apiVersion、kind、group、version 和 scope 字段与定义的值是否匹配,并且验证 CRD 的验证规则(validation schema)是否符合 Kubernetes API 对象的规范。
如果 CRD 的定义与内部的一致,验证通过,CRD 将被成功注册并可在 Kubernetes 中使用。否则,创建请求将被拒绝,并返回相应的错误消息,以指示定义不一致或违反了规范。 这些验证步骤有助于确保 CRD 的正确性和一致性。在创建自定义资源时,确保提供有效且唯一的名称,并确保 CRD 的定义与实际的需求匹配,以避免冲突和错误。
// k8s v1.19 // 样例参考k8s官网: https://kubernetes.io/zh-cn/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ // apiVersion: apiextensions.k8s.io/v1 #指定了 CRD 的 API 版本。 kind: CustomResourceDefinition #表示这是一个自定义资源定义对象。 metadata: #指定了CRD的名称为"crontabs.zuoyang.tech ",必须等于 spec 字段中的 "< name.plural>.< group>" 合并起来的形式。 name: crontabs.zuoyang.tech spec: group: zuoyang.tech #E指定了自定义资源所属的组为"zuoyang.tech"。 versions: - name: v1beta1 #定义了自定义资源的版本"v1beta1/v1alpha1"。 served: true #"served"表示该版本是否被提供服务。 storage: true #"storage"表示该版本是否将数据存储到持久化存储中。 schema: openAPIV3Schema: type: object #required: ["cronSpec","image"] properties: spec: type: object properties: # 添加自定义属性字段和类型 cronSpec: type: string image: type: string replicas: type: integer - name: v1 served: true storage: false schema: openAPIV3Schema: type: object #required: ["cronSpec","image"] properties: spec: type: object properties: # 添加自定义属性字段和类型 cronSpec: type: string image: type: string replicas: type: integer # conversion 节是 Kubernetes 1.13+ 版本引入的,其默认值为无转换,即 strategy 子字段设置为 None。 conversion: # None 转换假定所有版本采用相同的模式定义,仅仅将定制资源的 apiVersion 设置为合适的值. strategy: None # 可以是 Namespaced 或 Cluster scope: Namespaced names: # 名称的复数形式,用于 URL: /apis/< group>/< version>/< plural> plural: crontabs # 名称的单数形式,用于在命令行接口和显示时作为其别名 singular: crontab # kind 通常是驼峰编码(CamelCased)的单数形式,用于资源清单中 kind: CronTab # shortNames 允许你在命令行接口中使用更短的字符串来匹配你的资源 shortNames: - ct
执行下 kubectl apply 后,查看资源是否被 create:
[root@cce-poc-daxs1 zuoyang]# vim resourcedefinition.yaml [root@cce-poc-daxs1 zuoyang]# kubectl apply -f resourcedefinition.yaml -n test2 customresourcedefinition.apiextensions.k8s.io/crontabs.zuoyang.tech created [root@cce-poc-daxs1 zuoyang]# kubectl get crd -n test2 | grep zuoyang crontabs.zuoyang.tech 2023-07-10T10:24:09Z
[root@cce-poc-daxs1 zuoyang]# kubectl get crd/crontabs.zuoyang.tech -n test2 -o yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"apiextensions.k8s.io/v1","kind":"CustomResourceDefinition","metadata":{"annotations":{},"name":"crontabs.zuoyang.tech"},"spec":{"conversion":{"strategy":"None"},"group":"zuoyang.tech","names":{"kind":"CronTab","plural":"crontabs","shortNames":["ct"],"singular":"crontab"},"scope":"Namespaced","versions":[{"name":"v1beta1","schema":{"openAPIV3Schema":{"properties":{"spec":{"properties":{"cronSpec":{"type":"string"},"image":{"type":"string"},"replicas":{"type":"integer"}},"type":"object"}},"type":"object"}},"served":true,"storage":true},{"name":"v1","schema":{"openAPIV3Schema":{"properties":{"spec":{"properties":{"cronSpec":{"type":"string"},"image":{"type":"string"},"replicas":{"type":"integer"}},"type":"object"}},"type":"object"}},"served":true,"storage":false}]}} creationTimestamp: "2023-07-10T10:49:55Z" generation: 1 managedFields: - apiVersion: apiextensions.k8s.io/v1 fieldsType: FieldsV1 fieldsV1: f:status: f:acceptedNames: f:kind: {} f:listKind: {} f:plural: {} f:shortNames: {} f:singular: {} f:conditions: {} manager: kube-apiserver operation: Update time: "2023-07-10T10:49:55Z" - apiVersion: apiextensions.k8s.io/v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:annotations: .: {} f:kubectl.kubernetes.io/last-applied-configuration: {} f:spec: f:conversion: .: {} f:strategy: {} f:group: {} f:names: f:kind: {} f:listKind: {} f:plural: {} f:shortNames: {} f:singular: {} f:scope: {} f:versions: {} f:status: f:storedVersions: {} manager: kubectl-client-side-apply operation: Update time: "2023-07-10T10:49:55Z" name: crontabs.zuoyang.tech resourceVersion: "27044152" selfLink: /apis/apiextensions.k8s.io/v1/customresourcedefinitions/crontabs.zuoyang.tech uid: 62103aa5-5606-48a2-9dd7-6f646f99117e spec: conversion: strategy: None group: zuoyang.tech names: kind: CronTab listKind: CronTabList plural: crontabs shortNames: - ct singular: crontab scope: Namespaced versions: - name: v1beta1 schema: openAPIV3Schema: properties: spec: properties: cronSpec: type: string image: type: string replicas: type: integer type: object type: object served: true storage: true - name: v1 schema: openAPIV3Schema: properties: spec: properties: cronSpec: type: string image: type: string replicas: type: integer type: object type: object served: true storage: false status: acceptedNames: kind: CronTab listKind: CronTabList plural: crontabs shortNames: - ct singular: crontab conditions: - lastTransitionTime: "2023-07-10T10:49:55Z" message: no conflicts found reason: NoConflicts status: "True" type: NamesAccepted - lastTransitionTime: "2023-07-10T10:50:00Z" message: the initial names have been accepted reason: InitialNamesAccepted status: "True" type: Established storedVersions: - v1beta1
二、创建定制对象
在创建了 CustomResourceDefinition 对象之后,你可以创建定制对象(Custom Objects)。定制对象可以包含定制字段。这些字段可以包含任意的 JSON 数据。 在下面的例子中,在类别为 CronTab 的定制对象中,设置了cronSpec 和 image 定制字段。类别 CronTab 来自你在上面所创建的 CRD 的规约。
如果你将下面的 YAML 保存到 my-crontab.yaml:
apiVersion: "stable.example.com/v1" kind: CronTab metadata: name: my-new-cron-object spec: cronSpec: "* * * * */5" image: my-awesome-cron-image
并执行创建命令:
[root@cce-poc-daxs1 zuoyang]# kubectl apply -f my-crontab.yaml -n test2 [root@cce-poc-daxs1 zuoyang]# kubectl get CronTab -n test2 NAME AGE example-crontab 103s [root@cce-poc-daxs1 zuoyang]# kubectl get ct -o yaml apiVersion: v1 items: [] kind: List metadata: resourceVersion: "" selfLink: ""