本文以 VeOps CMDB 为例,提供完整的数据导入方案。采用 API 调用的方式,用同步工具 API 将数据同步到 CMS 2.0 中。
示例场景
本示例 Mock 了一套典型企业的 CMDB 数据,用于演示完整的导入流程。数据规模:
-
服务树三级组织结构:3 个事业部 → 8 个产品线 → 20 个应用
-
基础设施资源:30 台物理机、50 台虚拟机、40 个 Docker 容器
-
硬件组件:49 块网卡、89 块硬盘、171 条内存
-
关系网络:通过
contains(包含)和deploys_on(部署)两种关系类型,构建约 377 条关系
涵盖 9 种 CI 类型、460 个实例、377 条关系的完整 CMDB 资产图谱。
本地部署
Docker 本地一键部署, 更多部署命令参考:部署文档。
# 前提步骤: 安装 Docker 环境和 Docker Compose(v2)
# 拷贝项目代码
git clone https://github.com/veops/cmdb.git
# 进入主目录并启动
docker compose up -d
服务树结构

实体拓扑关系

实施步骤
步骤一:模型映射
理解 CMDB 与 UModel 之间的概念对应关系,为后续配置生成和数据同步奠定基础。
核心概念映射
|
CMDB 概念 |
UModel 概念 |
说明 |
|
配置项(CI) |
Entity(实体) |
CMDB 中的基本管理单元,如服务器、应用、数据库等 |
|
配置项类型(CI Type) |
EntitySet(实体集) |
定义一类实体的模型,包含字段定义、主键、生命周期等 |
|
CI Type 关系 |
EntitySetLink(实体集关联) |
定义不同实体类型之间的关系类型(如包含、部署、依赖) |
|
CI 实例关系 |
Topo(拓扑关系) |
具体实体实例之间的关联关系 |
|
属性定义 |
Field(字段) |
实体的属性字段,包含类型、约束、是否必填等 |
核心转换原则
-
模型定义层:CI Type → EntitySet
-
实例数据层:CI 实例 → Entity
-
关系定义层:CI Type 关系 → EntitySetLink
-
关系实例层:CI 实例关系 → Topo
实体类型映射表
基于示例场景,9 种 CI Type 映射到 UModel 的具体规则如下:
|
CMDB CI Type |
UModel EntitySet |
主键字段 |
显示字段 |
关系类型 |
|
事业部
|
|
|
|
contains → Product |
|
产品线
|
|
|
|
contains → Application |
|
应用
|
|
|
|
deploys_on → Server/VServer/Docker |
|
物理机
|
|
|
|
contains → VServer/NIC/HardDisk/RAM |
|
虚拟机
|
|
|
|
- |
|
Docker容器
|
|
|
|
- |
|
网卡
|
|
|
|
- |
|
硬盘
|
|
|
|
- |
|
内存
|
|
|
|
- |
步骤二:生成 UModel 配置
UModel 关于EntitySet/EntitySetLink配置文件既可以通过配置文件静态配置,也可以基于 CMDB 定义中的 Schema 去动态生成,混合使用是最佳实践方式, 如果静态文件存在,则以静态文件为主,这样做的好处在于集成了两者的优势。
以 VeOps 为例,实体有唯一标识,也有显式字段,唯一标识字段可以作为 EntitySet 的 primary_keys,而显示字段则可以作为 name_files,由于 VeOps 不支持 Schema 查询API,目前采用了静态配置的方法去生成 EntitySet 和 EntitySetLink 配置文件。
2.1 配置映射规则
编辑 config.yaml,配置 CI Type 到 EntitySet 的映射:
ci_type_mapping:
business_unit:
entity_set: "cmdb.business_unit"
domain: "cmdb"
primary_keys: ["bu_name"]
name_fields: ["bu_name"]
product:
entity_set: "cmdb.product"
domain: "cmdb"
primary_keys: ["product_name"]
name_fields: ["product_name"]
application:
entity_set: "cmdb.application"
domain: "cmdb"
primary_keys: ["project_name"]
name_fields: ["project_name"]
server:
entity_set: "cmdb.server"
domain: "cmdb"
primary_keys: ["server_name"]
name_fields: ["server_name", "private_ip"]
配置说明:
-
entity_set:UModel 实体集名称 -
primary_keys:唯一标识实体的字段 -
name_fields:用于显示的字段
2.2 运行生成工具
python3 generate_umodel_config.py
步骤三:应用 UModel 配置
将生成的 UModel 配置文件上传到 CMS 2.0 控制台,完成实体和关系的定义。
-
登录云监控2.0控制台。
-
进入目标工作空间,在左侧导航栏选择UModel 探索。
-
在UModel 探索页面,单击页面右上角
,在弹出框中单击上传 UModel YAML /JSON。 -
在批量上传 UModel的弹窗中,单击
选择文件,或将文件拖拽到上传框中:上传 umodel_config/目录下的所有 YAML 文件。文件上传完成后,文件列表显示全部 18 个文件验证通过(成功 18、警告 0、错误 0),单击 立即导入 完成批量导入。
-
文件上传后,单击立即导入。
-
导入成功后,单击页面右上角提交。
-
在提交预览页面,检查内容无误后,单击确认内容符合预期,执行变更。在变更情况弹框中,单击确定。
-
结果验证:在实体集列表中应该看到 9 个新增的
cmdb.*实体集。
步骤四:同步实体和关系数据
实体和关系数据通过 CMDB API 获取 CI 实例和关系数据,转换为 UModel 实体/关系格式并写入 SLS。
实体数据格式转换
VeOps API 通过 /api/v0.1/ci获取所有实体数据格式:
GET /api/v0.1/ci?ci_type=server&page=1&count=100
返回数据示例:
{
"_id": 1234,
"ci_id": "272",
"ci_type_id": "4",
"bu": "云计算",
"buy_date": "2023-01-08",
"ci_type": "server",
"ci_type_alias": "物理机",
"cmc_ip": "28.191.122.80",
"cnc_ip": "224.127.127.194",
"cpu": "AMD EPYC 7542",
"cpu_count": "2",
"ctc_ip": "75.76.9.36",
"device_spec": "Huawei RH2288H V5",
"env": "test",
"idc": "阿里云-河源",
"ilo_ip": "10.161.85.215",
"ilo_mac": "05:0f:a9:63:91:ad",
"kernel_version": "3.10.0-1160.el7.x86_64",
"logic_cpu_count": "40",
"manufacturer": "Dell",
"oneagent_id": "XD1VLEEIR15O",
"op_duty": "[\"张丽华\"]",
"os_version": "CentOS 7.9",
"perm": "{\"execute\": false, \"groups\": [\"viewers\", \"admins\", \"guests\"], \"owner\": \"张志强\", \"read\": true, \"write\": true}",
"private_ip": "10.122.144.73",
"rack": "59",
"raid": "RAID 10",
"ram": "64GB DDR4",
"ram_size": "64",
"rd_duty": "[\"齐晶\"]",
"server_name": "phy-server-011",
"server_room": "阿里云-河源机房",
"sn": "C2LVEAZRIVH1",
"ssh_port": "22",
"status": "在线",
"unique": "sn",
"unique_alias": "服务器序列号",
"vnc_port": "5910",
"__pack_meta__": "0|MTc2MjgzMzA5NTg5OTYzMjg1OQ==|32|3",
"__topic__": "",
"__source__": "30.221.145.27",
"__tag__:__receive_time__": "1763629311",
"__time__": "1763629311",
"__time_ns_part__": "127734016"
}
转换格式后写入 ${workspace}__entity ,系统字段映射如下:
|
UModel 字段 |
示例 |
说明 |
|
|
|
实体归属的域 |
|
|
|
实体集名称,对应 CI Type |
|
|
|
全局唯一ID |
|
|
|
首次观测时间,秒级时间戳 |
|
|
|
存活时间,秒为单位,一般设置为同步周期的 2-3 倍 |
|
|
|
首次观测时间,秒级时间戳 |
|
其他字段 |
|
保留所有原始字段 |
完整示例:
{
"__domain__": "cmdb",
"__entity_type__": "cmdb.server",
"__entity_id__": "b4da1c11d1a62257087aab071d27c1bc",
"__method__": "Update",
"__last_observed_time__": "1763629311",
"__keep_alive_seconds__": "3600",
"ci_id": "272",
"ci_type_id": "4",
"bu": "云计算",
"buy_date": "2023-01-08",
"ci_type": "server",
"ci_type_alias": "物理机",
"cmc_ip": "28.191.122.80",
"cnc_ip": "224.127.127.194",
"cpu": "AMD EPYC 7542",
"cpu_count": "2",
"ctc_ip": "75.76.9.36",
"device_spec": "Huawei RH2288H V5",
"env": "test",
"idc": "阿里云-河源",
"ilo_ip": "10.161.85.215",
"ilo_mac": "05:0f:a9:63:91:ad",
"kernel_version": "3.10.0-1160.el7.x86_64",
"logic_cpu_count": "40",
"manufacturer": "Dell",
"oneagent_id": "XD1VLEEIR15O",
"op_duty": "[\"张丽华\"]",
"os_version": "CentOS 7.9",
"perm": "{\"execute\": false, \"groups\": [\"viewers\", \"admins\", \"guests\"], \"owner\": \"张志强\", \"read\": true, \"write\": true}",
"private_ip": "10.122.144.73",
"rack": "59",
"raid": "RAID 10",
"ram": "64GB DDR4",
"ram_size": "64",
"rd_duty": "[\"齐晶\"]",
"server_name": "phy-server-011",
"server_room": "阿里云-河源机房",
"sn": "C2LVEAZRIVH1",
"ssh_port": "22",
"status": "在线",
"unique": "sn",
"unique_alias": "服务器序列号",
"vnc_port": "5910",
"__pack_meta__": "0|MTc2MjgzMzA5NTg5OTYzMjg1OQ==|32|3",
"__topic__": "",
"__source__": "30.221.145.27",
"__tag__:__receive_time__": "1763629311",
"__time__": "1763629311",
"__time_ns_part__": "127734016"
}
关系数据格式转换
VeOps 通过/api/v0.1/relation_ci获取 CI 关系数据。API 调用:
GET /api/v0.1/relation_ci?parent_type=product&child_type=application&level=1
返回数据示例:
{
"parent_id": 100,
"child_id": 200,
"relation_type": "contains"
}
UModel Topo 数据格式
转换后写入 ${workspace}__topo 的数据格式及系统字段映射:
|
UModel 字段 |
示例 |
说明 |
|
|
|
|
|
|
|
|
|
|
|
源实体全局唯一ID |
|
|
|
|
|
|
|
|
|
|
|
目标实体全局唯一ID |
|
|
|
标准化关系类型 |
|
|
|
首次观测时间,秒级时间戳 |
|
|
|
存活时间,秒为单位,一般设置为同步周期的 2-3 倍 |
|
|
|
首次观测时间,秒级时间戳 |
完整示例:
{
"__src_domain__": "cmdb",
"__src_entity_type__": "cmdb.server",
"__src_entity_id__": "cb18feff0a2faa1b007000773c717942",
"__dest_domain__": "cmdb",
"__dest_entity_type__": "cmdb.ram",
"__dest_entity_id__": "b4da1c11d1a62257087aab071d27c1bc",
"__relation_type__": "contains",
"__method__": "Update",
"__last_observed_time__": "1763703248"
}
2.1 配置同步连接
编辑 config.yaml,配置 CMDB 和 SLS 连接信息:
# CMDB 配置
cmdb:
endpoint: "http://cmdb.example.com"
api_key: "your-api-key"
secret: "your-api-secret"
# SLS 配置
sls:
endpoint: "cn-hangzhou.log.aliyuncs.com"
access_key_id: "YOUR_ACCESS_KEY_ID"
access_key_secret: "YOUR_ACCESS_KEY_SECRET"
project: "cms-workspace-project"
entity_logstore: "workspace__entity"
topo_logstore: "workspace__topo"
2.2 执行一键同步
执行全量同步命令,同步所有实体和关系数据:
python3 main.py --mode full --all
2.3 设置定期同步
UModel 实体需要定期更新 last_observed_time 字段来维持存活状态(KeepAlive 机制)。实际部署建议采用全量同步 + 增量同步相结合的方式:
全量同步
-
扫描 CMDB 中所有 CI 实例和关系,重新写入 EntityStore 中。
-
确保数据完整性,修复增量同步可能遗漏的数据。
-
适用于:首次导入、数据修复、定期数据校验(如每天凌晨执行)。
增量同步
-
仅同步自上次同步后发生变更的数据(依赖 CMDB 的
updated_at字段)。 -
同步速度快、资源消耗低,适合高频执行。
-
适用于:日常持续同步(如每 5-15 分钟执行一次)。
本示例采用 crontab 定时任务实现全量同步:
# 编辑 crontab
crontab -e
# 添加定时任务(每小时执行一次)
0 * * * * cd /path/to/cmdb_sync && python3 main.py --mode full --all >> logs/cron.log 2>&1
接入完成后的效果
完成数据导入后,可以在 CMS 2.0 控制台查看和操作 CMDB 数据。
1. 实体列表
查看所有从 CMDB 同步的实体。
2. 实体关系拓扑
可视化展示实体间的完整关系网络。
拓扑图中包含以下实体模型:硬盘(cmdb.harddisk)、网卡(cmdb.nic)、内存(cmdb.ram)、虚拟机(cmdb.vserver)、docker(cmdb.docker)、物理机(cmdb.server)、应用(cmdb.application)、产品(cmdb.product)、事业部(cmdb.business_unit)。实体间关系包括:物理机通过 contains 关系关联硬盘、网卡、内存、虚拟机;docker、虚拟机和应用通过 deploys_on 关系部署于物理机;应用通过 contains 关系包含产品;产品通过 contains 关系包含事业部。
3. 单个实体拓扑
查看特定实体的关联关系。
在关联拓扑页签中,以拓扑图形式展示实体的多层级关联关系。例如,事业部通过contains关系关联产品,产品通过contains关系关联应用,应用通过deploys_on关系关联部署目标(如Docker容器或物理机),物理机进一步通过contains关系关联硬盘、网卡、虚拟机、内存等基础设施组件。页面工具栏支持缩放、全屏、刷新和筛选操作,右上角可设置时间范围。
查询
链路数据查询
.topo | graph-call cypher(`
MATCH (src {__entity_type__:"cmdb.business_unit"})-[e1]-(n1)-[e2]-(n2)
RETURN src, e1, n1, e2, n2
`)
执行查询后,结果以表格形式展示 src、e1、n1、e2、n2 五列数据,其中 src 列为 cmdb.business_unit 类型实体,n1 列为 cmdb.product 类型实体,n2 列为 cmdb.application 等类型实体,e1 和 e2 列显示对应的关系数据。
多级跳
.topo | graph-call cypher(`
MATCH (src {__entity_type__:"cmdb.business_unit"})-[e*3..4]->(dest)
WHERE dest.__domain__ = 'cmdb'
RETURN src, dest, dest.__entity_type__
`)
执行该查询后,返回结果为三列表格,列名分别为 src、dest、__entity_type__。其中 src 列显示 cmdb.business_unit 类型实体(如"人工智能事业部"、"大数据事业部"),dest 列显示经过 3~4 跳关联到的 cmdb.server 或 cmdb.vserver 类型实体,__entity_type__ 列标识 dest 的实体类型。
获取单个实体可操作的方法
.entity_set with(domain='cmdb', name='cmdb.business_unit', ids=['cc723a11313b5b16a20806a64b89a212']) | entity-call __list_method__()
查询结果以表格形式返回该实体集支持的 7 个方法:__inspect__(Entity Configuration Inspector)、__list_method__(List Available Methods)、get_entities(Get Entities)、get_entity_set(Get Current EntitySet)、get_neighbor_entities(Get Neighbor Entities)、list_data_set(List DataSets)、list_related_entity_set(List Related Entities),每个方法包含 name、display_name、description、params、returns 等字段信息。
获取邻居节点
.entity_set with(domain='cmdb', name='cmdb.business_unit', ids=['cc723a11313b5b16a20806a64b89a212']) | entity-call get_neighbor_entities()
查询结果返回两行数据,包含四列:src_entity、dest_entity、direction、__link_type__。结果显示该 cmdb.business_unit 实体通过 contains 关系(方向为 out)关联了两个 cmdb.product 类型的实体。
结合高阶算子完成高级能力
当实体接入其他可观测数据后,可结合高阶 SPL 算子完成高级能力,以下示例针对应用的请求延迟指标进行异常检测:
.entity_set with(domain='apm', name='apm.service', ids=['e22adf09a11550f4d7eae98d8a11a1e9'])
| entity-call get_metric('apm', 'apm.metric.apm.service', 'avg_request_latency_seconds', aggregate=false)
| extend r = series_decompose_anomalies(__value__)
| extend anomaly_b =r.anomalies_score_series , anomaly_type = r.anomalies_type_series , __anomaly_msg__ = r.error_msg
| extend x = zip(anomaly_b, __ts__, anomaly_type, __value__)
| extend __anomaly_rst__ = filter(x, x-> x.field0 > 0)
| project __entity_id__, __labels__, __anomaly_rst__, __anomaly_msg__
__anomaly_rst__中返回异常时间点,异常类型,以及当时的值
执行查询后,结果表格中 __anomaly_rst__ 列显示检测到的异常类型为 SPIKE_UP(突增)和 SPIKE_DOWN(突降)及对应异常分数,__anomaly_msg__ 列为 null。