https://kubernetes.io/zh/docs/concepts/extend-kubernetes/api-extension/custom-resources/
https://staight.github.io/2019/10/08/Kubernetes-CRD%E7%AE%80%E4%BB%8B/
Kubernetes 提供了两种方式供你向集群中添加定制资源:- CRD 相对简单,创建 CRD 可以不必编程。
- API 聚合 需要编程,但支持对 API 行为进行更多的控制,例如数据如何存储以及在不同 API 版本间如何转换等。
1、CRD概述
CRD的全称为CustomResourceDefinitions,即自定义资源。k8s拥有一些内置的资源,比如说Pod,Deployment,ReplicaSet等等,而CRD则提供了一种方式,使用户可以自定义新的资源,以扩展k8s的功能。 使用CRD可以在不修改k8s源代码的基础上方便的扩展k8s的功能,比如腾讯云TKE使用CRD:logcollectors.ccs.cloud.tencent.com以添加日志收集服务,而Istio也大量使用到了CRD。 值得一提的是,另一种扩展k8s的方式是apiservice,通过API:metrics.k8s.io自定义HPA是其最典型的应用。CustomResourceDefinition API 资源允许你定义定制资源。 定义 CRD 对象的操作会使用你所设定的名字和模式定义(Schema)创建一个新的定制资源, Kubernetes API 负责为你的定制资源提供存储和访问服务。 CRD 对象的名称必须是合法的 DNS 子域名。
CRD 使得你不必编写自己的 API 服务器来处理定制资源,不过其背后实现的通用性也意味着 你所获得的灵活性要比 API 服务器聚合少很多。 可以使用kubectl api-resources命令查看集群中已定义的资源:从如上输出中可以略窥一二,CRD至少包括如下属性:
kubectl api-resources
- NAME:CRD的复数名称
- SHORTNAMES:cli中使用的资源简称
- APIGROUP:API所使用的组名称
- NAMESPACED:是否具有namespace属性
- KIND:资源文件需要,用以识别资源
# crd-test.ymlapiVersion: apiextensions.k8s.io/v1beta1kind: CustomResourceDefinitionmetadata:# 名称必须符合如下格式:<plural>.<group>name: crontabs.staight.k8s.iospec:# 组名,表示使用该API: /apis/<group>/<version>group: staight.k8s.io# version列表,表示该CRD支持的版本versions:- name: v1# 开启/关闭该APIserved: true# 有且只能有一个版本要将storage设置为truestorage: true# Namespaced/Cluster,表示该CRD是命名空间属性还是集群属性scope: Namespacednames:# API中使用的名称:/apis/<group>/<version>/<plural>plural: crontabs# 单数名称,cli中使用singular: crontab# 往往是首字母大写的单数名称,资源文件中需要用到kind: CronTab# cli中的简称shortNames:- ct# 阻止无法识别的字段,集群版本1.15以上才可使用preserveUnknownFields: false# 创建资源文件时需验证的字段validation:openAPIV3Schema:type: objectproperties:spec:type: objectproperties:cronSpec:type: stringimage:type: stringreplicas:type: integer
1.1 使用前提
在k8s中CRD本身也是资源,大于1.7.0版本的集群可以使用piextensions.k8s.io/v1beta1API访问CRD,大于1.16.0版本则可以使用apiextensions.k8s.io/v1API。1.2 创建CRD实例
# crd-test.ymlapiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata:# 名称必须符合如下格式:<plural>.<group>name: crontabs.samplecontroller.k8s.ioannotations:"api-approved.kubernetes.io": "unapproved, experimental-only; please get an approval from Kubernetes API reviewers if you're trying to develop a CRD in the *.k8s.io or *.kubernetes.io groups"spec:group: samplecontroller.k8s.ionames:kind: Crontab # 往往是首字母大写的单数名称,资源文件中需要用到plural: crontabs # API中使用的名称:/apis/<group>/<version>/<plural>singular: crontab # 单数名称,cli中使用shortNames: # cli中的简称- ctscope: Namespaced # Namespaced/Cluster,表示该CRD是命令空间属性还是集群属性# version列表,表示该CRD支持的版本preserveUnknownFields: false # 阻止无法识别的字段,集群版本1.15以上才可使用versions:- name: v1alpha1served: true # 开启/关闭该APIstorage: true # 有且只能有一个版本要将storage设置为true# 创建资源文件时需验证的字段schema:openAPIV3Schema:type: objectproperties:spec:type: objectproperties:cronSpec:type: stringimage:type: stringreplicas:type: integer
CRD创建完成。可以通过URL:https://IP:6443/apis/crontabs.samplecontroller.k8s.io/v1/namespaces/default/crontabs访问到crontab资源。
kubectl create -f crd-test.yamlcustomresourcedefinition.apiextensions.k8s.io/crontabs.samplecontroller.k8s.io created
1.3 查看创建的CRD
kubectl get crd crontabs.samplecontroller.k8s.ioNAME CREATED ATcrontabs.samplecontroller.k8s.io 2021-12-30T01:50:50Z
1.4 创建自定义资源对象
在创建CRD之后,即可创建其资源的对象了。资源文件示例:注意spec中的字段应符合CRD的要求,创建它:
# crontab.ymlapiVersion: "samplecontroller.k8s.io/v1alpha1"kind: CronTabmetadata:name: new-crontabnamespace: defaultspec:cronSpec: "* * * * *"image: new-image
接着即可看到该对象:
kubectl create -f crontab.yamlcrontab.samplecontroller.k8s.io/new-crontab created
kubectl get ctNAME AGEnew-crontab 6s
2、API 服务聚合
通常,Kubernetes API 中的每个都需要处理 REST 请求和管理对象持久性存储的代码。 Kubernetes API 主服务器能够处理诸如 pods 和 services 这些内置资源,也可以 按通用的方式通过 CRD 来处理定制资源。聚合层(Aggregation Layer) 使得你可以通过编写和部署你自己的 API 服务器来为定制资源提供特殊的实现。 主 API 服务器将针对你要处理的定制资源的请求全部委托给你自己的 API 服务器来处理,同时将这些资源 提供给其所有客户端。
