自定义服务CSD
在不同业务环境下,服务对平台有着不同的诉求,Kubernetes提供自定义资源CRD的轻量化机制。而在实践过程中,发现对于服务能力如服务依赖、服务访问、服务部署、监控日志等公共能力欠缺。
因此围绕CRD自研CSD,通过声明式配置CRD的能力引用,增强服务治理能力。
CSD本身属于CustomServiceDefinition类型的资源,其符合k8s资源的通用定义方法。其apiVersion和kind是固定的,metadata.name可自行配置:
apiVersion: osc.io/v1beta1 kind: CustomServiceDefinition metadata: name: kafka-csd
CSD的spec包含下面的配置:
配置项 |
配置描述 |
必填 |
---|---|---|
CRDRef |
通过apiVersion,kind以及matadata.name三个字段关联同一目录下的某个CRD资源 |
是 |
displayName |
所属CRD名称 |
否 |
description |
所属CRD描述 |
否 |
role |
描述CRD角色,取值范围为{serviceEntity, operation},大小写敏感,默认为serviceEntity。 |
否 |
capabilityRequirements |
平台能力引用配置 |
否 |
serviceEntityDependencies |
服务依赖配置 |
否 |
descriptors |
服务安装时参数展示的UI控件定义 |
否 |
versionDefinition |
服务实例版本定义 |
否 |
defaultConfiguration |
CRD的CR示例 |
否 |
role
在Openshift Operator Framework规范中,开发者定义的各类CRD资源都是对等的,没有更进一步的划分,但从实际的功能属性上来说,很容易识别出,不同CRD所处的层级和使用场景并不相同,以etcd为例,可能定义有代表服务主体本身的etcd CRD,以及表示etcd备份的backup CRD,两者客观上存在从属和依赖关系。所以,平铺的定义方式并不能很好的体现这种资源的层级和保证用户体验,在这个维度进行了细化,把CRD的功能和应用场景,按其角色分为以下两类:
- serviceEntity: 服务实体类资源,即提供如etcd实例CRD定义。
- operation:运维功能类,服务实例安装后以独立页签的形式展示,用户可以浏览已有的operation实例以及主动下发新的operation实例,如etcd backup CRD。
其中operation属于服务实体资源的能力(Capability)范畴,与serviceEntity相比只是行为方式上有所不同。
特别地,认为Helm服务的场景是一个最基本的,只包含一个serviceEntity资源定义的场景。Operator则可以包含多个不同角色的CSD,服务包在转换为OSC服务包后,用户需要对不同角色的CRD对应的CSD文件进行定制化的配置。
capabilityRequirements
- 配置能力引用需要在csd文件中声明capabilityRequirements。
- 能力引用只支持引入operator类型的平台能力,即平台提供的包括监控、日志等的公共能力。
- 可通过defaultPath配置文件路径,统一配置到vendor目录下。
capabilityRequirements配置样例
# 能力引用配置 capabilityRequirements: - apiVersion: osc.io/v1 # 引用平台监控capability kind: MonitorConfig defaultPath: vendor/monitor_config.yaml - apiVersion: osc.io/v1 # 引用平台日志capability kind: LogConfig defaultPath: vendor/log_config.yaml
参数名称 |
参数描述, |
参数示例 |
必填 |
---|---|---|---|
apiVersion |
所引用的能力的配置版本,固定值osc.io/v1 |
osc.io/v1 |
是 |
kind |
所引用的能力的配置类型,范围列表MonitorConfig|LogConfig |
MonitorConfig |
是 |
defaultPath |
默认配置文件路径,路径为vendor目录 |
vendor/monitor_config.yaml |
是 |
serviceEntityDependencies
- 配置服务依赖需要在csd文件中配置serviceEntityDependencies。
- 仅支持对公有服务的依赖,不支持依赖私有服务。
- defaultPath为依赖实例的配置文件,会覆盖服务自带配置。
serviceEntityDependencies配置样例
# 服务依赖 serviceEntityDependencies: - service: rdsService # 依赖operator类型的RDS实例 apiVersion: rds.io/v1alpha1 kind: rds defaultPath: vendor/rds_provider.yaml - service: redisService # 依赖Helm类型的Redis实例,apiVersion、kind不配置 defaultPath: vendor/redis_service_values.yaml # redis的values.yaml文件
参数名称 |
参数描述 |
参数示例 |
必填 |
---|---|---|---|
service |
所依赖的服务的名称 |
rdsService |
是 |
apiVersion |
所依赖的服务的配置版本 |
rds.io/v1alpha1 |
否 |
kind |
所依赖的服务的配置类型 |
rds |
否 |
defaultPath |
默认配置文件路径,统一配置在vendor目录下。 |
参见样例 |
是 |
- rds_provider.yaml
apiVersion: osc.io/v1 kind: rds spec: ...
- redis_service_values.yaml
apiVersion: osc.io/v1 kind: redis spec: global: imageRegistry: "" imagePullSecrets: [] clusterDomain: cluster.local resources: limits: {} requests: {}
descriptors
descriptor字段用于配置UI控件,提升部署服务的用户体验,对服务参数进行控件增强,包括服务规格spec和服务状态status。该控件为可选项。
# UI控件 descriptors: spec: - description: "kafka实例个数" displayName: 集群大小 path: {kafka.replicas} restriction: scenes: - CCE x-descriptors: - "urn:alm:descriptor:com.tectonic.ui:podCount" status: - description: "kafka实例个数" displayName: 集群大小 path: {kafka.replicas} restriction: scenes: - CCE x-descriptors: - "urn:alm:descriptor:com.tectonic.ui:podCount"
参数名称 |
参数描述 |
必填 |
---|---|---|
displayName: |
控件显示名称 |
是 |
description |
控件显示描述 |
是 |
path |
控件对应字段,描述的对象上字段的点分隔路径,例如globalConfig1.field1 |
是 |
restriction |
如果不同的部署的场景需要不同的控件配置,可配置此字段,支持CCE、UCS两种配置,分别表示云容器引擎和华为云UCS场景 |
否 |
x-descriptors |
控件类型,具体参考配置表单控件了解相关配置 |
是 |
versionDefinition
实例版本定义配置是在csd文件中配置versionDefinition。
- versionDefinition配置tag样例如下。
versionDefinition: mode: tag path: spec.kafka.image tags: - 1.1.1 - 2.2.2 - 3.3.3 - 9.9.9
- versionDefinition配置url样例如下。
versionDefinition: mode: url path: spec.kafka.image tags: - 1.1.1 - 2.2.2 - 3.3.3 - 9.9.9
defaultConfiguration: |-{ .... ... "spec": { "kafka": { "config": { }, "image": "example:1.1.1" "nodeIps": [], "nodeSelector": {}, "podAntiAffinity": true, "ports": { "bootstrapServer": 9092, "prometheus": 9404 }, "replicas": 3, "storageSize": "8Gi" } } }
参数名称 |
参数描述 |
参数示例 |
必填 |
---|---|---|---|
description |
单击升级时的提示信息,知会用户进行实例升级的注意事项 |
您可以直接升级到最新版本,升级期间会发生5s之内的连接闪断,请确认应用程序具备重连机制 |
否 |
mode |
实例的镜像格式,当前仅支持url、tag这两种格式 |
取值范围固定为[url、tag]
|
必填, 当mode配置之后,path和tags就成了必填项 |
path |
实例镜像替换路径,位于defaultConfiguration字段下的值 |
例如,path值配置为"spec.kafka.image",则需要替换的值是"example:1.1.1" |
必填 |
tags |
实例镜像tag版本号列表。建议使用引号,否则YAML会将类似2.0的tag版本号识别为浮点数。
注意:
配置在tags下的实例版本号默认都是兼容的实例版本,即这些版本之间能进行互相升级。不兼容的版本号配置在tags列表下会造成升级完成之后实例功能有问题。 |
以实例镜像文件为test-x86_64-2.0.1.20210929123638.tar为例, 实例镜像文件通过docker load -i test-x86_64-2.0.1.20210929123638.tar执行完成之后,会在控制台回显如下信息: Loaded image: test-x86_64:2.0.1.20210929123638 则tag版本号为2.0.1.20210929123638,如果有多个版本镜像,则都可以通过此方式获取tag版本号, 然后将这些tag版本号配置在tags下面 |
必填 |
对于lifecycle文件中配置了upgrade字段的服务包,需要确保versionDefinition字段与被升级的operator的所管理的实例相兼容,否则会导致上传服务包或升级服务operator失败,具体规则如下:
1. 在上传服务包阶段,upgrade.replaces字段指定的被升级operator的versionDefinition字段为空时,允许上传服务包;不为空时,新的versionDefinition.tags需要与其有交集才能发布。
2. 在服务operator升级阶段,被升级的operator当前管理的实例版本必须都在新的versionDefinition.tags列表中,否则不允许升级,需要确认新版本的operator是否能够管理这些实例,如果可以,则修改versionDefinition后重新上传服务包,否则需要删除不兼容的实例后再升级。
apiVersion: osc.io/v1beta1 kind: CustomServiceDefinition metadata: name: kafka-csd spec: # 通过CRDRef将此CSD跟同一文件夹下的某个CRD相关联 CRDRef: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: kafkas.osc.huawei.com # CRD显示名字 displayName: kafka # CRD 描述 description: kafka Description # CRD的角色 role: serviceEntity # 公共能力引用(只针对平台能力引用) capabilityRequirements: - apiVersion: osc.io/v1 # 引用平台监控能力 kind: MonitorConfig defaultPath: vendor/monitor_config.yaml - apiVersion: osc.io/v1 # 引用平台日志能力 kind: LogConfig defaultPath: vendor/log_config.yaml # 服务依赖 serviceEntityDependencies: - service: rdsService apiVersion: rds.io/v1alpha1 # 依赖operator格式的RDS kind: rds defaultPath: vendor/rds_provider.yaml - service: redisService # 依赖Helm格式的redisService defaultPath: vendor/redis_service_values.yaml # redis的values.yaml文件 # UI控件 descriptors: spec: - description: "" displayName: "" path: {crd-name.replicas} x-descriptors: - "urn:alm:descriptor:com.tectonic.ui:podCount" status: - description: "" displayName: "" path: {crd-name.replicas} x-descriptors: - "urn:alm:descriptor:com.tectonic.ui:podCount" # CRD对应的CR样例 defaultConfiguration: |-{ "apiVersion": "osc.huawei.com/v1", "kind": "Kafka", "metadata": { "annotations": { "osc.io/occupied-port": "135,139" }, "name": "kafka-sample", "namespace": "kfk", "finalizers": [ "kafka.finalizers.osc.huawei.com" ] }, "spec": { "kafka": { "config": { }, "image": "xxx/xx/aa:1.0" "nodeIps": [], "nodeSelector": {}, "podAntiAffinity": true, "ports": { "bootstrapServer": 9092, "prometheus": 9404 }, "replicas": 3, "storageSize": "8Gi" } } } # 服务实例升级 versionDefinition: description: 您可以直接升级到最新版本,升级期间会发生5s之内的连接闪断,请确认应用程序具备重连机制 mode: url path: spec.image tags: - "2.7.0" - "2.7.1" - "2.7.2"