对接手册

一、编写目的

方便用户快速了解和使用CICD管理系统,节省人工辅导成本。

二、适用范围

1、锐明

备注:内部文档,禁止外传

三、产品介绍

3.1、名词解释

序号概要名词说明
1CICD管理系统面向研发、测试、运维等不同角色的综合平台,整合软件开发、测试和部署各阶段的繁琐流程。通过可视化、配置化、一键化操作,实现DevOps持续交付,提高研发效率、降低成本,并支持云环境与客户私有化部署,尽量减少人工干预。
2私有化运维交付系统
针对运维及前线技术支持/专家设计,按环境维度管理客户局点。该系统从 CICD管理系统 获取发布后的中间件或业务组件包,支持安装、升级、变量同步等运维操作,确保产品部署后达到就绪状态
3客户交付系统
集中管理所有客户的部署模型信息,对接开发内部的统一网关和用户中心,与运营平台打通。同时联动 私有化运维交付系统,实现从部署模型配置到日常运维的全流程一站式管理
4OMS
为「Operation and Maintenance System」的缩写, 专职负责部署工作.
OMS = OMS Server + OMSlet
5CDS
为「Customer Delivery System」的缩写, 客户交付系统系统
6cicd-web
CICD管理系统 的前端组件,负责展示及交互。
7cicd-server
CICD管理系统 的后端组件,通过HTTP接口为 cicd-web 提供服务,主要负责基础信息管理,采用Java开发。
8oms-server
CICD管理系统私有化运维交付系统 共用。它提供HTTP接口,负责运维部署动作的编排与执行,上游对接 cicd-server 和 custom-server,采用Python开发。
9oms-let
安装在目标机上的轻量级代理,封装Shell脚本、加固系统配置,并负责部分常用软件包的安装。通过HTTP接口接收OMS Server下发的命令,采用Shell脚本开发。
10host-baseline
安装在目标机上, 提供系统级文件, 尽可能屏蔽系统差异. 无运行态, 开发语言: Shell.
11cicd-document-web
CICD管理系统 的帮助文档, 属于前端组件。
12jenkins
专用于 CICD管理系统, 利用其Pipeline Job承接流水线的sonar扫描、编译构建、组装包、发版及代码覆盖率等任务.
13COS
CICD管理系统 中的物料库,使用腾讯云的cos对象存储,统一存放组件包,项目版本包,流水线集成包,证书文件等.

3.2、解决方案总览

3.2.1、逻辑视图

CICD管理系统 由5个逻辑组件组成,如下:

  1. CICD管理系统: 有单独的web管理界面配套, 云环境下的操作入口。

  2. Jenkins: 负责实际的流水线执行, 输出物料(即包文件)。

  3. 物料库: 统一存放物料(一般为构建好的包文件)。

  4. OMS Server: 运维管理系统的服务端, 单独剥离运行以兼容云环境&客户私有化环境的部署。

  5. Machine XXX: 具体部署业务组件的机器节点, 与OMS Server配套使用。

各逻辑组件的关系如图:

逻辑视图

3.2.2、部署视图

部署视图

3.3、CICD管理系统(单品)介绍

CICD管理系统 作为整个解决方案系统门户,提供可视化、可编排的CI/CD持续交付软件生产线,实现DevOps持续交付高效自动化,缩短应用开发到市场交付周期,提升研发效率。

流水线服务本质上是一个可视化的自动化任务调度平台,需要配合服务器中编译构建、代码检查、测试、部署等服务的自动化任务使用。根据需要的场景,如开发测试环境应用部署、生产环境应用部署等,对这些自动化任务进行自定义编排,一次配置后就可以一键自动化触发调度执行,避免频繁低效的手工操作。

3.3.1、业务流程图

业务流程图

四、平台对接

4.1、C++组件接入

如下,以mms组件接入示例 1.代码新增cicd/descriptor.yml,参考5.3.1 组件描述符

C++组件接入图

2.代码新增cicd/compile_dependency.yml,参考5.3.8 依赖项

C++组件接入图

3.代码新增cicd/nacos/mms_application.properties

C++组件接入图

4.代码新增cicd/mariadb/init_s17_mms.sql

C++组件接入图

5.代码新增cicd/assemble.sh

C++组件接入图

