ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

蓝鲸智云配置平台(BlueKing CMDB)Kubernetes workload 批量更新接口实战指南

蓝鲸智云配置平台(BlueKing CMDB)Kubernetes workload 批量更新接口实战指南
  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

蓝鲸智云配置平台(BlueKing CMDB)

项目地址:https://gitcode.com/gh_mirrors/bk/bk-cmdb
点击查看免费下载

本文面向需要基于蓝鲸智云配置平台(BlueKing CMDB)开放 API 对容器工作负载(Workload)进行批量维护的开发者,系统讲解batch_update_kube_workload接口的请求结构、嵌套参数、调用示例与响应约定,并结合仓库源码揭示从路由注册、鉴权、事务到数据库落库的完整实现链路。阅读本文后,你将能够准确构造请求体批量更新 Deployment、StatefulSet 等九类 Kubernetes 工作负载,并理解接口的校验边界与底层存储原理。

一、接口概述

batch_update_kube_workload用于批量更新 workload(工作负载),是 CMDB 容器业务模型中操作 Kubernetes 工作负载的核心接口之一。接口基本信息如下:

项目说明
接口版本v3.12.1+
所需权限容器工作负载编辑
HTTP 方法PUT
网关资源路径/api/v3/updatemany/kube/workload/{kind}
后端转发路径/api/v3/updatemany/kube/workload/{kind}

该资源在 API 网关配置中声明于 docs/apidoc/apigw/backend/bk_apigw_resources_bk-cmdb.yaml,operationId即为batch_update_kube_workload,采用 PUT 方法转发至 CMDB 后端,并配置了默认限流策略(bk-rate-limit,默认 100 tokens/秒)。

在后端服务中,该接口对应的路由注册与处理器可见于 src/scene_server/topo_server/service/kube/service.go:

utility.AddHandler(rest.Action{Verb: http.MethodPut, Path: "/updatemany/kube/workload/{kind}", Handler: s.UpdateWorkload})

其中{kind}为路径参数,用于指定工作负载类型。

二、请求参数详解

2.1 顶层参数

参数名称参数类型必选描述
bk_biz_idint是业务 id
kindstring是workload 类型,目前支持的 workload 类型有deployment、daemonSet、statefulSet、gameStatefulSet、gameDeployment、cronJob、job、pods(不通过 workload 而直接创建 Pod)、customResource(自定义资源)
dataobject是包含需要更新的字段
idsarray是在 cc 中的 id 唯一标识数组

注意:文档明确提示,使用 k8s 的唯一标识和 cc 的唯一标识传入关联信息时,这两种方式只能使用其中一种,不能混用。本接口通过ids字段使用 cc 中的唯一标识进行批量定位。

2.2 data 子参数

data对象承载本次更新需要修改的字段,均为可选:

参数名称参数类型必选描述
labelsmap否标签
selectorobject否工作负载选择器
replicasint否工作负载实例个数
strategy_typestring否工作负载更新机制
min_ready_secondsint否指定新创建的 Pod 在没有任意容器崩溃情况下的最小就绪时间,只有超出这个时间 Pod 才被视为可用
rolling_update_strategyobject否滚动更新策略

从源码字段描述看(见 src/kube/types/deployment.go),labels、selector、strategy_type、min_ready_seconds、rolling_update_strategy均为可编辑字段(IsEditable: true),而name、namespace等标识性字段不可编辑,不能在更新请求中修改。

strategy_type的取值与 Kubernetes 语义一致,以 Deployment 为例(见 src/kube/types/deployment.go):

  • Recreate:先杀掉所有已存在的 Pod 再创建新的;
  • RollingUpdate:通过滚动更新方式逐步缩容旧 ReplicaSet、扩容新 ReplicaSet。

2.3 selector 与 match_expressions

selector(工作负载选择器)是 Kubernetes 中的标签查询条件,其语义为:matchLabels与matchExpressions的结果做AND逻辑合并;空的标签选择器匹配所有对象,为 null 时则什么也不匹配(见 src/kube/types/workload.go 的LabelSelector定义)。

参数名称参数类型必选描述
match_labelsmap否根据 label 匹配
match_expressionsarray否匹配表达式

match_expressions[x]每个元素包含:

参数名称参数类型必选描述
keystring是标签的 key
operatorstring是操作符,可选值:"In"、"NotIn"、"Exists"、"DoesNotExist"
valuesarray否字符串数组,如果操作符为"In"或"NotIn",不能为空;如果为"Exists"或"DoesNotExist",必须为空

