更新时间:2024-06-13 GMT+08:00
分享

自定义服务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包含下面的配置:

表1 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
 
    
    
表2 capabilityRequirements配置

参数名称

参数描述,

参数示例

必填

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文件
表3 serviceEntityDependencies配置

参数名称

参数描述

参数示例

必填

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。该控件为可选项。

descriptors样例:
# 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"
表4 descriptors配置

参数名称

参数描述

必填

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"
          }
        }
      }
表5 versionDefiniton配置

参数名称

参数描述

参数示例

必填

description

单击升级时的提示信息,知会用户进行实例升级的注意事项

您可以直接升级到最新版本,升级期间会发生5s之内的连接闪断,请确认应用程序具备重连机制

mode

实例的镜像格式,当前仅支持url、tag这两种格式

取值范围固定为[url、tag]

  • mode配置为url,则会将上述所示defaultConfiguration字段下的"image"字段的值替换为"example:2.2.2"
  • mode配置为tag后,则会将上述所示defaultConfiguration字段下的"image"字段的值替换为"2.2.2"

必填, 当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后重新上传服务包,否则需要删除不兼容的实例后再升级。

示例:csd.yaml完整示例,以kafka为例。
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"

相关文档