本文以 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 文件。
文件上传后,单击立即导入。
导入成功后,单击页面右上角提交。
在提交预览页面,检查内容无误后,单击确认内容符合预期,执行变更。在变更情况弹框中,单击确定。
结果验证:在实体集列表中应该看到 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 --all2.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. 实体关系拓扑
可视化展示实体间的完整关系网络。

3. 单个实体拓扑
查看特定实体的关联关系。

查询
链路数据查询
.topo | graph-call cypher(`
MATCH (src {__entity_type__:"cmdb.business_unit"})-[e1]-(n1)-[e2]-(n2)
RETURN src, e1, n1, e2, n2
`)
多级跳
.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__
`)
获取单个实体可操作的方法
.entity_set with(domain='cmdb', name='cmdb.business_unit', ids=['cc723a11313b5b16a20806a64b89a212']) | entity-call __list_method__()
获取邻居节点
.entity_set with(domain='cmdb', name='cmdb.business_unit', ids=['cc723a11313b5b16a20806a64b89a212']) | entity-call get_neighbor_entities()
结合高阶算子完成高级能力
当实体接入其他可观测数据后,可结合高阶 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__中返回异常时间点,异常类型,以及当时的值