注:assemble.sh的组件名(COMPONENT_NAME)及组件版本号(COMPONENT_VERSION可使用 $1,$2来代替。$1,$2值在jenkins 构建时注入,$1="mms",$2="V3.0.15",需要注意最终与编译文件名称是否匹配。

4.2、Java组件接入

如下,以djms组件接入示例

1.代码新增cicd/descriptor.yml,参考5.3.1 组件描述符

说明:组件描述符中集群变量可参考原package_define.yml集群变量

Java组件接入图

2.代码新增cicd/nacos/djms_application.properties(使用规则可参考5.3.3 Nacos初始化

Java组件接入图

3.代码新增cicd/mariadb/init_s17_djms.sql(数据库初始化脚本,可参考5.3.2 数据库初始化

Java组件接入图

4.调整assemble.xml配置

Java组件接入图

5.调整maven打包后压缩包名称, 规范: ${组件名}-${组件版本}.tar.gz, eg: djms-3.0.15.2-SNAPSHOT.tar.gz

Java组件接入图

6.代码新增 cicd/assemble.sh(打包脚本,java中仅做组件包的拷贝,打包由maven完成,拷贝组件包到指定文件夹以满足对接规范) Java组件接入图

assemble.sh示例

#!/bin/bash

# 构建组件包的shell脚本, 组件包仅要求后缀名为"tar.gz", 文件名不做限制. e.g. xxxxabcxxx.tar.gz

# 当前脚本目录
CURRENT_DIR=$(dirname "$0")
# 当前脚本目录绝对路径
CURRENT_DIR_ABSOLUTE_PATH=$(realpath "$\{CURRENT_DIR\}")
# 组件名-eg:djms
COMPONENT_NAME="djms"
# 组件版本号-V3.15.2
COMPONENT_VERSION="3.0.15.2"
# 组件文件名(含后缀)
COMPONENT_FILE_NAME="$\{COMPONENT_NAME\}-$\{COMPONENT_VERSION\}.tar.gz"

# 组装组件包, 对于Java工程, 大部分项目都用了assembly插件输出.tar.gz, 因此可以直接拷贝过来
cp -a "$\{CURRENT_DIR_ABSOLUTE_PATH\}/../target/$\{COMPONENT_NAME\}-$\{COMPONENT_VERSION\}-SNAPSHOT.tar.gz" "
注:assemble.sh的组件名(COMPONENT_NAME)及组件版本号(COMPONENT_VERSION可使用 $1,$2来代替。$1,$2值在jenkins 构建时注入,$1="djms",$2="V3.0.15.2",需要注意最终与编译文件名称是否匹配。

4.3、前端组件接入

如下,以cicd-web组件接入示例

1.项目内添加config.ini.j2、config.runtime.js.template.j2文件\

config.ini.j2:对应原有的config.ini文件。原有config.ini由jenkins打包时前端脚本生成,对接cicd后config.ini文件将由cicd通过config.ini.j2模板生成。

前端组件接入图

2.config.runtime.js.template.j2:对应原有的config.runtime.js.template文件

前端组件接入图

3.添加script脚本(采用原有前端项目jenkins工作空间中的通用脚本)

前端组件接入图

4.添加cicd文件夹。内容包含组件描述符descriptor.yml和打包脚本assemble.sh

组件描述符descriptor.yml

前端组件接入图

5.打包脚本assemble.sh

前端组件接入图

#!/bin/bash

# 构建组件包的shell脚本, 组件包仅要求后缀名为"tar.gz", 文件名不做限制. e.g. xxxxabcxxx.tar.gz

# 当前脚本目录
CURRENT_DIR=$(dirname "$0")
# 当前脚本目录绝对路径
CURRENT_DIR_ABSOLUTE_PATH=$(realpath "$\{CURRENT_DIR\}")
# 组件名
COMPONENT_NAME="cicd-web"
# 组件版本号
COMPONENT_VERSION="V1.0.3"
# 组件文件名(含后缀)
COMPONENT_FILE_NAME="$\{COMPONENT_NAME\}-$\{COMPONENT_VERSION\}.tar.gz"

cd "$\{CURRENT_DIR_ABSOLUTE_PATH\}/.."
mkdir cicd
cp -aRf ./component/* ./cicd/
tar -zcvf "$\{COMPONENT_FILE_NAME\}" dist nginx.conf config.properties config.ini.j2 script bin config.runtime.js.template.j2 cicd
mv "$\{COMPONENT_FILE_NAME\}" "$\{CURRENT_DIR_ABSOLUTE_PATH\}"

注:assemble.sh的组件名(COMPONENT_NAME)及组件版本号(COMPONENT_VERSION可使用 $1,$2来代替。$1,$2值在jenkins 构建时注入,$1="cicd-web",$2="V1.0.3",需要注意最终与编译文件名称是否匹配。

4.4、升级支持接入步骤

4.4.1、 代码对接

4.4.1.1、 前端服务

1、基于目标版本拉取对接分支

示例:

基于对接版本拉新分支 fms目标分支: V3.15.5-cicd 原分支(对接版本): 3.0.15.5

前端服务图

2、合并上次对接分支代码

主要合并cicd文件夹

前端服务图

3、修改打包脚本文件中版本号

文件路径:cicd\assemble.sh

前端服务图

4.4.1.2、java后端服务

1、基于目标版本拉取对接分支

示例:

基于对接版本拉新分支 fms目标分支: V3.15.5-cicd 原分支(对接版本): 3.0.15.5

java后端服务图

2.合并上次对接分支代码

主要合并cicd文件夹和assembly.xml

java后端服务图

如存在${组件名}_application.properties文件配置变更,直接替换。

目标文件路径:cicd\nacos${组件名}_application.properties

java后端服务图

3.修改打包脚本文件中版本号

文件路径:cicd\assemble.sh

java后端服务图

4.sql文件调整 说明:sql文件存储路径cicd\mariadb

init_${数据库名}_fms.sql:数据库初始化文件,对应descriptor.yml中的mariadb_config

update_${版本号}.sql:对应某个版本的sql变动文件,如该版本无sql变更则无需创建该文件(本次对接的版本与上次cicd对接版本若存在sql变更,两个版本期间的所有sql变更合并为一个sql文件,统一命名为update_${当前对接的版本号}.sql)

实例:

java后端服务图

4.5、操作指南

1.界面新建团队(已有团队则跳过)

操作指南图

2.界面新建组件

操作指南图

3.界面新建组件版本

操作指南图

五、对接改造方案详解

CICD内部逻辑宏观上分为三个大步骤: 基础信息配置打包部署, 每一步都需要遵循相应的规范. 组件包文件涉及规范的目录结构如下:(详细解释参考下述章节)

- $\{根目录\}
    cicd # 位于打包文件的根目录, CICD系统所需的输入都统一存放于该文件夹
    ├── assemble.sh              # [必填] 打包脚本
    ├── compile_dependency.yml   # [选填] 仅适用于C++项目, 声明库依赖
    ├── descriptor.yml           # [必填] 组件描述符
    ├── mariadb                  # [选填] 初始化数据库所需的sql文件
    │   └── init_s17_mms.sql
    └── nacos                    # [选填] 初始化nacos所需的dataId
        └── mms_application.properties
    script # 位于打包文件的根目录, 与OMSlet交互, 负责日常运维操作
    ├── install.sh                  # 安装脚本
    ├── start.sh                    # 启动脚本  
    ├── stop.sh                     # 停止脚本
    ├── uninstall.sh                # 卸载脚本
    ├── guard.sh                    # 守护脚本
    ├── health.sh                   # 健康检查脚本
    ├── pid.sh                      # 获取进程号脚本

5.1、C++组件接入基础信息配置(cicd-web负责)

流水线的输入源均为 组件, 组件的获取目前强制从git仓库拉取. 因此前置web界面中必须正确配置:

1). git地址, 操作入口: 版本管理 -> 组件管理

操作界面参考: 使用手册 4.3.1

2). git分支, 操作入口: 版本管理 -> 组件版本管理

操作界面参考: 使用手册 4.5.1

5.2、jenkins构建上下文

CICD在构建时提供了上下文文件供业务组件作为构建参数使用:

1、jenkins构建时,会在目标项目代码顶层目录同级追加文件cicd_output/context_info.txt

2、context_info.txt内容:

componentName=s17-upgrade # 【必填】
componentVersionName=V3.18.1 # 【必填】
branchName=V3.18.1-release  # 【必填】字符串,当前构建防止
bizName=pipeline | coverage # 【必填】字符串枚举值,pipeline: 流水线构建  coverage:代码覆盖率触发

3、jenkins构建临时目录完整示例:/iotp/data/cicd_custom_workspace/pipelineEnvCmpId_10092/git_source_code/cicd_output/context_info.txt

5.3、打包(Jenkins负责)

不同语言类型的项目, 其打包方式不一样. 如 JavaNode 均有成熟的版本依赖以及打包工具, 而 C++ 类型项目需要手动配置头文件及依赖的库文件. 因此对于CICD系统, 在打包环节不会限制具体的使用方式, 仅在拉取git代码并构建后, 配合界面流水线流程配置中的打包任务即 组装组件包, 才会最终生成组件包文件.

组装组件包 任务内会固定调用相对(git代码仓库)路径为 cicd/assemble.sh 的shell文件, 输出的组件包文件也放至cicd文件夹内, 名称及类型为: $\{组件名称\}-$\{组件版本号名称\}.tar.gz.

Note: 打包好的组件包文件会存放至物料库, OMS-Server 做实际的部署操作时内部会自行根据部署描述符转换为物料坐标, 根据物料坐标从物料库获取组件包文件.

5.4、部署(OMS Server负责)

5.4.1、组件描述符

组件描述符文件相对路径为 $\{根目录\}/cicd/descriptor.yml, 其作用是统一记录对接cicd过程中需要配置的信息(需涵盖老CICD的 local_package_define.ymlpackage_define.yml 两个文件的配置,国产化配置也维护到此文件), 格式为yml. 示例:

# 必填: 预留, 运维管理系统开放API版本.
apiVersion: "v1"
# 必填: 表示当前对象, 目前可选范围:Component(组件)、Deployment(部署)
kind: "Component"
# 必填: 标识出当前组件是三级研发的哪种类型: env | base | standard | custom
level: "base"
# 必填: 当类型为Component时, 这里表示组件名称
name: "mms"
# 选填: 元数据, KV形式, 自定义
metadata:
  key1: "value1"
# 必填: 期望该对象的规格(静态信息)
spec:
  # 选填: 文件操作信息
  # 当组件自身为集群模式(有多个实例)部署时, 文件操作执行时间点在所有实例开始部署前.
  # 当有多个文件操作声明时, 执行顺序为:按本YAML文件内声明的顺序串行执行
  file_operations:
      # 必填, 文件操作类型, 取值范围: remove-文件移除, copy-文件拷贝
      # 视文件操作类型不同, 声明的字段名不同, 具体参考下方备注
    - type: remove
      # 如下为适用于操作类型为 remove 的字段
      # 必填, 标识待操作对象
      object_to_be_operated:
        # 必填, 需要操作的组件名.
        # e.g: 部署组件A时, 需要删除组件B所部署机器上的路径path1, 那么这里 service_name 填写 组件B 即可
        service_name: "base-server-service"
        # 选填, 当 service_name 有多个实例(即部署在多个机器上)时, 标识具体操作哪些机器
        # 取值范围: all - 所有主机, random - 随机取一台, first - 第一台, last - 最后一台
        # PS: first 和 last的语义为按照主机的ip(一般为内网)做字符串排序后,取第一个/最后一个
        # 默认值: all
        hosts: "all"
        # 必填, 待操作的文件路径, 说明:
        # * 必须以 /iotp/ 开头
        # * 路径信息支持通配符(通配符格式与Linux上的rm命令所支持的通配符保持一致)
        # * 通配符部分仅做用于最后一段文件uri. 除最后一段uri外, 不支持Linux特殊的 . 和 .. 标识符
        # * 仅支持文件, 不支持文件夹
        abs_path: "/iotp/plugin/demo-sdk-V*.jar"
      # 选填, 当依据上述信息识别的路径为空时, 需要采取的措施
      # 取值范围: ignore - 忽略, logWarning - 记录一个警告日志信息, reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: ignore
      on_path_not_exists: "ignore"
      # 选填, 有做实际的文件操作, 但文件操作的结果失败时, 需要采取的措施
      # 取值范围: ignore - 忽略, logWarning - 记录一个警告日志信息, reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: reportFailureAndAbort
      on_operation_failure: "reportFailureAndAbort"
      # 选填, 文件操作超时时间, 单位:秒.  超时后, 流程报错阻断
      # 默认值: 60
      time_out: 60

    - type: copy
      # 如下为适用于操作类型为 copy 的字段
      # 必填, 需要拷贝的源文件路径 说明:
      # * 该路径为相对于当前组件最终打包态内的相对路径,并非代码态(git仓库内)的相对路径
      # * 为强制相对路径概念, 必须以 "./" 开头
      # * 目前不支持通配符, 必须是一个精确的路径
      # * 解析后的路径目前不支持文件夹, 必须是一个文件
      src_file_relative_path: "./libs/bus-sdk-V3.16.0.jar."
      # 选填, 当依据上述信息识别的源路径为空时, 需要采取的措施
      # 取值范围: ignore - 忽略, logWarning - 记录一个警告日志信息, reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: reportFailureAndAbort
      on_src_path_not_exists: "reportFailureAndAbort"
      # 必填, 标识待操作目标对象
      target_object_to_be_operated:
        # 必填, 需要操作的组件名.
        # e.g: 部署组件A时, 需要将文件file1拷贝至组件B所部署机器上的路径path1, 那么这里 service_name 填写 组件B 即可
        service_name: "base-server-service"
        # 选填, 当 service_name 有多个实例(即部署在多个机器上)时, 标识具体操作哪些机器
        # 取值范围: all - 所有主机, random - 随机取一台, first - 第一台, last - 最后一台
        # PS: first 和 last的语义为按照主机的ip(一般为内网)做字符串排序后,取第一个/最后一个
        # 默认值: all
        hosts: "all"
        # 必填, 指定需要拷贝的目标文件路径, 说明:
        # * 必须以 /iotp/ 开头,
        # * 必须是绝对路径, 不支持路径通配符
        abs_path: "/iotp/plugin/demo-sdk-V3.16.0.jar"
      # 选填, 当依据上述信息识别的目标路径已存在(且类型是文件)时, 需要采取的措施
      # 取值范围: ignore - 忽略(不会做文件拷贝动作)
      #          logWarning - 记录一个警告日志信息(不会做文件拷贝动作)
      #          overwrite - 记录一个警告日志信息, 并覆盖目标机器已存在的文件
      #          reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: overwrite
      on_target_path_exists: "overwrite"
      # 选填, 有做实际的文件操作, 但文件操作的结果失败时, 需要采取的措施
      # 取值范围: ignore - 忽略, logWarning - 记录一个警告日志信息, reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: reportFailureAndAbort
      on_operation_failure: "reportFailureAndAbort"
      # 选填, 文件操作超时时间, 单位:秒.  超时后, 流程报错阻断
      # 默认值: 60
      time_out: 60

  # 选填: 依赖的中间件组件(非业务组件)
  dependencies_middleware_component:
      # 必填: 中间件名称
    - name: "mariadb"
      # 版本: 组件版本
      version: "V10.5.15"
    - name: "nacos"
      version: "V2.0.4"
    - name: "redis"
      version: "V6.2.6"

  # 选填: 需要执行的数据库初始化信息
  mariadb_config:
    # 此服务访问Mariadb的用户,切记不是root用户
    user: "mms"
    # 组件在运行过程中, 程序内访问达梦数据库的用户(非必填,若为空则使用user完成达梦数据库的用户创建及赋权),切记不是root用户
    dm_user: "s17_mms"
    # 此服务访问Mariadb的用户对应的密码
    password: "ENC#jkJNanq1Tn6Tt4N+hqFvtt461dBh+0jdRTkv#"
    # 数据库初始化脚本(顺序执行)
    # 文件名称为init_数据库名.sql
    # 组件在运行过程中,程序内需要访问的数据库schema名称(对用户做此数据库的赋权操作,同时做数据库初始化), 支持多个数据库(但不推荐).
    database:
        # 数据库名
      - "s17_mms"
    # 文件名称为init_数据库名.sql
    grant_database:
        # 数据库名
      - "s17_oms"

  # 选填: 需要执行的nacos初始化信息
  nacos_config:
    # 在父节点内选填: 初始化模式, 取值范围: generated, custom.  未指定时默认为 generated
    # generated: 兼容现有ansible的接入规范, 由框架自动创建namespace、group、dataId 以及客户端的 bootstrap.properties
    #           dataId生成如下三类: ${componentName}_application.properties, ${componentName}.properties, ${componentName}_${ip}.properties
    # custom: 由组件自身指定namespace、group以及dataId的创建, 检测组件包cicd中是否存在nacos文件夹, 若有则按如下标准上传
    #         cicd/nacos/${namespace}/${group}/${dataId}.properties
    #         其中${dataId}.properties可为j2模板文件, 以支持变量替换
    mode: "generated"

  # 选填: 执行的clickhouse初始化信息
  clickhouse_config:
    # 此服务对应的数据库名称,数组格式,支持多个数据库
    database:
      - "base_reports_data"       # 数据库名, 文件名称为init_数据库名.sql
      - "mock_base_reports_data"

  # 选填: 需要进行jinja2变量替换的文件, 路径从打包文件的根目录开始
  template_files:
    - "jinja2_test_folder/application.properties.j2"
    - "jinja2_test_folder/sub_folder1/afterMigrateError.sql.j2"

  # 选填: 标识当前组件的 监听端口 和 需要在linux系统中保留的端口信息
  ports:
      # 必填: 端口名称
    - name: "httpListeningPort"
      # 必填: 类型, 取值范围: listen - 监听类型端口, reserved - 保留类型端口.
      # 无论何种类型, 都将添加至linux中的保留端口中 (net.ipv4.ip_local_reserved_ports)
      type: "reserved"
      # 必填: 单个6606  端口段6606-6608  多个6606,6607,6608
      value: 8099
      # 选填(推荐填写): 端口用途描述
      desc: "http通信端口"

  # 选填: 集群变量定义
  cluster_variables:
      # 必填: 变量名
    - name: "someVar"
      # 必填: 变量描述
      desc: "some description"
      # 必填: 取值
      value: "some value"

  # 选填: 实例变量定义
  instance_variables:
      # 必填: 变量名
    - name: "someVar"
      # 必填: 变量描述
      desc: "some description"
      # 必填: 默认值
      value: "some value"
5.4.1.1、apiVersion

必填, 预留字段, 用于标识组件描述符的版本. 目前固定取值为 v1

5.4.1.2、kind

必填, 用于区分是 部署描述符 还是 组件描述符. 组件描述符取值固定为 Component Note: 部署描述符为 cicd-server 与 OMS-Server 之间交互的数据, 对于接入方无需关注.

5.4.1.3、level

必填, 标识当前组件属于三级研发的哪一层, 取值范围(大小写敏感): env - 环境/中间件, base - 基础组件, standard - 行业标准组件, custom - 行业定制组件

5.4.1.4、name

必填, 组件名称. 必须与界面配置的组件名称相同

5.4.1.5、spec.dependencies_middleware_component

选填, 依赖的中间件列表. 每项指定中间件名称(name)及版本(version), 具体填写内容可在界面参考”CICD团队”内的组件. OMS-Server在部署过程中, 会对组件描述符中所声明的中间件依赖项, 以及界面中项目所关联的组件来做匹配逻辑, 当且仅当两边声明一致时才会自动安装所依赖的中间件. 目前支持的中间件如下:

名称 / name版本 / version备注
database(mariadb)V10.5.15 数据库依赖后续统一写database,不写具体的数据库名称,已有组件依赖的mariadb无需改动cicd自动适配。 应用场景:中间件环境部署的mysql/dmserver时,cicd校验依赖中间件时将自动适配为校验mysql/dmserver是否已安装。
nacosV2.2.3 支持X86/ARM双架构架构中间件 控制台默认账户密码: nacos/IOTP-socan#2970
V2.2.3
redisV6.2.6 支持X86/ARM双架构架构中间件
redis-sentinelV6.2.6 支持X86/ARM双架构架构中间件
zookeeperV3.8.4 支持X86/ARM双架构架构中间件
kafkaV3.7.1 支持X86/ARM双架构架构中间件
nginxV17.239.58 支持X86/ARM双架构架构中间件
clickhouse-serverV22.2.3.5 支持X86/ARM双架构架构中间件
minioV2023-02-27
nodeV10.24.0 支持X86/ARM双架构架构中间件
assets-engineV2.0.0 支持X86/ARM双架构架构中间件
flinkV1.13.6
milvusV2.3.10
vsftpdV3.0.2
dmserverV8.0.0 ARM架构中间件
admqV3.0.5 ARM架构中间件
5.4.1.6 spec.database_config

说明:为以往的mariadb_config功能迁移,是数据库初始化信息(不具体到实际的数据库中间件),同时兼容以往的mariadb_config,已有组件可不做调整。

选填, 声明需要执行的数据库初始化信息。

dm_user: 组件在运行过程中, 程序内访问达梦数据库的用户(非必填,若为空则使用user完成达梦数据库的用户创建及赋权),切记不是root用户

user: 组件在运行过程中, 程序内访问数据库的用户,切记不是root用户

password: 组件在运行过程中, 程序内访问数据库的密码,根据安全规范,请使用jasypt加密字符串(目前已支持数据库密文密码), 切记不是root用户的密码

database: 组件在运行过程中,程序内需要访问的数据库schema名称(对用户做此数据库的赋权操作,同时做数据库初始化), 支持多个数据库(但不推荐).

grant_database: 组件在运行过程中,程序内需要访问的数据库schema名称(对用户做此数据库的赋权操作,同时做数据库初始化), 支持多个数据库(但不推荐).

OMS Server根据上述四个配置项在Mariadb中创建数据库以及用户操作, 每个数据库允许额外指定其空库时的初始化sql, 具体参考下述章节 5.3.2 数据库初始化

5.4.1.7 spec.nacos_config

选填, 声明需要执行的nacos初始化信息.

mode: 标识以何种模式执行, 取值范围: generated、custom. 不同模式的初始化逻辑不同, 具体参考下述章节 5.3.3 Nacos初始化

5.4.1.8 spec.template_files

选填, 声明需要做jinja2模板替换的文件路径, 相对于打包文件的根目录. 模板文件详情参考下述章节 5.3.6 模板文件

5.4.1.9 spec.cluster_variables && spec.instance_variables

选填, 声明集群&&实例变量, 每个变量有3个必填元素: name、desc、value. 取值均为字符串内容, 其中value除字面量值外, 还支持 变量表达式变量函数写法, 详细函数说明参考下述章节 5.3.7 变量 使用集群变量的场景包括:

  • jinja2模板文件的替换

  • nacos初始化(在 generated 模式下), ${componentName}.properties 文件内容的生成, 每一个集群变量都会转换为文件中的KV配置项

使用实例变量的场景包括:

  • jinja2模板文件的替换

  • nacos初始化(在 generated 模式下), ${componentName}_${ip}.properties 文件内容的生成, 每一个实例变量都会转换为文件中的KV配置项

Note: 对于大部分程序, 集群中每个实例都会使用相同的配置内容, 因此无需配置instance_variable. 仅当各个实例的确需要配置不同的内容时才使用, 如: 设备接入端相关程序需要配置实例所运行机器的ip地址.

5.4.1.10 spec.clickhouse_config

选填, 声明需要执行的clickhouse初始化信息 database:组件在运行过程中,程序内需要访问的数据库schema名称, 支持多个数据库. Clickhouse初始化逻辑参考下述章节 5.3.4 Clickhouse初始化

5.4.1.11 spec.ports

选填, 声明需要开放防火墙端口的白名单

示例:

apiVersion: "v1"
kind: "Component"
level: "base"
name: "dcs"
spec:
  ports:
  # 必填: 端口名称
  - name: "dcsHfTlsPort"
    # 必填: 类型, 取值范围: listen - 监听类型端口, reserved - 保留类型端口.
    # 无论何种类型, 都将添加至linux中的保留端口中 (net.ipv4.ip_local_reserved_ports)
    type: "listen"
    # 必填: 单个6606  端口段6606-6608  多个6606,6607,6608.
    # 支持通过 变量表达式 引用集群变量内变量
    value: 'f"$\{dcs.hf.tls.port\}"'
  cluster_variables:
  - name: "dcs.hf.tls.port"
    desc: ""
    value: 'default(dcsHfTlsPort,"21099")'
  • spec.ports.name不能与spec.cluster_variables.name同名

  • spec.ports.value中的引用name必须与spec.cluster_variables.name一致

  • spec.ports.value中的引用name在spec.cluster_variables中必须存在

5.4.2、数据库初始化

完整的数据库初始化包含: 建库 + 建用户 + 授权访问 + 空库初始化.

【建库】 和【建用户】已在组件描述符 spec.mariadb_config(或database_config) 声明

【授权访问】由OMS Server负责

【空库初始化】需由接入方将sql文件(该文件囊括了空库的全量初始化逻辑, e.g: 建表、建索引、预置数据等)放置约定的路径:

  1. Mariadb/Mysql: $\{根目录\}/cicd/mariadb/init_$\{数据库名\}.sql
  2. 达梦数据库: $\{根目录\}/cicd/dmserver/init_$\{数据库名\}.sql

OMS Server 内部会统一将上述4个步骤合并输出为一个临时sql文件, 并在数据库服务的master节点做本地执行. 合并后的示例sql文件(为兼容mysql8.0语法,建用户建表语句已更新)内容示例如下:

CREATE DATABASE IF NOT EXISTS `s17_mms` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS  'mms'@'192.168.146.29' IDENTIFIED BY 'ST-smm#1988';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE,  REFERENCES, INDEX, ALTER ON `s17_mms`.* TO `mms`@'192.168.146.29';
USE `s17_mms`;

/* 下面为接入方给定的sql文件内容 */

组件描述符部分示例

数据库初始化图

5.4.3、Nacos初始化

完整的Nacos初始化包含: (组件描述符中)指定初始化模式 + 指定配置文件

generated模式(默认值)

兼容现有ansible框架下的接入规范,标识由 OMS Server自动创建namespace、group、dataId 以及组件内的config/bootstrap.properties文件.

推导规则: namespace对应团队标识, group对应组件名称, dataId分为四类:

  • ${componentName}_application.properties 组件给定, 文件路径位置: ${打包根目录}/cicd/nacos/xxx_application.properties. 安装/升级时始终覆盖.
  • ${componentName}_base.properties 依据组件描述符中所声明的集群变量 cluster_variables 生成. 安装/升级时始终覆盖.
  • ${componentName}_update.properties 记录运维过程中变更的KV. 仅会在Nacos控制台不存在时创建, 已存在时忽略.
  • ${componentName}_${ip}.properties 依据组件描述符中所声明的实例变量 instance_variables 生成. 仅会在Nacos控制台不存在时创建, 已存在时忽略.

bootstrap.properties 文件内容, 由 OMS Server 按固定模板生成, 随后放至路径: ${根目录}/config/bootstrap.properties. 生成示例内容:

Nacos初始化图

custom模式

标识由组件自身指定namespace、group以及dataId的创建, 采用文件系统来组织, 规则: ${根目录}/cicd/nacos/${namespace}/${group}/${dataId}.properties

其中 ${dataId}.properties 可为j2模板文件, 以支持变量替换. 同时该模式下, bootstrap.properties 也不再生成, 需要接入方自行指定(可按j2模板文件给定, 关于jinja2模板参考下述章节 5.3.6). 示例:

custom模式图

custom模式图

组件描述符部分示例

custom模式图

5.4.4、Clickhouse初始化

Clickhouse目前的初始化仅支持建表建库,OMS Server 仅负责将接入方指定的【建库】和【建表】脚本进行合并,然后统一执行初始化

完整的ck数据库初始化包含: 建库 + 空库初始化.

【建库】 在组件描述符 spec.clickhouse_config 声明

【空库初始化】需由接入方将sql文件(该文件囊括了空库的全量初始化逻辑放置约定的路径: ${根目录}/cicd/clickhouse/init_clickhouse_${数据库名}.sql

OMS Server 内部会统一将上述2个步骤合并输出为一个临时sql文件, 并在clickhouse的master节点做本地执行. 合并后的示例sql文件内容如下:

CREATE DATABASE IF NOT EXISTS base_reports_data on cluster streamax_ckcluster;
DROP DATABASE IF EXISTS base_reports_data on cluster streamax_ckcluster;
CREATE DATABASE IF NOT EXISTS base_reports_data on cluster streamax_ckcluster;
USE base_reports_data;

CREATE TABLE ODS_ALARM_HANDLE
(
    `h_alarm_id` UInt64 not null COMMENT '报警ID',
    `h_biz_type` String not null COMMENT '10010:报警处理状态通知,10012:报警状态通知',
    `h_status` Int8 not null COMMENT '报警ID',
    `h_insert_time` DateTime not NULL COMMENT '插入ck时间'
)ENGINE = ReplicatedReplacingMergeTree('/clickhouse/table/\{shard\}/\{database\}/\{table\}','\{replica\}')
PARTITION BY toYYYYMM(h_insert_time)
ORDER BY (h_alarm_id,h_biz_type)
TTL h_insert_time + INTERVAL 6 MONTH
COMMENT '报警处理';

组件描述符部分示例

Clickhouse初始化图

5.4.5、JVM初始化

JVM初始化配置是通过jinja2模板的形式完成;使用时通过在前端界面定义环境变量,实现在jinja2模板中动态替换引用变量: 如dcs中的jvm动态配置

  1. 在dcs服务中定义jvm的jinja2模板,同时在组件描述符 descriptor.yml 文档中定义模板文件位置,定义环境变量配置

JVM初始化图

  1. 在jinja2文件中引用组件描述符 descriptor.yml 文件中的变量

JVM初始化图

  1. 前端界面定义jvm环境变量;环境变量定义规则:如果只有该服务使用该变量,建议定义key时带上适用组件.

JVM初始化图

5.4.6、模板文件

模板文件主要解决的问题是: 代码级别无法确定其配置值, 需要根据部署的 主机/环境/方式 来动态确定.

OMS Server 目前支持Jinja2模板语法, 不限定模板文件的位置及使用场景, 仅会基于变量源(参考下述章节 5.3.7.1 )做文件的生成动作. 凡是要做变量替换的文件均可以此方式支持, 只需在 组件描述符 中列举出完尽的模板文件.

模板文件名无限制, 但文件后缀强制为”.j2”. 生成后会在相同位置输出移除 .j2 后缀的文件, 且原模板文件会被删除. 如:${根目录}/config/bootstrap.properties.j2 生成后变为 ${根目录}/config/bootstrap.properties`

详尽的Jinja2模板文件语法可参考官网: https://jinja.palletsprojects.com/en/stable/

组件描述符部分示例

jinja2模板图

5.4.7、变量

变量服务于模板文件的生成以及nacos配置文件内容的生成.

5.4.7.1、变量源

整个 CICD管理系统 内, 有如下几处变量源, 优先级从低到高依次为(相同key的配置值高优先级覆盖低优先级):

变量源 配置入口 作用 备注
集群变量 git仓库 -> 组件描述符 声明服务于集群的变量. 支持 字面量值变量函数
实例变量 git仓库 -> 组件描述符 声明服务于单个实例的变量. 支持 字面量值变量函数
环境变量 web界面 -> 环境管理 -> 环境变量 声明环境级别的变量,一般由各项目版本的开发人员添加. 配置时可指定 适用于组件
预定义变量 无法配置, OMS Server内部指定 通常包含当前主机IP、依赖的中间件地址等信息. 此类信息的特点是必须在部署时才能确定, 无法提前给出 不支持界面自定义

OMS Server在部署过程中基于变量源汇总的KV做模板生成逻辑.

5.4.7.2、变量函数

若nacos初始化模式为generated, 那么 集群变量 会额外推送至nacos存储.

对于业务组件, 集群变量 通常会指定诸如mysql、redis等三方中间件的地址, 此类信息无法提前在组件描述符 descriptor.yml 中指定, 而组件描述符本身又不能以jinja2方式给定. 因此引入变量函数来占位, 实际取值会根据函数计算结果得出, 示例:

变量函数图

目前支持的函数(大小写敏感)包括:

函数名函数作用函数参数示例/说明贴图
env获取依赖的中间件信息参数个数固定为两个, 参数1标识中间件, 参数2标识中间件的信息key(可选的参数信息参考下表)env(mariadb,master_ip)
local_ip获取当前机器iplocal_ip()
该函数仅作用于实例级别变量
south_ip获取当前主机所配置的南向IP, 未配置时取当前机器ip(即local_ip函数结果)south_ip()
该函数仅作用于实例级别变量
north_ip获取当前主机所配置的北向IP, 未配置时取当前机器ip(即local_ip函数结果)south_ip()
该函数仅作用于实例级别变量
deployment_mode获取部署模式(单机为0,集群为1)deployment_mode()
optional获取可选中间件信息(若指定中间件未安装则返回空字符串) 参数个数固定为两个 参数1标识中间件 参数2标识中间件的信息key (可选的参数信息参考下方optional表) optional(minio,addresses)
default获取界面配置的环境变量,若未配置则取默认值参数个数固定为两个 参数1标识界面配置的变量名 参数2标识变量默认值Note: 变量名, 只能包含数字,下划线,中横线,字母 且 只能用下划线或字母开头default(component_name,dcs)
为支持默认值复杂value,default支持第二种写法参数2变量默认值通过双引号修饰,将双引号中的字符串认定为一个值 'default(component_name,"dc##,,,&*%^%^s")'
env_cert获取证书配置,若未配置则取默认值 参数个数固定为两个 参数1标识证书相关的key 参数2标识变量默认值 (可选的参数信息参考下方env_cert表) env_cert(key_path,/iotp/network/cert/s17.key)
optional_storage获取存储配置(变量来源中间件配置和环境变量) 参数个数固定为两个 参数1标识cicd预定义的变量名,当前仅支持cicd_storage_app_id 参数2标识变量默认值 optional_storage(cicd_storage_app_id, 20210101)
optional_dependency_value依赖服务变量读取函数 使用该函数需提前在cicd系统中配置组件的依赖关系,以贴图为例,需先配置ms依赖服务为mdgw, 使用该函数的取值顺序如下 1、判断环境mdgw服务是否部署,存在则取mdgw集群变量中的intranet.proxy.http.port参数 2、若mdgw未部署则取ms服务上下文变量中的intranet.http.hls.port参数 3、若ms服务上下文变量中的intranet.http.hls.port参数不存在,则取默认参数21240 optional_dependency_value(“依赖服务名”,“依赖服务集群变量取值项”,“上下文变量取值项”,默认参数)

env函数支持的中间件及其信息key为:

中间件标识信息key作用&类型示例&说明
database(mariadb)master_ip数据库主节点IP(mha部署时为虚拟ip; 不区分类型, mysql/mariadb/dmserver通用) 字符串“192.168.132.15” 推荐使用env(database, master_ip),已有组件兼容env(mariadb, master_ip)
port数据库端口(不区分类型, mysql/mariadb/dmserver通用) 整型13306 推荐使用env(database, port),已有组件兼容env(mariadb, port)
all_ips数据库全部节点ip(不区分类型, mysql/mariadb/dmserver通用) 字符串数组 [ “192.168.132.15”, “192.168.132.16”, “192.168.132.17” ] 推荐使用env(database, all_ips),已有组件兼容env(mariadb, all_ips)
redismaster_ip主节点IP 字符串“192.168.132.15”
port端口 整型16379
all_ips全部节点ip 字符串数组 [ “192.168.132.15”, “192.168.132.16”, “192.168.132.17” ]
mode部署模式 整型单机-0, 集群(哨兵)-1
addresses集群地址 字符串“192.168.1.100:16379,192.168.1.101:16379”
nacosport端口 整型21980
all_ips全部节点ip 字符串数组 [ “192.168.132.15”, “192.168.132.16”, “192.168.132.17” ]
addresses集群地址 字符串“192.168.1.100:21980,192.168.1.101:21980”
kafkaport消息中间件端口(admq/kafka通用) 整型16379
addresses消息中间件集群地址(admq/kafka通用) 字符串“192.168.1.100:19092,192.168.1.101:19092”
clickhouseport端口 整型18123
addresses集群地址 字符串“192.168.1.100:18123,192.168.1.101:18123”
all_addresses全部集群地址 字符串“192.168.1.100:18123,192.168.1.101:18123”
master_ip主节点IP 字符串“192.168.132.15”
clickhouse_user用户名 字符串default
clickhouse_password_plaintext明文密码 字符串仅做示例, 不可使用
ST-esuohkcilc
clickhouse_password_ciphertext密文密码 字符串仅做示例, 不可使用
e653e07d52a090f3293524add62ba5
flinkport端口 整型18081
addresses集群地址 字符串“192.168.1.100:18081,192.168.1.101:18081”
assets-enginemaster_ip逻辑上的主节点 字符串192.168.132.1
node_port服务端口 整型20600
nginx_portnginx映射端口 整型20601
addresses全量地址 字符串192.168.132.1:20600,192.168.132.2:20600
zookeeperaddresses全量地址 字符串192.168.1.1:12181,192.168.1.2:12181,192.168.1.3:12181
milvusmaster_ip主节点IP 字符串192.168.132.172
port端口 整型19530

optional函数支持的中间件及其信息key为:

说明:oci存储时config.ini文件内需要填写pem证书文件路径,此路径固定为(config文件也将存放在此路径下):/iotp/cloud_config/oci/${pem文件名称}

中间件标识信息key作用&类型示例&说明
minioaddresses集群地址 字符串“192.168.0.1:21186,192.168.0.2:21186”
port端口 整型21187
cosregioncos.public.region 字符串ap-guangzhou
access_keycos.public.access.key 字符串AKIDZx4vzseorfCSSxGYzoPr
secret_keycos.public.secret.key 字符串GFBrIbXCbldEYcePt5
ossaddressesoss地址 字符串192.168.132.171:9999
access_keyoss.public.access.key 字符串AKIDZx4vzseorfCSSxGYzoPr
secret_keyoss.public.secret.key 字符串GFBrIbXCbldEYcePt5
obsaddressesobs地址 字符串192.168.132.171:9999
regionobs.public.region 字符串ap-guangzhou
access_keyobs.public.access.key 字符串AKIDZx4vzseorfCSSxGYzoPr
secret_keyobs.public.secret.key 字符串GFBrIbXCbldEYcePt5
ociconfig_pathoci config配置文件存放路径 字符串/iotp/cloud_config/oci/config.ini
access_keyoci.public.access.key 字符串AKIDZx4vzseorfCSSxGYzoPr
secret_keyoci.public.secret.key 字符串GFBrIbXCbldEYcePt5

env_cert函数支持的key和推荐default值为:

证书Key默认值作用&类型
pfx_path/iotp/network/nginx/platform.pfxpfx证书路径
key_path/iotp/network/nginx/platform.keypem私钥路径
pem_path/iotp/network/nginx/platform.pempem公钥路径
pfx_key_store_passwordENC#iiU2enuvCjiBhkXr2BMIzpKoF1aGW+yx#pfx容器密码
pfx_key_aliasalias证书别名
pfx_key_password TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305 证书密码
5.4.7.3、变量表达式

为支持环境变量、集群变量同级间相互引用,特引入 变量表达式 写法(同时兼容原有写法直接填变量值或变量函数):

变量表达式规则:变量表达式整体通过 f"xxx"修饰,以 f"开头、"结尾 作为是否是变量表达式的判定依据。

f"xxx" 中支持直接写变量值,也支持通过 ${} 去修饰一个变量名,解析时会将 ${} 中字符串作为一个变量名在同等级的变量中寻找同名变量并做值替换。

作用域应用场景环境变量配置变量表达式处理后的变量值
环境变量引用其他环境变量f"${cicd_variable}"cicd_variable1=streamax_value
仅变量值的表达式写法f"cicd_value"cicd_variable2=cicd_value
变量值与环境变量混用f"http://${cicd_variable}:${cicd_variable2}"cicd_variable3=http://streamax_value:cicd_value
传递型环境变量f"http:${cicd_variable1}"cicd_variable3=streamax_value
集群变量引用其他集群变量'f"${cicd.variable1}"'cicd.variable3=cicd_value
仅变量值的表达式写法'f"cicd_value"'cicd.variable1=cicd_value
变量值与集群变量混用'f"${cicd.variable1}####"'cicd.variable2=cicd_value####
传递型集群变量'f"http:${cicd.variable2}"'cicd.variable4=http:cicd_value####

注意:集群变量不支持表达式跟变量函数混用,若此场景,将需要用变量函数配置的部分单独抽成一个独立的集群变量

错误写法:直接在变量表达式中写env(mariadb,master_ip)函数获取mariadb主节点ip

错误写法图

正确写法:将env(mariadb,master_ip)函数单独写为一个变量的value,同时变量函数引用新加的mariadb变量名,如下:

正确写法图

5.4.7.4、预定义变量

预定义变量服务于模板文件 + 变量函数, 目前支持的预定义变量如下:

变量Key说明示例(示例值均包含类型信息, 如带双引号的为字符串)
_first_index_ip主机列表索引第一的主机ip“192.168.1.100”
_instance_index标识某个组件(在某次任务单中)在对应集群中的索引, 从1开始1
_host_ip标识当前主机的ip地址“192.168.1.100”
_instance_qty标识当前组件(集群下)总计多少实例3
_cluster_host_ips标识当前组件(集群下)所有的实例IP, 类型为JSON数组形式["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_kafka_all_ips标识当前任务单中部署kafka的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_kafka_port标识kafka的监听端口19092
_kafka_addresseskafka集群的地址"192.168.1.100:19092,192.168.1.111:19092"
_zookeeper_all_ips标识当前任务单中部署zookeeper的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_zookeeper_port标识zookeeper的监听端口12181
_mariadb_master_ip标识当前任务单中数据库的master ip"192.168.1.101"
_mariadb_all_ips标识当前任务单中部署数据库的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_mariadb_port标识mariadb的监听端口13306
_redis_all_ips标识当前任务单中部署Redis的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_redis_port标识redis的监听端口16379
_redis_mode标识redis的模式, 取值范围: 单机-0, 集群(哨兵)-10
_redis_addressesredis集群的地址"192.168.1.100:16379,192.168.1.111:16379"
_nacos_all_ips标识当前任务单中部署nacos的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_nacos_port标识nacos的监听端口21980
_nacos_addressesnacos集群的访问地址“192.168.0.1:21980,192.168.0.2:21980”
_clickhouse_all_ips当前任务单中部署clickhouse的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_clickhouse_portclickhouse的监听端口19000
_clickhouse_addressesclickhouse集群的访问地址"192.168.0.1:19000,192.168.0.2:19000"
_clickhouse_userclickhouse用户default
_clickhouse_password_plaintextclickhouse明文密码"ST-esuohkcilc"
_clickhouse_password_ciphertextclickhouse密文密码"653e07d52a090f3293524ad"
_nginx_all_ips标识当前任务单中部署nginx的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
_prometheus_all_ips标识当前任务单中部署prometheus的全量ip["192.168.1.100", "192.168.1.101", "192.168.1.102"]
cicd_storage_app_idcicd预定义的存储app_id:标识当前任务单中的APPID(当前规则:预定义的变量cos_app_id > 界面填写的cicd_storage_app_id)"2018081019"
cos_app_idcos云存储的app_id2018081020

组件描述符部分示例

预定义变量图

5.4.8、依赖项(仅适用于C++项目)

S17 C++项目在编译/运行时会额外依赖头文件、静态库或动态库, 这些依赖项来源于内部公共库 或 下载的第三方库. 为解决依赖项问题, 统一在文件 cicd/compile_dependency.yml 中声明全量的依赖项,每个依赖项也采用git管理. 在编译业务组件时, 会自动解析该文件, 按需递归编译依赖项.

编译过程中的目录固定为 cicd_compile, 每次编译前会予以清空. 编译后依赖项的输出固定为 cicd_output, 其中又按照依赖项的ID来组织. 接入方的打包脚本 cicd/assemble.sh 可按需拷贝相关库文件. 关于S17 C++项目编译说明可参考:

以mms为例, 最终编译成功后的目录结构如下:

依赖项图

依赖声明文件 compile_dependency.yml 示例:

dependencies:
  # 对应一个依赖项, 至少有1个
  - id: "s17-sdk-third-party"   # 必填: 唯一标识该依赖项
    third: true                 # 必填: 标识是否为第三方库, 第三方库不会触发编译过程, 并且在生成s17_sdk时, 会追加至third_party目录
    gitRepo: "http://182.148.52.90:8300/xieling/s17-sdk-third-party.git"    # 必填: git仓库地址
    branch: "v1.0.2_test" # 必填: 分支名
  - id: "cpp_basic"             # 必填: 唯一标识该依赖项
    third: false                # 必填: 标识是否为第三方库, 第三方库不会触发编译过程, 并且在生成s17_sdk时, 会追加至third_party目录
    gitRepo: "http://182.148.52.90:8300/xieling/cpp_basic.git"    # 必填: git仓库地址
    branch: "feature-1.0.15"    # 必填: 分支名

5.4.9、运维脚本

约定:本套工具主要由 oms-let 完成,需要业务组件支持相关脚本的支持,为减少业务层相关脚本的开发工作,尽量少的改动业务组件,本套工具对接,与原有ansibleCICD系统基本保持一致,包括安装(install.sh)启动(start.sh)停止(stop.sh)健康检查(health.sh)守护(guard.sh)卸载(uninstall.sh). oms-let 仅做对应脚本工具的调用操作,具体内部逻辑由服务组件脚本完成, 服务组件需注册为systemd自定义服务.

5.4.9.1、组件自动集成运维脚本

CICD-V1.1.1 版本后,支持组件在构建时自动集成最新的运维脚本,包括bin目录下脚本和script目录下脚本。

运维现有脚本文件及结构

运维脚本图

替换时机

组件未发布且使用jenkins进行构建时;

替换数据来源

script脚本、bin脚本

替换规则

替换规则图

改造点

以java工程为例, 替换脚本统一会放到以下目录,需要自查assembly

bin 文件 -> ~/install/$\{level\}/$\{componentName\}/packages/bin
script 文件 -> ~/install/$\{level\}/$\{componentName\}/script
toolbox 文件 -> ~/install/$\{level\}/$\{componentName\}/script/toolbox

java图

5.4.9.2、服务安装

调用各组件目录下的 install.sh, 完整路径为: $svc_name/script/install.sh

调用示例:

# Shell脚本支持如下入参:
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/install.sh <svc_name> <svc_type>
5.4.9.3、服务启动

调用各组件目录下的 start.sh, 完整路径为: $svc_name/script/start.sh

调用示例:

# Shell脚本支持如下入参:
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/start.sh <svc_name> <svc_type>
5.4.9.4、服务停止

调用各组件目录下的 stop.sh, 完整路径为: $svc_name/script/stop.sh

调用示例:

# Shell脚本支持如下入参:
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/stop.sh <svc_name> <svc_type>
5.4.9.5、服务守护

调用各组件目录下的 guard.sh, 完整路径为: $svc_name/script/guard.sh

调用示例:

# Shell脚本支持如下入参:
# operation_type 操作类型:
#     start   #启动启动守护,每15S扫描一次
#     status  #守护脚本状态
#     kill    #停止守护
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/component_guard.sh <operation_type> <svc_name> <svc_type>
5.4.9.6、服务卸载

调用各组件目录下的 uninstall.sh, 完整路径为: $svc_name/script/uninstall.sh

调用示例:

# Shell脚本支持如下入参:
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/component_guard.sh <operation_type> <svc_name> <svc_type>
5.4.9.7、服务健康检查

调用各组件目录下的 health.sh, 完整路径为: $svc_name/script/health.sh

# Shell脚本支持如下入参:
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/health.sh <svc_name> <svc_type>

health.sh示例:

#!/bin/bash
# 退出码0表示运行正常
# 退出码1表示未运行
function healthCheckMariadb()
{
    $\{MARIADB_DIR\}/support-files/mysql.server status
    systemctl status mariadb >/dev/null 2>&1
    if [ $? -eq 0 ]
    then
        write_log 4 1
        exit 0
    else
        write_log 4 2
        exit 1
    fi
}
5.4.9.8、进程PID获取

调用各组件目录下的 pid.sh, 完整路径为: $svc_name/script/pid.sh

# Shell脚本支持如下入参:
# svc_name 组件名
# svc_type 组件类型/三级研发级别
/iotp/env/oms-let/script/pid.sh <svc_name> <svc_type>

pid.sh示例:

#!/bin/bash
function GetMariadbPID()
{
    pid=`systemctl status mariadb | grep "Main PID" | awk '{print $3}'`
    systemctl status mariadb > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
        echo "$pid"
    else
        echo "-1"
    fi
}

GetMariadbPID
# 当服务运行时输出具体的PID进程号
# 当服务未运行或未安装时,输出-1

5.4.10、通用文件操作

CICD以 中台SPI 为契机, 提供通用文件操作, 辅助各团队尽可能将部署步骤自动化, 使用方式为:

  1. 各组件按需在组件描述符 cicd/descriptor.yml 内声明该组件在部署时需要执行的文件删除、文件拷贝动作
  2. OMS Server 在实际部署组件时,依据上述步骤声明的内容执行实际的文件删除、文件拷贝动作

仍然以 中台SPI 使用场景为例, 对应的组件描述符内 file_operations 内容如下(每个字段的作用参考对应的字段备注):

# 必填: 期望该对象的规格(静态信息)
spec:
  # 选填: 文件操作信息
  # 当组件自身为集群模式(有多个实例)部署时, 文件操作执行时间点在所有实例开始部署前.
  # 当有多个文件操作声明时, 执行顺序为:按本YAML文件内声明的顺序串行执行
  file_operations:
      # 必填, 文件操作类型, 取值范围: remove-文件移除, copy-文件拷贝
      # 视文件操作类型不同, 声明的字段名不同, 具体参考下方备注
    - type: remove
      # 如下为适用于操作类型为 remove 的字段
      # 必填, 标识待操作对象
      object_to_be_operated:
        # 必填, 需要操作的组件名.
        # e.g: 部署组件A时, 需要删除组件B所部署机器上的路径path1, 那么这里 service_name 填写 组件B 即可
        service_name: "base-server-service"
        # 选填, 当 service_name 有多个实例(即部署在多个机器上)时, 标识具体操作哪些机器
        # 取值范围: all - 所有主机, random - 随机取一台, first - 第一台, last - 最后一台
        # PS: first 和 last的语义为按照主机的ip(一般为内网)做字符串排序后,取第一个/最后一个
        # 默认值: all
        hosts: "all"
        # 必填, 待操作的文件路径, 说明:
        # * 必须以 /iotp/ 开头
        # * 路径信息支持通配符(通配符格式与Linux上的rm命令所支持的通配符保持一致)
        # * 通配符部分仅做用于最后一段文件uri. 除最后一段uri外, 不支持Linux特殊的 . 和 .. 标识符
        # * 仅支持文件, 不支持文件夹
        abs_path: "/iotp/plugin/demo-sdk-V*.jar"
      # 选填, 当依据上述信息识别的路径为空时, 需要采取的措施
      # 取值范围: ignore - 忽略, logWarning - 记录一个警告日志信息, reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: ignore
      on_path_not_exists: "ignore"
      # 选填, 有做实际的文件操作, 但文件操作的结果失败时, 需要采取的措施
      # 取值范围: ignore - 忽略, logWarning - 记录一个警告日志信息, reportFailureAndAbort - 记录一个错误信息, 并阻断组件自身的部署流程
      # 默认值: reportFailureAndAbort
      on_operation_failure: "reportFailureAndAbort"
      # 选填, 文件操作超时时间, 单位:秒.  超时后, 流程报错阻断
      # 默认值: 60
      time_out: 60
异常流程
  • cicd/descriptor.yml 中文件操作相关字段, 未按规定编写时, 前置Jekins编译时阻断
  • 当不同组件所声明的文件操作(如删除), 其操作对象为同一文件, 且组件间部署顺序恰好为并行时, 此时CICD不会做限制, 因此实际结果未知.
  • 单个文件操作不具备原子性. e.g: 如果涉及多台主机, 某一台机器执行失败, 不会回滚已执行成功的主机动作.
补充说明
  • 单个文件操作的命令执行超时时间默认为60s, 超时后始终阻断流程. 接入方需要自行识别文件操作可能的耗时, 按需调整.
  • yaml中对于 源 or 目标路径不存在时, 均有默认处理策略. 接入方可按业务特性自行调整.
  • 对于单个文件操作, yaml中均会声明其操作失败时的默认处理策略. 接入方可按业务特性自行调整.
  • 当文件操作对象, 涉及多台机器时, 机器间的执行顺序为串行
  • 文件操作先于模板渲染执行. 因此如果文件操作涉及组件内的j2模板文件, 目前迭代不支持先渲染再执行的动作.
  • 文件操作不会识别具体的上下文, 因此如果某些文件需要配套级联动作(如nginx -t校验语法正确性, nginx -s reload重加载, 中台动态生效插件), 目前需要操作者自行完成 或 行业层程序自行实现.
  • 对于依赖部署模型信息的文件操作, 在 OMS Server 中, 不会单独校验部署模型, 始终按照 组件描述符 内声明的策略来执行.

e.g:

组件A在其 组件描述符 内声明, 将包内的文件 "./libs/demo.tar.gz" 拷贝至中间件mariadb所在全部机器的指定路径 "/iotp/data/env/mariadb/abc.tar.gz"

对于以下情况, 程序都不会单独校验:

1). 中间件环境数据不包含mariadb

2). 中间件环境数据包含mariadb, 且是自建, 但未安装成功

3). 中间件环境数据包含mariadb, 但是云中间件

4). 中间件mariadb所在机器父级目录 /iotp/data/env/mariadb/ 不存在

均按照 yaml 中字段 "on_target_path_not_exists" 声明的策略来执行

6.FAQ

6.1.1、接入不用nacos的后端服务注意事项

CICD服务统一优先使用系统注册命令systemctl start ${服务名} 进行服务启停,所以需使用${服务名}.service文件。目前CICD系统仅提供一套前端通用模板和后端通用模板(依赖nacos的业务服务适用),针对不使用nacos的后端服务提供业务方自定义service文件的能力。

自定义service文件示例如下:

1、以base-license-server服务为例:需要在服务内添加cicd/systemd/base-license-server.service文件。并调整maven打包脚本assembly.xml,确保service文件在打包后文件的cicd/systemd文件夹中存在:

业务流程图

2、service文件内容模板如下,仅需将下面红框中的组件名称和组件类型改为对应的信息即可。

业务流程图

[Unit]
Description=base-license-service

[Service]
Type=forking
User=streamax
Group=streamax
LimitNOFILE=1048576
Environment="PATH=/iotp/script:/iotp/tools:/iotp/script/toolbox:/usr/java/jdk1.8.0_202-amd64/bin:/usr/java/jdk1.8.0_202-amd64/jre/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
Environment="LD_LIBRARY_PATH=/iotp/lib/third"
ExecStart=/iotp/base/base-license-service/bin/start.sh
RemainAfterExit=yes
ExecStop=/iotp/base/base-license-service/bin/stop.sh

[Install]
WantedBy=multi-user.target

6.1.2、接入达梦数据库的后端服务注意事项

CICD管理系统 在V1.1.7版本已具备ARM架构部署能力,国产化所使用的达梦数据库在语法以及历史(老CICD)配置应用上面与X86有诸多差异,因此使用 CICD管理系统 进行ARM架构部署时有以下修改点(注意事项)

  1. 新增 cicd/dmserver 目录, 维护达梦数据库初始化sql, 后续sql使用规则与mariadb文件夹一致(版本sql变更需增加update和维护init) 业务流程图

  2. 因达梦数据库特性,需用户与数据库名称一致,部分服务(在x86中)目前未统一用户名, 需在 cicd/descriptor.yml 新增 dm_user 业务流程图

  3. assembly.xml 添加打包cicd/dmserver目录配置(C++无需处理) 业务流程图

  4. 服务现有的 local_package_define.ymlpackage_define.yml 配置,需合并到 cicd/descriptor.ymlcluster_variables(新CICD仅维护一份配置),目前识别到的变量及示例如下: 业务流程图