带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.1(二)

2.1.1      CRD介绍

 

1. 声明式 API

 

什么是声明式 API呢?首先我们需要了解在Kubernetes中,使用 Deployment、DamenSet,StatefulSet等资源来管理应用 Workload,使用 Service、Ingress等来管理应用的访问方式,使用 ConfigMap和 Secret 来管理应用配置。在集群中对这些资源的创建、更新、删除的动作都会被转换为事件(Event),Kubernetes 的 Controller Manager 负责监听这些事件并触发相应的任务来满足用户的期望。这种方式称为声明式,用户只需要关心应用程序的最终状态,其他的过程都通过   Kubernetes来完成,通过这种方式可以大大简化应用配置管理的复杂度。

声明式 API指的是用户提交一个定义好的 API 对象来描述所期望的状态。例如上面创建的Namespace 资源,这个资源类型表明用户期望的结果是创建一个名字为Nginx的命名空间。那么用户无须关心如何创建 Namespaces资源,只需要关注结果即可。

什么是过程式 API呢?过程式 API 一次只能处理一个写请求,否则可能会产生冲突,已不具备合并操作的能力 。

声明式 API的特点是允许有多个 API写端以 PATCH的方式对 API对象进行修改,而无须关心本地原始Yaml 文件的内容。声明式API才是Kubernetes 项目编排能力的核心。对于 API对象的增、删、改、查,可以在完全无须外界干预的情况下,完成对“实际状态”和“期望状态”的调谐(Reconcile)过程。这种调谐过程的实现者则是 Controller的处理逻辑。

当开发者对 Kubernetes 的使用逐渐增多之后,会发现这些默认的资源不足以支撑我们的系统,以 NginxIngress 为例,如果用户想要实现负载均衡限流器功能,目前 NiginxIngress 的配置不支持这样的特性,对于这种非通用的特性,Kubernetes提供了一种扩展性的支撑方式,即自定义资源。

典型地,声明式 API特点如下。

(1)你的 API 包含相对而言为数不多、尺寸较小的对象(资源)。

(2)对象定义了应用或者基础设施的配置信息。

(3)对象更新操作频率较低。

(4)通常需要人来读取或写入对象。

(5) 对象的主要操作是 CRUD风格的(创建、读取、更新和删除)。

(6) 不需要跨对象的事务支持:API 对象代表的是期望状态而非确切实际状态。命令式 API与声明式有所不同。 以下迹象表明你的 API可能不是声明式 API。

(1)客户端发出“做这个操作”的指令,之后在该操作结束时获得同步响应。

(2)客户端发出“做这个操作”的指令,并获得一个操作 ID,之后需要检查一个Operation对象来判断请求是否成功完成。

(3)将你的 API类比为 RPC

(4)需要较高的访问带宽(长期保持每秒数十个请求)。

(5)在对象上执行的常规操作并非是CRUD

(6) API 不太容易用对象来建模。

 

2. CRD场景

 

什么是 CRD呢?为什么要有 CRD资源呢?通过对下面内容的学习,大家会对 CRD有概念性的认识。首先   Kubernetes  为用户提供了丰富的资源,如资源对象、配置对象、存储对象和策略对象,如表 2-1所示。


 

表 2-1资源对象表

类别

名称

资源对象

Pod、ReplicaSet、Deployment、StatefulSet、DammonSet、Job、CronJob

配置对象

Node、Namespace、Service、ConfigMap、Ingress、Label

存储对象

Volume、Persistent Volume

策略对象

SecurityContext、ResourceQuota、LimitRange

 

虽然 Kubernetes 为我们提供了丰富的资源类型,但是在不同应用场景下,某些传统资源类型仍不能满足用户需求,他们对平台可能存在一些特殊的需求,为了满足这些需求,Kubernetes社区为我们提供了一种抽象Kubernetes的扩展资源。这种抽象的资源类型叫作自定义资源定义(CRD,Custom Resource Definition)。CRD为我们提供资源的快速注册和使用的接口。其实在很早的k8s 版本中自定义资源就已经被提出,当时叫作TPR(ThirdPartyResource),这是与CRD类似的概念,但是在1.9以上的版本中被弃用,而 CRD则进入 beta 状态。

(1)什么时候需要添加定制资源?

① 你希望使用 Kubernetes客户端库和 CLI 来创建和更改新的资源。

② 你希望 Kubectl 能够直接支持你的资源。

③ 你希望构造新的自动化机制,监测新对象的更新事件,并对其他对象执行 CRUD(增加、检索、更新、删除)操作,或者监测后者更新前者。

④ 你希望编写自动化组件来处理对对象的更新。

⑤ 你希望使用 KubernetesAPI对诸如 .spec、.status和 .metadata 等字段进行约定。

⑥ 你希望对象是对一组受控资源的抽象,或者对其他资源的归纳提炼。

(2)  如何定义一个 CRD?

我们通过代码清单 2-3中的 Yaml文件来创建一个 AppconfigCRD资源。

apiVersion:apiextensions.k8s.io/v1kind:CustomResourceDefinitionmetadata:

名称必须符合下⾯的格式 :<plural>.<group>

name:crontabs.stable.example.comspec:

# RESTAPI使⽤的组名称 :/apis/<group>/<version>

group:stable.example.com

# RESTAPI使⽤的版本号 :/apis/<group>/<version>versions:

-name:v1

可以通过served来开关每个版本

served:true

有且仅有⼀个版本开启存储

storage:trueschema:

openAPIV3Schema:

type:objectproperties:

spec:

type:objectproperties:

cronSpec:type:string

image:

type:stringreplicas:

type: integer# NamespacedCluster

scope:Namespacednames:

URL中使⽤的复数名称/apis/<group>/<version>/<plural>

plural:crontabs

CLI中使⽤的单数名称

singular:crontab

CamelCased格式的单数类型。在清单⽂件中使⽤

kind:CronTab

CLI中使⽤的资源简称

shortNames:


-ct

 

首先我们解释一下创建的 CRD 的参数。

① 第一行和第二行我们定义了 CRD的版本。

② metadata定义了访问的 CRD资源的名称,名称必须与下面的 spec字段匹配。

③ Spec.group 定义了资源属于什么组,这里我们定义成 stable.example.com。

④ Spec.versions 定义了资源存储的版本,这里定义为 v1。

⑤ scope定义了我们创建的资源的作用范围?这里定义成Namespace范围。

⑥ pluralsingular 定义了资源的单复数形式,这个根据实际情况命名即可。


我们执行 kubectlapply-fcrd.yaml就可以创建名称为 appconfig 的 CRD 资源了。同时我们定义的 CRD资源 RESTfulAPI将会定义成 /apis/stable.example.com/v1/namespaces/*/crontabs/。

(3)  如何创建一个CRD 实例对象?

首先定义一个符合上面CRD资源的apiVersion和资源类型(kind(见代码清单2-4)。

apiVersion:"stable.example.com/v1"kind:CronTab

metadata:

name:my-new-cron-objectspec:

cronSpec:"*****/5"

image:my-awesome-cron-image

 

创建 CRD对象后,可以创建自定义对象,自定义对象可包含自定义字段。这些字段可以包含任意  JSON。如代码清单2-4所示,cronSpec 和 image 自定义字段在自定义对象中设置 CronTab。CronTab类型来自上面创建的 CRD对象的规范,然后执行kubectleapply-fmy-crontab.yaml即可。

上一篇:模块"XX"可能与您正在运行的Windows版本不兼容。检查该模块是否与regsvr32.exe的x86或x64版


下一篇:苹果新专利曝光,让自动驾驶汽车警报系统与电子设备无缝连接