【kubernetes/k8s概念】CRD CustomResourceDefinition 自定义资源类型
当看istio源码时,发现使用CRD,本文分析Custom Resource DefinitionWHY CRD?一些特殊的需求,现有资源类型(deploy service statefulset等)满足不了,可以抽象Kubernetes 自定义资源满足需求,WHAT CRD ?k8s1.7 +增加了CRD 二次开发能力来扩展 API...
当看istio源码时,发现使用CRD,本文分析Custom Resource Definition
WHY CRD?
一些特殊的需求,现有资源类型(deploy service statefulset等)满足不了,可以抽象 Kubernetes 自定义资源满足需求,
WHAT CRD ?
k8s 1.7 +增加了 CRD 二次开发能力来扩展 API,通过 CRD 可以向 API 中增加新资源类型,无需修改 Kubernetes 源码或创建自定义的 API server,该功能大大提高了 Kubernetes 的扩展能力。
CRD是一种无需编码就可以扩展原生kubenetes API接口的方式。适合扩展kubernetes的自定义接口和功能。如果想更为灵活的添加逻辑就需要API Aggregation方式
CRD 高级特性:
- 支持 subresource,比如 status 或者 scale
- finalizer,在删除自定义资源的同时去做垃圾回收
- controller,通过 client-go 中的 informer,实现更强大的功能
- crd 的 validation 可对资源中的字段进行验证,设置默认值
HOW CRD ?
如何添加一个Custom resources到kubernetes呢?
两种方式将Custom resources添加到集群。
- Custom Resource Definitions (CRDs):更易用、不需要编码。但是缺乏灵活性
- API Aggregation:需要编码,允许通过聚合层的方式提供更加定制化的实现
引用网上相当赞的图
向Kubernetes API注册schema的资源,并定义相关API
Create a CustomResourceDefinition
当创建一个新的自定义资源定义(CRD)时,Kubernetes API Server 通过创建一个新的RESTful资源路径进行应答,无论是在命名空间还是在集群范围内,正如在CRD的
scope
域指定的那样。
与现有的内建对象一样,删除一个命名空间将会删除该命名空间内所有的自定义对象。
CRD本身并不区分命名空间,对所有的命名空间可用
以下的CRD保存到resourcedefinition.yaml,
kubectl apply -f resourcedefinition.yaml
创建一个自定义资源kind: CustomResourceDefinition
,指定API Group的名称stable.example.com
创建一个/apis/http://stable.example.com/v1/namespaces/<namespace>/crontabs/...的API
可以使用此端点URL来创建和管理自定义对象。 这些对象的kind
就是你在上面创建的CRD中指定的CronTab
对象
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.stable.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
group: stable.example.com
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: crontabs
# singular name to be used as an alias on the CLI and for display
singular: crontab
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: CronTab
# shortNames allow shorter string to match your resource on the CLI
shortNames:
- ct
Create custom objects
在CRD对象创建完成之后,你可以创建自定义对象了。自定义对象可以包含自定义的字段。这些字段可以包含任意的JSON。
以下的示例中,在一个自定义对象
CronTab
种类中设置了cronSpec
和image
字段。这个CronTab
种类来自于你在上面创建的CRD对象。
kubectl apply -f crontab.yml,在CRD对象创建完成之后就创建自定义对象(instances)了,这些自定义对象实例就可以类似Kubernetes的常用对象如Deployment、Service、Pod等一样进行CURD操作了
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * * */5"
image: my-awesome-cron-image
可以看到它包含了自定义的cronSpec
和image
字段,来自于你用于创建它的yaml
# kubectl get ct -o yaml
apiVersion: v1
items:
- apiVersion: stable.example.com/v1
kind: CronTab
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"stable.example.com/v1","kind":"CronTab","metadata":{"annotations":{},"name":"my-new-cron-object","namespace":"default"},"spec":{"cronSpec":"* * * * */5","image":"my-awesome-cron-image"}}
creationTimestamp: 2019-01-19T09:24:54Z
generation: 1
name: my-new-cron-object
namespace: default
resourceVersion: "10288282"
selfLink: /apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object
uid: 14c61440-1bcc-11e9-b451-00505683f77b
spec:
cronSpec: '* * * * */5'
image: my-awesome-cron-image
kind: List
metadata:
resourceVersion: ""
selfLink: ""
Subresources
v1.10 开始 CRD 还支持 /status
和 /scale
等两个子资源(Beta),并且从 v1.11 开始默认开启。
v1.10 版本使用前需要在
kube-apiserver
开启--feature-gates=CustomResourceSubresources=true
# resourcedefinition.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
version: v1
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
# subresources describes the subresources for custom resources.
subresources:
# status enables the status subresource.
status: {}
# scale enables the scale subresource.
scale:
# specReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Spec.Replicas.
specReplicasPath: .spec.replicas
# statusReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Replicas.
statusReplicasPath: .status.replicas
# labelSelectorPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Selector.
labelSelectorPath: .status.labelSelector
$ kubectl create -f resourcedefinition.yaml
$ kubectl create -f- <<EOF
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * * */5"
image: my-awesome-cron-image
replicas: 3
EOF
$ kubectl scale --replicas=5 crontabs/my-new-cron-object
crontabs "my-new-cron-object" scaled
$ kubectl get crontabs my-new-cron-object -o jsonpath='{.spec.replicas}'
5
自定义控制器
只有跟自定义控制器结合起来,资源对象中的声明式API翻译成用户所期望的状态。自定义控制器可以用来管理任何资源类型,一般是跟自定义资源结合使用。
在使用 CRD 扩展 Kubernetes API 时,通常还需要实现一个新建资源的控制器,监听新资源的变化情况,并作进一步的处理。
https://github.com/kubernetes/sample-controller 提供了一个 CRD 控制器的示例,包括
- 如何注册资源
Foo
- 如何创建、删除和查询
Foo
对象 - 如何监听
Foo
资源对象的变化情况
编译
[lin@node1 sample-controller]$ ./hack/update-codegen.sh
Generating deepcopy funcs
Generating clientset for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/client/clientset
Generating listers for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/client/listers
Generating informers for samplecontroller:v1alpha1 at k8s.io/sample-controller/pkg/client/informers[lin@node1 sample-controller]$ go build -v -o samplecontroller
参考:
https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
更多推荐
所有评论(0)