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.yml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# 名称必须符合如下格式:<plural>.<group>
name: crontabs.staight.k8s.io
spec:
# 组名,表示使用该API: /apis/<group>/<version>
group: staight.k8s.io
# version列表,表示该CRD支持的版本
versions:
- name: v1
# 开启/关闭该API
served: true
# 有且只能有一个版本要将storage设置为true
storage: true
# Namespaced/Cluster,表示该CRD是命名空间属性还是集群属性
scope: Namespaced
names:
# API中使用的名称:/apis/<group>/<version>/<plural>
plural: crontabs
# 单数名称,cli中使用
singular: crontab
# 往往是首字母大写的单数名称,资源文件中需要用到
kind: CronTab
# cli中的简称
shortNames:
- ct
# 阻止无法识别的字段,集群版本1.15以上才可使用
preserveUnknownFields: false
# 创建资源文件时需验证的字段
validation:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
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.yml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# 名称必须符合如下格式:<plural>.<group>
name: crontabs.samplecontroller.k8s.io
annotations:
"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.io
names:
kind: Crontab # 往往是首字母大写的单数名称,资源文件中需要用到
plural: crontabs # API中使用的名称:/apis/<group>/<version>/<plural>
singular: crontab # 单数名称,cli中使用
shortNames: # cli中的简称
- ct
scope: Namespaced # Namespaced/Cluster,表示该CRD是命令空间属性还是集群属性
# version列表,表示该CRD支持的版本
preserveUnknownFields: false # 阻止无法识别的字段,集群版本1.15以上才可使用
versions:
- name: v1alpha1
served: true # 开启/关闭该API
storage: true # 有且只能有一个版本要将storage设置为true
# 创建资源文件时需验证的字段
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
type: integer
CRD创建完成。可以通过URL:https://IP:6443/apis/crontabs.samplecontroller.k8s.io/v1/namespaces/default/crontabs访问到crontab资源。
kubectl create -f crd-test.yaml
customresourcedefinition.apiextensions.k8s.io/crontabs.samplecontroller.k8s.io created
1.3 查看创建的CRD
kubectl get crd crontabs.samplecontroller.k8s.io
NAME CREATED AT
crontabs.samplecontroller.k8s.io 2021-12-30T01:50:50Z
1.4 创建自定义资源对象
在创建CRD之后,即可创建其资源的对象了。资源文件示例:注意spec中的字段应符合CRD的要求,创建它:
# crontab.yml
apiVersion: "samplecontroller.k8s.io/v1alpha1"
kind: CronTab
metadata:
name: new-crontab
namespace: default
spec:
cronSpec: "* * * * *"
image: new-image
接着即可看到该对象:
kubectl create -f crontab.yaml
crontab.samplecontroller.k8s.io/new-crontab created
kubectl get ct
NAME AGE
new-crontab 6s
2、API 服务聚合
通常,Kubernetes API 中的每个都需要处理 REST 请求和管理对象持久性存储的代码。 Kubernetes API 主服务器能够处理诸如 pods 和 services 这些内置资源,也可以 按通用的方式通过 CRD 来处理定制资源。聚合层(Aggregation Layer) 使得你可以通过编写和部署你自己的 API 服务器来为定制资源提供特殊的实现。 主 API 服务器将针对你要处理的定制资源的请求全部委托给你自己的 API 服务器来处理,同时将这些资源 提供给其所有客户端。