这四个操作符在源码中对应LabelSelectorOperator枚举(见 src/kube/types/workload.go):

const ( LabelSelectorOpIn LabelSelectorOperator = "In" LabelSelectorOpNotIn LabelSelectorOperator = "NotIn" LabelSelectorOpExists LabelSelectorOperator = "Exists" LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist" )

2.4 rolling_update_strategy、max_unavailable 与 max_surge

rolling_update_strategy的约束为:当strategy_type为RollingUpdate时不为空,其他情况为空。其结构对应源码中的RollingUpdateDeployment(见 src/kube/types/deployment.go)。

参数名称参数类型必选描述
max_unavailableobject否最大不可用
max_surgeobject否最大溢出

语义对照 Kubernetes 原生定义:

  • max_unavailable:更新过程中最多可以处于不可用状态的 Pod 数量;max_surge为 0 时,该值不能为 0;
  • max_surge:更新过程中可以超出期望 Pod 数量的最大调度个数;max_unavailable为 0 时,该值不能为 0。

两者均可取绝对数值(如5)或期望 Pod 数的百分比(如10%),由此引入了IntOrString类型:

参数名称参数类型必选描述
typeint是可选值为 0(表示 int 类型)或 1(表示 string 类型)
int_valint否当type为 0(int 类型)时不能为空,为对应的 int 值
str_valstring否当type为 1(string 类型)时不能为空,为对应的 string 值

IntOrString的底层定义在 src/kube/types/workload.go 与 src/kube/types/workload.go:

const ( IntType = 0 // IntOrString 持有 int StringType = 1 // IntOrString 持有 string ) type IntOrString struct { Type Type `json:"type" bson:"type"` IntVal int32 `json:"int_val" bson:"int_val"` StrVal string `json:"str_val" bson:"str_val"` }

三、调用示例

以下为更新业务bk_biz_id=3下 cc 标识为1、2、3的 Deployment 工作负载的完整请求体:

{ "bk_biz_id": 3, "kind": "deployment", "ids": [ 1, 2, 3 ], "data": { "labels": { "test": "test", "test2": "test2" }, "selector": { "match_labels": { "test": "test", "test2": "test2" }, "match_expressions": [ { "key": "tier", "operator": "In", "values": [ "cache" ] } ] }, "replicas": 1, "strategy_type": "RollingUpdate", "min_ready_seconds": 1, "rolling_update_strategy": { "max_unavailable": { "type": 0, "int_val": 1 }, "max_surge": { "type": 0, "int_val": 1 } } } }

该示例同时演示了:

  • labels直接整体替换为{"test": "test", "test2": "test2"};
  • selector同时使用match_labels与match_expressions,其中match_expressions以In操作符匹配tier标签含cache的表达式;
  • strategy_type取RollingUpdate,此时rolling_update_strategy必须提供,且max_unavailable、max_surge以 int 类型(type=0)给出绝对值1。

四、响应示例与响应参数说明

4.1 响应示例

{ "result": true, "code": 0, "data": null, "message": "success", "permission": null }

4.2 响应参数说明

参数名称参数类型描述
resultbool请求成功与否。true 表示请求成功;false 表示请求失败
codeint错误编码。0 表示 success,>0 表示失败错误
messagestring请求失败返回的错误信息
permissionobject权限信息
dataobject请求返回的数据

批量更新成功后data为null,调用方以result=true, code=0判断操作成功即可。

五、源码实现链路与底层原理

5.1 请求解析与参数校验

后端处理器UpdateWorkload位于 src/scene_server/topo_server/service/kube/workload.go,处理流程依次为:

  1. kind 校验:从路径参数取出kind并调用types.WorkloadType.Validate()校验,仅当 kind 属于九类枚举值之一才继续(见 src/kube/types/types.go);
  2. 请求解码:将请求体解码为types.WlUpdateOption;
  3. 参数校验:调用req.Validate()。

请求结构定义于 src/kube/types/workload.go:

type WlUpdateOption struct { BizID int64 `json:"bk_biz_id"` WlUpdateByIDsOption } type WlUpdateByIDsOption struct { Kind WorkloadType `json:"kind"` IDs []int64 `json:"ids"` Data WorkloadInterface `json:"data"` }

Validate()的校验规则(可精确复现接口的失败场景):

  • bk_biz_id不能为 0,否则报参数缺失错误;
  • ids不能为空数组;
  • ids数量必须小于WlUpdateLimit = 200(见 src/kube/types/workload.go),超出即返回"数量超出限制"错误;
  • data不能为 nil;
  • 最终调用具体 workload 类型的ValidateUpdate(),例如 Deployment 的校验实现于 src/kube/types/deployment.go,基于字段描述符DeploymentFields逐字段校验。

解码时WlUpdateByIDsOption.UnmarshalJSON会依据kind动态创建对应类型的实例(kind.NewInst()),所以data会被正确解析为 Deployment、StatefulSet 等具体结构。

5.2 权限校验与存在性检查

  • 权限校验:处理器构造acmeta.ResourceAttribute{Type: acmeta.KubeWorkload, Action: acmeta.Update}并调用AuthManager.Authorize,即文档所述"容器工作负载编辑"权限;无权限时返回RespNoAuth。
  • 存在性检查:通过checkWorkloadData按ids查询工作量实例(ListWorkload,条件为id in ids),若查询结果为空直接返回 "no workload founded";同时校验这些工作负载所在命名空间是否为共享命名空间(checkWlSharedNs),避免跨业务误操作共享集群资源。

5.3 事务、更新落库与审计

更新操作包在CoreService().Txn().AutoRunTxn事务内执行,保证批量更新与审计日志写入的原子性:

  1. 调用CoreService().Kube().UpdateWorkload转发至 coreservice;
  2. 在 coreservice 中(见 src/source_controller/coreservice/service/kube/workload.go):
    • 根据kind.Table()解析出对应的物理表(如cc_DeploymentBase、cc_StatefulSetBase等,映射关系见 src/kube/types/types.go);
    • 调用req.Data.BuildUpdateData()生成仅包含可编辑字段的更新数据,并自动附加last_time与modifier字段(见 src/kube/types/deployment.go);
    • 以id in ids为条件执行 MongoDB 批量Update。
  3. 更新成功后生成AuditUpdate类型审计日志并保存,记录本次修改字段(auditParam.WithUpdateFields)。

5.4 客户端调用封装

若你在 Go 服务中通过 apimachinery SDK 调用该能力,接口声明位于 src/apimachinery/toposerver/kube/apis.go,调用方式可参考集成测试用例(见 src/test/topo_server/workload_test.go):

updateOpt := types.WlUpdateOption{ BizID: bizID, WlUpdateByIDsOption: types.WlUpdateByIDsOption{ IDs: []int64{wlID}, Data: &wl, }, } err := kubeClient.UpdateWorkload(ctx, header, types.KubeDeployment, &updateOpt)

测试中同样以IntOrString{Type: types.StringType, StrVal: "2"}演示了百分比/字符串形式的max_unavailable用法,与文档中str_val参数相互印证。

六、使用注意事项

  1. 标识方式唯一性:本接口通过 cc 内部ids定位工作负载,与基于 k8s 唯一标识的关联方式二者只能取其一,不能混用;
  2. 批量上限:单次ids数量上限为 200(WlUpdateLimit),超出将校验失败;
  3. 滚动更新策略约束:仅当strategy_type=RollingUpdate时rolling_update_strategy才允许非空;max_unavailable与max_surge不能同时为 0;
  4. 不可编辑字段:name、namespace等标识字段不可随更新请求修改,更新数据仅包含可编辑的 spec 字段;
  5. 权限前置:调用者必须具备业务下"容器工作负载编辑"权限,否则请求会在鉴权阶段被拒绝;
  6. 共享命名空间保护:当目标工作负载位于共享命名空间时,接口会校验业务归属,防止越权修改其他业务的工作负载。

综上,该接口是 CMDB 容器管理体系中按 cc 标识批量调整工作负载配置的标准入口,理解其参数约束与源码落库逻辑,可帮助你在自动化运维与平台集成场景中稳定地完成容器资源变更。

  • 后端
  • 企业应用
  • 运维

【免费下载链接】bk-cmdb

蓝鲸智云配置平台(BlueKing CMDB)

项目地址:https://gitcode.com/gh_mirrors/bk/bk-cmdb
点击查看免费下载
上一篇:SSLRec 项目常见问题解决方案
下一篇:颠覆性AI绘画优化:3大智能方案让你的低配电脑流畅创作

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进