自定义服务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"