一、概述
在K8S系统扩展点中,开发者可以通过CRD(CustomResourceDefinition)来扩展K8SAPI,其功能主要由APIExtensionServer负责。使用kubernetes的 CustomResourceDefinition 就可以定义出属于我们自己的 kind.
使⽤CRD扩展资源分为三步:
注册⾃定义资源:开发者需要通过K8S提供的⽅式注册⾃定义资源,即通过CRD进⾏注册,注册之后,K8S就知道我们⾃定义资源的存在了,然后我们就可以像使⽤K8S内置资源⼀样使⽤⾃定义资源(CR)
使⽤⾃定义资源:像内置资源⽐如Pod⼀样声明资源,使⽤CR声明我们的资源信息
删除⾃定义资源:当我们不再需要时,可以删除⾃定义资源
二、注册自定义资源
# demo-crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# name 必须匹配下面的spec字段:并且格式为:’<名称复数形式>.<组名>‘
# <plural>.<group>
name: demos.jacson.com
spec:
# 组名称,用于 REST API : /apis/<组>/<版本>
# /apis/<group>/<version>
group: jacson.com
# 列举此 CustomResourceDefinition 所支持的版本
names:
# kind 通常是单数形式的帕斯卡编码(PascalCased)形式。你的资源清单会使用这一形式。
kind: Demo
# plural 名字用于 REST API 中的定义:/apis/<group>/<version>/<plural>
# 名称的复数形式,用于 URL: /apis/<组>/<版本>/<名称的复数形式>
plural: demos
# singular 名称用于命令操作或显示的一个别名
singular: demo
# 这个地方就是平时使用kubectl get po 当中这个 po 是 pod的缩写的定义,我们可以直接使用kubectl get dm查看
shortNames:
- dm
# 定义作用范围:Namespaced(命名空间级别)或者 Cluster(整个集群)
scope: Namespaced
versions:
- name: v1 # 版本名称,比如 v1、v2beta1 等等
served: true # 版本名称,比如 v1、v2beta1 等等,每个版本都可以通过served 标志来独立启用或禁止
storage: true # 是否开启通过 REST APIs 访问 `/apis/<group>/<version>/...` ,其中一个且只有一个版本必须标记为存储版本
schema: # 定义自定义对象的声明规范
openAPIV3Schema:
description: Define demo YAML Spec
type: object
properties:
# 自定义CRD的字段类型
spec:
type: object
properties:
uuid:
type: string
name:
type: string
image:
type: string
memory:
type: integer
disk:
type: integer
kubectl apply -f demo-crd.yaml
查看:
kubectl get dm
三、使用自定义资源
待CRD创建完成之后,我们就可以使⽤它来创建我们的⾃定义资源了,其创建⽅式跟内置的资源如Pod这些是⼀样的,只是需要将kind、apiVersion指定为我们CRD中声明的值,⽐如使⽤上⾯例⼦中的CRD定义资源:
# demo-cr.yaml
apiVersion: "jacson.com/v1"
kind: Demo
metadata:
name: crd-demo
spec:
uuid: "2c4789b2-30f2-4d31-ab71-ca115ea8c199"
name: "waibizi-wx-virtual-machine"
image: "Centos-7.9"
memory: 4096
disk: 500
[root@master ~]# kubectl get crd | grep demo
demos.jacson.com 2022-07-23T13:42:43Z
[root@master ~]# kubectl get dm
NAME AGE
crd-demo 13s
四、拓展
1、Finalizer
Finalizer能够让控制器实现异步的删除前(Pre-delete)回调。与内置对象类似,定制对象也⽀持Finalizer
# demo-cr.yaml
apiVersion: "jacson.com/v1"
kind: Demo
metadata:
name: crd-demo
finalizers:
- jacson.com/finalizer
使用kubectl delete dm crd-demo的时候会卡住,也就是回调,需要使用kubectl edit dm crd-demo,进去将finalizers两句话删除,即可删除掉cr。
2、合法性验证
在定义crd中:指定name字段必须以test开头
properties:
name:
type: string
pattern: ’^test$‘
cr.yaml
如果name不是test则创建失败。
3、附加字段,获取某个字段的值,例如本例子中,一共有五个字段,这里获取name
....
schema:
...
additionalPrinterColumns:
- name: Name
type: string
description: The name of resource
jsonPath: .spec.name
...
[root@master ~]# kubectl get dm
NAME NAME
crd-demo test
4、子资源
CRD仅支持status和scale子资源
....
schema:
...
subresources:
## status 启用 status 子资源
status: {}
## scale 启用 scale 子资源
scale:
## specReplicasPath 定义定制资源中对应 scale.spec.replicas 的 JSON 路径
specReplicasPath: .spec.replicas
...
5、设置默认值
properties:
name:
type: string
default: "demo"
6、多版本
...
versions:
...
conversion:
strategy: Webhook
webhook:
conversionReviewVersions:["v1","v1beta1"]
clientConfig:
service:
namespace: default
name: example-conversion-webhook-server
path: /crdconvert
caBundle: "Ci0tLS0tQk...<base64-encodedPEMbundle>...tLS0K"