蓝鲸配置平台 bk-cmdb 容器集群查询接口 list_kube_cluster 完整指南:filter 过滤与分页实践
蓝鲸配置平台 bk-cmdb 容器集群查询接口 list_kube_cluster 完整指南:filter 过滤与分页实践
导读
本文面向需要在蓝鲸智云配置平台(bk-cmdb)中按业务维度查询容器集群的开发者,围绕 list_kube_cluster(查询容器集群)接口展开:从请求参数、filter 过滤规则、page 分页约束到响应结构逐项拆解,并给出"查详情"与"只查数量"两种典型请求示例。读完本文,你将掌握该接口的完整调用姿势、querybuilder 过滤规则的组装方法与底层实现原理,可直接用于 CMDB 容器资源管理、容器拓扑同步等场景的接口对接。
接口概览
list_kube_cluster 是蓝鲸配置平台(bk-cmdb)面向容器集群模型(Cluster)提供的查询接口,自 v3.12.1 版本起可用,调用所需权限为业务访问权限。
该接口通过 ESB(蓝鲸 API 网关)暴露,ESB 到 CMDB 的映射关系定义在 docs/apidoc/cc/cc.yaml 中:
| 映射项 | 值 |
|---|---|
| ESB 路径 | /v2/cc/list_kube_cluster/ |
| 接口名称 | list_kube_cluster |
| ESB 请求方法 | POST |
| api_type | query |
| CMDB 目标路径 | /api/v3/findmany/kube/cluster |
| CMDB 目标请求方法 | POST |
从源码看,该目标路径注册于 topo_server 的 kube 服务路由中,对应 SearchClusters 处理器:
- 路由注册:src/scene_server/topo_server/service/kube/service.go,
POST /findmany/kube/cluster→s.SearchClusters。 - 请求处理:src/scene_server/topo_server/service/kube/cluster.go。
请求参数
公共参数(common args)
接口文档中的 {{ common_args_desc }} 为公共参数占位,调用时需携带网关鉴权信息,典型字段如下(与请求示例一致):
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| bk_app_code | string | 是 | 应用 ID(ESB 中的应用标识) |
| bk_app_secret | string | 是 | 应用密钥 |
| bk_username | string | 否 | 用户名(与 bk_token 二选一) |
| bk_token | string | 否 | 登录态 Token(与 bk_username 二选一) |
接口参数
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| bk_biz_id | int | 是 | 业务 ID |
| filter | object | 否 | 容器集群查询范围(过滤条件) |
| fields | array | 否 | 所要查询的容器集群属性,不写代表搜索全部数据 |
| page | object | 是 | 分页条件 |
在源码中,该请求体被解析为 types.QueryClusterOption(src/kube/types/cluster.go),结构为 BizID + Filter + Page + Fields,与文档字段一一对应。
filter:容器集群属性过滤规则
filter 参数是容器集群属性字段过滤规则的组合,用于根据容器集群属性字段搜索集群。组合支持 AND 与 OR 两种方式,允许嵌套,最多嵌套 2 层。
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| condition | string | 是 | 规则操作符(AND / OR) |
| rules | array | 是 | 过滤集群的范围规则 |
rules:三元组过滤规则
rules 中每条过滤规则为三元组 field、operator、value:
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| field | string | 是 | 字段名 |
| operator | string | 是 | 操作符,可选值:equal、not_equal、in、not_in、less、less_or_equal、greater、greater_or_equal、between、not_between |
| value | - | 否 | 操作数,不同的 operator 对应不同的 value 格式 |
操作符枚举在 pkg/filter 中定义(如 pkg/filter/operator.go),equal 对应相等比较(value 为基本数据类型)、not_equal 对应不等比较;in/not_in 匹配字段值是否在指定集合中(value 为类型一致的基本数据类型数组)。
字段名取值参考容器集群模型字段(见 src/kube/types/cluster.go 与 src/kube/types/types.go),常用的可过滤字段包括:
| 字段名 | 含义 | 字段名 | 含义 |
|---|---|---|---|
| name | 集群名称 | network_type | 网络类型 |
| scheduling_engine | 调度引擎 | region | 地域 |
| uid | 集群自有 ID | vpc | vpc 网络 |
| xid | 关联集群 ID | network | 集群网络 |
| version | 集群版本 | type | 集群类型 |
| environment | 环境 | bk_biz_id | 业务 ID |
filter 校验由 QueryClusterOption.Validate() 完成(src/kube/types/cluster.go):它基于集群字段描述符生成默认表达式选项,对 filter 表达式做合法性校验,非法操作符或字段会返回参数错误。
组装规则(querybuilder)
filter 的组装规则基于 querybuilder 模块,完整说明见仓库内 src/common/querybuilder/README.md,要点如下:
- 支持类 jQuery-QueryBuilder 形式的输入参数;
- 过滤规则分为原子规则(AtomRule)与组合规则(CombinedRule),组合节点可以是原子规则或组合规则,由此实现嵌套;
- 每条规则通过
ToMgo转换为 MongoDB 查询条件; - 在
between/not_between之外,模块还扩展了时间类操作符(datetime_less、datetime_greater等,仅支持 RFC3339 时间格式)与字符串操作符(begins_with、contains、ends_with等),可在组合条件时灵活选用。
一个嵌套组合示例(来自该模块文档):
{
"condition": "AND",
"rules": [
{
"field": "price",
"operator": "less",
"value": 10.25
},
{
"condition": "OR",
"rules": [
{
"field": "category",
"operator": "equal",
"value": 2
},
{
"condition": "AND",
"rules": [{
"field": "name",
"operator": "not_in",
"value": ["a", "b"]
}]
}
]
}
]
}
page:分页条件
| 字段 | 类型 | 必选 | 描述 |
|---|---|---|---|
| start | int | 是 | 记录开始位置 |
| limit | int | 是 | 每页限制条数,最大 500 |
| enable_count | bool | 是 | 本次请求为获取数量还是详情的标记 |
| sort | string | 否 | 排序字段,在字段前加 -(如 sort:"-field")表示按字段 field 降序 |
注意:
enable_count为 true 表示此次请求只获取数量,此时其余字段必须为初始化值:start 为 0,limit 为 0,sort 为"";- 调用方未指定
sort时,后台默认按容器集群 ID 排序; - 必须设置分页参数,一次最大查询数据不超过 500 个。
BasePage.ValidateWithEnableCount 的实现(src/common/metadata/page.go)与文档约束完全一致:启用 enable_count 时若 start/limit/sort 非初始值则报 page.enable_count 参数错误;limit 上限受 common.BKMaxLimitSize = 500 约束(见 src/common/definitions.go),超出会返回分页 limit 超限错误。查询集群时传入的 maxLimit 正是 common.BKMaxLimitSize,这也解释了"单次最大 500 条"的硬性限制。
请求参数示例
获取详细信息请求参数
{
"bk_app_code": "esb_test",
"bk_app_secret": "xxx",
"bk_username": "xxx",
"bk_token": "xxx",
"bk_biz_id": 2,
"filter": {
"condition": "AND",
"rules": [
{
"field": "scheduling_engine",
"operator": "equal",
"value": "k8s"
},
{
"field": "version",
"operator": "equal",
"value": "1.1.0"
}
]
},
"page": {
"start": 0,
"limit": 500,
"enable_count": false
}
}
获取数量请求示例
{
"bk_app_code": "esb_test",
"bk_app_secret": "xxx",
"bk_username": "xxx",
"bk_token": "xxx",
"filter": {
"condition": "AND",
"rules": [
{
"field": "scheduling_engine",
"operator": "equal",
"value": "k8s"
},
{
"field": "version",
"operator": "equal",
"value": "1.1.0"
}
]
},
"page": {
"start": 0,
"limit": 0,
"enable_count": true
}
}
注意:获取数量场景下可省略 bk_biz_id 之外的查询语义(示例中 filter 仍可携带以精确统计满足条件的集群数量),但 page 必须严格保持 start=0、limit=0、enable_count=true。
返回结果示例
详细信息接口响应
{
"result": true,
"code": 0,
"message": "success",
"permission": null,
"data": {
"count": 0,
"info": [
{
"name": "cluster",
"scheduling_engine": "k8s",
"uid": "xxx",
"xid": "xxx",
"version": "1.1.0",
"network_type": "underlay",
"region": "xxx",
"vpc": "xxx",
"network": "127.0.0.0/21",
"type": "INDEPENDENT_CLUSTER",
"environment": "xxx",
"bk_project_id": "21bf9ef9be7c4d38a1d1f2uc0b44a8f2",
"bk_project_name": "test",
"bk_project_code": "test"
}
]
},
"request_id": "87de106ab55549bfbcc46e47ecf5bcc7"
}
获取容器集群数量接口响应
{
"result": true,
"code": 0,
"message": "success",
"permission": null,
"data": {
"count": 1,
"info": [
]
},
"request_id": "87de106ab55549bfbcc46e47ecf5bcc7"
}
返回结果参数说明
通用响应字段
| 名称 | 类型 | 描述 |
|---|---|---|
| result | bool | 请求成功与否。true:请求成功;false:请求失败 |
| code | int | 错误编码。0 表示 success,>0 表示失败错误 |
| message | string | 请求失败返回的错误信息 |
| permission | object | 权限信息 |
| data | object | 请求返回的数据 |
| request_id | string | 请求链 id |
data
| 字段 | 类型 | 描述 |
|---|---|---|
| count | int | 记录条数 |
| info | array | 集群实际数据 |
info[x]:集群字段明细
| 字段 | 类型 | 描述 |
|---|---|---|
| name | string | 集群名称 |
| scheduling_engine | string | 调度引擎 |
| uid | string | 集群自有 ID |
| xid | string | 关联集群 ID |
| version | string | 集群版本 |
| network_type | string | 网络类型 |
| region | string | 地域 |
| vpc | string | vpc 网络 |
| network | array | 集群网络 |
| type | string | 集群类型 |
| environment | string | 环境 |
| bk_project_id | string | 项目 ID |
| bk_project_name | string | 项目名称 |
| bk_project_code | string | 项目英文名 |
响应结构对应源码中的 types.Cluster(src/kube/types/cluster.go),其中:
type为集群类型枚举,取值为INDEPENDENT_CLUSTER(独立集群)与SHARE_CLUSTER(共享集群),由ClusterType.Validate()严格校验(src/kube/types/cluster.go);scheduling_engine为调度引擎(如 k8s、tke 等);network为集群 overlay 网络地址(如["1.1.1.0/21"]);xid为底层依赖的集群 ID。
注意:
- 如果本次请求是查询详细信息,那么
count为 0;如果查询的是数量,那么info为空。即 count 与 info 在同一响应中互斥出现,分别承载两类请求的结果。
源码级执行流程与底层实现
SearchClusters 处理器(src/scene_server/topo_server/service/kube/cluster.go)的完整调用链如下:
- 参数解析与校验:将请求体解码为
types.QueryClusterOption,随后调用searchCond.Validate()完成字段、filter 表达式与分页参数校验; - 鉴权:构造
acmeta.KubeCluster + Find的资源属性进行授权校验(业务访问权限即对应此处的 Find 动作),未授权则返回 403 语义的错误; - 共享集群兼容:调用
GenSharedClusterListCond(src/scene_server/topo_server/logics/kube/kube.go)将业务自身集群与平台业务共享集群的条件合并——若无共享关系,直接以bk_biz_id过滤;否则以 OR 组合bk_biz_id = 业务ID与id in 共享集群ID再与原始 filter 取 AND,最终转换为 MongoDB 条件; - 数量查询分支:当
page.enable_count = true时,调用 CoreService 的Count().GetCountByFilter按cc_ClusterBase表统计数量,并以 count 返回(此时 info 为空数组); - 详情查询分支:构造
metadata.QueryCondition(携带 filter、page、fields),调用 CoreServiceKube().SearchCluster查询数据,返回结构为ResponseCluster{Data: <a href="https://link.gitcode.com/i/de93066d959d3e0c2cf2fcbaf6b09120" target="_blank">]Cluster}([src/source_controller/coreservice/service/kube/cluster.go),最终按{count: 0, info: [...]}组装响应。
底层存储层面,集群数据落在 MongoDB 的 cc_ClusterBase 表(表名常量见 src/kube/types/types.go)。CoreService 的查询实现直接对 MongoDB 执行 Find + Start(分页起始)+ Limit(分页条数)+ Sort(排序)+ Fields(字段裁剪),与文档中 page 的四个字段语义一一对应。
测试用例验证
仓库自带 topo_server 的 kube 集群集成测试(src/test/topo_server/cluster_test.go),覆盖了与本文接口相同的两种典型场景:
- 按名称查询集群详情:构造
filter.Expression{ CombinedRule{ AND, AtomRule{Field: name, Operator: equal, Value: "cluster"} } }与page{start:0, limit:10, enable_count:false},断言返回 count 为 0(表示详情查询); - 按名称统计集群数量:构造同样的原子规则过滤,
page仅设置enable_count: true,断言info.Count == 1。
该测试同时验证了:集群名称为必填字段(缺少 name 时创建报错)、非编辑字段(如 uid)不允许更新、批量删除等约束。这些与 filter 中 name 字段可过滤、uid 字段可参与等值查询的事实相互印证。
常见使用要点小结
- 业务维度隔离:
bk_biz_id必填,查询结果限定在该业务(以及按共享集群机制可见的共享集群)范围内; - 过滤优先使用 equal/in/not_in:对 name、scheduling_engine、version 等字段的精确匹配最常用;需要区间比较时使用
less/greater系列; - 控制返回字段:通过
fields数组只取所需属性,可减少网络与存储开销; - 分页纪律:limit 最大 500;查数量与查详情严格区分
enable_count,两种模式下 count/info 的返回语义不同,勿混用; - 权限前置:接口要求业务访问权限,接入方需保证调用账号在对应业务下具备访问权限,否则会收到权限错误响应。
如需了解容器集群的创建、批量更新、批量删除等配套接口,可继续阅读同目录下的 create_kube_cluster.md、batch_update_kube_cluster.md 等文档;filter 规则的完整操作符说明见 src/common/querybuilder/README.md。