Kubernetes API 使用CRD扩展资源对象

2020-08-17 0 By admin

CRD是Kubernetes从1.7版本开始引入的特性,在Kubernetes早期版本中被称为TPR(ThirdPartyResources,第三方资源)。TPR从Kubernetes 1.8版本开始被停用,被CRD全面替换。
CRD本身只是一段声明,用于定义用户自定义的资源对象。但仅有CRD的定义并没有实际作用,用户还需要提供管理CRD对象的CRD控制器(CRD Controller),才能实现对CRD对象的管理。

CRD控制器通常可以通过Go语言进行开发,并需要遵循Kubernetes的控制器开发规范,基于客户端库client-go进行开发,需要实现Informer、ResourceEventHandler、Workqueue等组件具体的功能处理逻辑。
详细的开发过程请参考官方示例(https://github.com/kubernetes/samplecontroller)和client-go库(https://github.com/kubernetes/samplecontroller/
blob/master/docs/controller-client-go.md)的详细说明。

一、创建CRD的定义

与其他资源对象一样,对CRD的定义也使用YAML配置进行声明。
以Istio系统中的自定义资源VirtualService为例,配置文件crdvirtualservice.yaml的内容如下:

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: virtualservices.networking.istio.io
  annotations:
    "helm.sh/hook": crd-install
  labels:
    app: istio-pilot
spec:
  group: networking.istio.io
  scope: Namespaced
  versions:
  - name: v1alpha3
    served: true
	storage: true
  names:
    kind: VirtualService
	listKind: VirtualServiceList
	singular: VirtualService
	plural: virtualservices
	categories:
	- istio-io
	- networking-istio-io

1.1、CRD定义中的关键字段解释

1、group:设置API所属的组。将其映射为API URL中“/apis/”的下一级目录,设置networking.istio.io生成的API URL路径为“/apis/networking.istio.io”。
2、scope:该API的生效范围,可选项为Namespaced(由Namespace限定)和Cluster(在集群范围全局生效,不局限于任何Namespace),默认值为Namespaced。
3、versions:设置此CRD支持的版本,可以设置多个版本,用列表形式表示。
目前还可以设置名为version的字段,只能设置一个版本,在将来的Kubernetes版本中会被弃用,建议使用versions进行设置。
如果该CRD支持多个版本,则每个版本都会在API URL“/apis/networking.istio.io”的下一级进行体现,例如“/apis/networking.istio.io/v1”或“/apis/networking.istio.io/v1alpha3”等。
每个版本都可以设置下列参数:

  1. name:版本的名称,例如v1、v1alpha3等。
  2. served:是否启用,在被设置为true时表示启用。
  3. storage:是否进行存储,只能有一个版本被设置为true。

4、names:CRD的名称,包括单数、复数、kind、所属组等名称的定义,可以设置如下参数。

  1. kind:CRD的资源类型名称,要求以驼峰式命名规范进行命名(单词的首字母都大写),例如VirtualService。
  2. listKind:CRD列表,默认被设置为List格式,例如VirtualServiceList。
  3. singular:单数形式的名称,要求全部小写,例如virtualservice。
  4. plural:复数形式的名称,要求全部小写,例如virtualservices。
  5. shortNames:缩写形式的名称,要求全部小写,例如vs。
  6. categories:CRD所属的资源组列表。例如,VirtualService属于istio-io组和networking-istio-io组,用户通过查询istio-io组和networkingistio-io组,也可以查询到该CRD实例。

1.2、创建CRD资源对象

使用kubectl create命令完成CRD的创建:
kubectl create -f crd-virtualservice.yaml
在CRD创建成功后,由于本例的scope设置了Namespace限定,所以可以通过API Endpoint“/apis/networking.istio.io/v1alpha3/namespaces//virtualservices/”管理该CRD资源。

二、基于 CRD 的定义创建自定义资源对象

基于CRD的定义,用户可以像创建Kubernetes系统内置的资源对象(如Pod)一样创建CRD资源对象。
在下面的例子中,virtualservice-helloworld.yaml 定义了一个类型为VirtualService的资源对象:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
  - "*"
  gateways:
  - helloworld-gateway
  http:
  - match:
    - uri:
	  exact: /hello
  route:
  - destination:
    host: helloworld
	port:
	  number: 5000

除了需要设置该CRD资源对象的名称,还需要在spec段设置相应的参数。
在spec中可以设置的字段是由CRD开发者自定义的,需要根据CRD开发者提供的手册进行配置。
这些参数通常包含特定的业务含义,由CRD控制器进行处理。
使用kubectl create命令完成CRD资源对象的创建:
kubectl create -f virtualservice-helloworld.yaml
然后,用户就可以像操作Kubernetes内置的资源对象(如Pod、RC、Service)一样去操作CRD资源对象了,包括查看、更新、删除和watch等操作。