☰
CubeFS Master 用户管理 API 完全指南:从用户创建到卷授权与转移
2026/10/5 14:56:17 网站建设 项目流程
  • 存储
  • 分布式文件系统
  • 对象存储
  • 云原生

【免费下载链接】cubefs

cloud-native distributed storage

项目地址:https://gitcode.com/gh_mirrors/cu/cubefs
点击查看免费下载

CubeFS 的用户管理机制以 Master 节点的 HTTP 接口为核心,为对象存储(object storage)与 POSIX 文件系统提供统一的身份标识、AK/SK 凭证与权限控制能力。本文基于官方管理 API 文档,结合 master/api_service_user.go、master/user.go 与 proto/user_proto.go 等源码实现,系统讲解用户创建、删除、查询、更新、授权、移除权限与卷所有权转移的全部 API 调用方式、参数含义与底层原理,帮助读者完整掌握 CubeFS 多租户用户体系的运维要点。

用户体系的核心概念

在 CubeFS 中,用户管理服务于对象存储(S3 协议)与 POSIX 文件系统两套访问入口,其核心设计如下:

  • 用户 ID 与卷 Owner 强绑定:CubeFS 将卷的Owner字段视为用户 ID。创建卷时若Owner值为testuser,则该卷会自动归属于用户testuser(体现在用户信息的own_vols列表中)。
  • 自动建用户:如果创建卷时不存在与Owner相同值的用户 ID,Master 会在创建卷的过程中自动创建该用户。
  • root 用户自举:集群启动时自动创建 root 用户(type 值为0x1)。从源码看,master/user.go 中定义了RootUserID = "root"与默认密码DefaultRootPasswd = "CubeFSRoot"。
  • 用户类型枚举:proto/user_proto.go 定义了四种UserType:0x0(invalid,无效)、0x1(root)、0x2(admin,管理员)、0x3(normal,普通用户)。Valid()方法仅接受 root/admin/normal 三种类型,且 API 层拒绝直接创建或修改为 root 类型(见 master/api_service_user.go)。
  • AK/SK 凭证:每个用户对应一对对象存储凭证——Access Key(16 位字母数字)与 Secret Key(32 位字母数字),未指定时由系统自动生成。

从 HTTP 路由注册(master/http_server.go)可以看到,用户管理接口均挂在 Master 的 HTTP 服务(默认端口17010)下,路径常量定义于 proto/admin_proto.go(如UserCreate、UserUpdate等)。

创建用户(Create User)

通过 POST 请求向/user/create接口提交 JSON 数据创建用户:

curl -H "Content-Type:application/json" -X POST --data '{"id":"testuser","pwd":"12345","type":3}' "http://10.196.59.198:17010/user/create"

创建成功后,该用户即可用于访问集群中的对象存储功能。

::: tip 提示 集群启动时自动创建 root 用户(type 值为0x1),因此 root 用户无需(也不允许)通过该接口重复创建。 :::

参数列表

参数类型说明取值范围是否必填默认值
idstring用户 ID由字母、数字和下划线组成,不超过 21 个字符是无
pwdstring用户密码无限制否CubeFSUser
akstring对象存储 Access Key由 16 位字母和数字组成否系统自动生成
skstring对象存储 Secret Key由 32 位字母和数字组成否系统自动生成
typeint用户类型2(管理员)/ 3(普通用户)是无

源码级校验规则(可参见 master/user.go 的createKey与 master/api_service_user.go):

  • 用户 ID 必须匹配ownerRegexp,即^[A-Za-z][A-Za-z0-9_]{0,20}$(首字符必须为字母,总长度不超过 21 字符),该正则定义于 master/server.go。不匹配时返回ErrInvalidUserID。
  • 类型必须合法(Valid()通过且非 root),否则返回ErrInvalidUserType。
  • 密码为空时默认使用CubeFSUser(常量DefaultUserPassword);密码在存储时经 SHA-1 摘要后保存(encodingPassword,见 master/user.go)。
  • AK/SK 为空时通过util.RandomString随机生成,且会循环检查 AK 在AKStore中的唯一性,避免与既有用户冲突;显式传入的 AK/SK 则需分别满足AKRegexp(^[a-zA-Z0-9]{16}$)与SKRegexp(^[a-zA-Z0-9]{32}$),见 proto/user_proto.go。
  • 用户 ID 重复时返回ErrDuplicateUserID。

删除用户(Delete User)

curl -v "http://10.196.59.198:17010/user/delete?user=testuser"

删除集群中指定的用户。

参数列表

参数类型说明
userstring用户 ID

删除前置约束(见 master/user.go 的deleteKey):删除前会检查该用户是否仍拥有卷(Policy.OwnVols非空则返回ErrOwnVolExists),root 用户不可删除(返回ErrNoPermission),用户不存在返回ErrUserNotExists。删除成功后,Master 会同步从userStore、AKStore以及各卷的volUser索引中移除该用户(removeUserFromAllVol)。

查询用户信息(Query User Information)

查询接口返回用户基本信息,包括用户ID、Access Key、Secret Key、用户拥有的卷列表、其他用户授予的权限列表、用户类型、创建时间等。其中:

  • policy字段:表示该用户拥有权限的卷及其权限;
  • own_vols:表示 Owner 为该用户的卷;
  • authorized_vols:表示其他用户授权的卷及对应的权限限制。

上述字段对应 proto/user_proto.go 中的UserPolicy结构:OwnVols []string与AuthorizedVols map[string][]string(卷到权限字符串列表的映射)。

按用户 ID 查询

curl -v "http://10.196.59.198:17010/user/info?user=testuser" | python -m json.tool

参数列表

参数类型说明
userstring用户 ID

按 Access Key 查询

curl -v "http://10.196.59.198:17010/user/akInfo?ak=0123456789123456" | python -m json.tool

参数列表

参数类型说明
akstring用户 16 位 Access Key

按 AK 查询时,Master 先通过AKStore反查AKUser(AK 与用户 ID 的映射),再取出完整用户信息(getKeyInfo,见 master/user.go)。AK 参数还会经AKRegexp校验格式(master/api_service_user.go)。

响应示例

{ "user_id": "testuser", "access_key": "gDcKaBvqky4g8StT", "secret_key": "ZVY5RHlrnOrCjImW9S3MajtYZyxSegcf", "policy": { "own_vols": ["vol1"], "authorized_vols": { "ltptest": [ "perm:builtin:ReadOnly", "perm:custom:PutObjectAction" ] } }, "user_type": 3, "create_time": "2020-05-11 09:25:04" }

该响应结构即 proto/user_proto.go 中UserInfo的 JSON 序列化结果。

查询用户列表(Query User List)

curl -v "http://10.196.59.198:17010/user/list?keywords=test" | python -m json.tool

查询集群中所有用户 ID 包含指定关键字的用户信息。底层实现遍历userStore,用strings.Contains(userInfo.UserID, keywords)进行子串匹配(getAllUserInfo,见 master/user.go)。

参数列表

参数类型说明
keywordsstring在用户 ID 中搜索的关键字

更新用户信息(Update User Information)

curl -H "Content-Type:application/json" -X POST --data '{"user_id":"testuser","access_key":"KzuIVYCFqvu0b3Rd","secret_key":"iaawlCchJeeuGSnmFW72J2oDqLlSqvA5","type":3}' "http://10.196.59.198:17010/user/update"

更新指定用户 ID 的信息,包括Access Key、Secret Key与用户类型。

参数列表

参数类型说明是否必填
user_idstring要更新的用户 ID是
access_keystring新的 Access Key否
secret_keystring新的 Secret Key否
typeint新的用户类型否

源码细节(updateKey,见 master/user.go):未修改的用户 ID 返回ErrInvalidUserID;root 用户不允许被修改(ErrNoPermission);新的 AK 会做格式校验与全局唯一性检查(重复返回ErrDuplicateAccessKey);type传入 0 表示不修改类型;更新 AK 时同时维护AKStore映射(先删除旧 AK 条目,再写入新 AK 条目),保证 AK 反查的一致性。测试用例 master/api_service_test.go 展示了通过createKey创建用户并调用transferVol的典型用法。

用户授权(User Authorization)

curl -H "Content-Type:application/json" -X POST --data '{"user_id":"testuser","volume":"vol","policy":["perm:builtin:ReadOnly","perm:custom:PutObjectAction"]}' "http://10.196.59.198:17010/user/updatePolicy"

更新指定用户对某个卷的访问权限。policy的取值可以是以下几种形式之一:

  • 只读或读写权限,取值为perm:builtin:ReadOnly或perm:builtin:Writable;
  • 指定操作的权限,格式为action:oss:XXX。例如GetObject操作对应的 policy 值为action:oss:GetObject;
  • 自定义权限,格式为perm:custom:XXX,其中 XXX 由用户自定义。

指定权限后,该用户在使用对象存储功能时只能在规定的权限范围内访问该卷。

::: danger 警告 如果该用户已拥有对此卷的权限设置,此操作会覆盖原有权限。 :::

参数列表

参数类型说明是否必填
user_idstring设置权限的用户 ID是
volumestring设置权限的卷名称是
policystring slice要设置的权限列表是

权限模型与底层实现:

  • 权限字符串经由 proto/perm_action.go 中的ParsePermission/ParseAction解析。内置权限(builtin)匹配正则^perm:builtin:...:(Writable|ReadOnly)$,操作权限(action)匹配^action:((oss:(\w+))|(posix:(\w)+))$,自定义权限匹配^perm:custom:(\w)+$。
  • AddAuthorizedVol(见 proto/user_proto.go)会过滤掉无法解析的非法权限项后写入AuthorizedVols[volume],因此同一卷的授权是整体覆盖语义。
  • 更新前会校验卷是否存在(返回ErrCodeVolNotExists),且不允许对用户自己拥有的卷授权(返回ErrIsOwner,见 master/user.go)。
  • 权限判断时,UserPolicy.IsAuthorized/IsAuthorizedS3(proto/user_proto.go)负责判定用户对卷与具体操作的访问权:owner 默认拥有全部权限;内置Writable权限覆盖写类 S3 API,内置ReadOnly权限则结合WriteS3Api列表(PutObject、DeleteObject、CompleteMultipartUpload等)拒绝写操作。
  • 内置权限还映射到具体操作集合builtinPermissionActionsMap(proto/perm_action.go),例如ReadOnly包含OSSGetObjectAction、OSSListObjectsAction、POSIXReadAction等,Writable在其基础上追加OSSPutObjectAction、OSSUploadPartAction、POSIXWriteAction等。
  • 授权成功后还会在卷的用户索引volUser中登记(addUserToVol),便于按卷反查用户。

移除用户权限(Remove User Permissions)

curl -H "Content-Type:application/json" -X POST --data '{"user_id":"testuser","volume":"vol"}' "http://10.196.59.198:17010/user/removePolicy"

移除指定用户对某个卷的全部权限。

参数列表

参数类型说明是否必填
user_idstring移除权限的用户 ID是
volumestring移除权限的卷名称是

底层实现调用removePolicy(master/user.go):对用户拥有的卷执行该操作会返回ErrIsOwner;否则从AuthorizedVols中删除该卷条目(RemoveAuthorizedVol),并同步从volUser索引中移除用户与卷的关联。

转移卷(Transfer Volume)

curl -H "Content-Type:application/json" -X POST --data '{"volume":"vol","user_src":"user1","user_dst":"user2","force":true}' "http://10.196.59.198:17010/user/transferVol"

转移指定卷的所有权。此操作将指定卷从源用户移除并添加到目标用户,同时将卷结构中的Owner字段值更新为目标用户的用户 ID。

参数列表

参数类型说明是否必填
volumestring要转移所有权的卷名称是
user_srcstring卷的原始属主,必须与卷Owner字段的原值一致是
user_dststring所有权转移的目标用户 ID是
forcebool是否强制转移卷。设为 true 时,即使user_src与卷Owner字段的值不相等,卷也会被转移到目标用户否

源码级执行流程(transferUserVol见 master/api_service_user.go,transferVol见 master/user.go):

  1. 校验卷存在(不存在返回ErrCodeVolNotExists)。
  2. 非force模式下,若vol.Owner != param.UserSrc,直接返回ErrHaveNoPolicy拒绝转移。
  3. 调用transferVol:若源用户确实拥有该卷,先从源用户移除该卷所有权(removeOwnVol),再为目标用户添加该卷所有权(addOwnVol)。
  4. 更新卷的Owner字段为目标用户 ID,并通过m.cluster.syncUpdateVol(vol)将卷元数据同步写入 Raft 持久化;若同步失败则回滚Owner并返回ErrPersistenceByRaft。
  5. 测试用例 master/api_service_test.go 中createUserWithPolicy即通过transferVol将卷commonVolName的所有权转移给新用户cfs,可作实践参考。

接口速查与运维建议

操作方法路径关键参数
创建用户POST/user/createid, pwd, ak, sk, type
删除用户GET/POST/user/deleteuser
按 ID 查询GET/user/infouser
按 AK 查询GET/user/akInfoak
查询列表GET/user/listkeywords
更新用户POST/user/updateuser_id, access_key, secret_key, type
用户授权POST/user/updatePolicyuser_id, volume, policy[]
移除权限POST/user/removePolicyuser_id, volume
转移卷POST/user/transferVolvolume, user_src, user_dst, force

实际使用时请注意以下几点:

  • 所有接口均针对 Master 节点 HTTP 服务(默认17010端口)发起,路由注册见 master/http_server.go。
  • 创建与更新接口仅接受admin(2)与normal(3)两种类型,root 用户由集群自动创建且不可被删除或降级。
  • 用户的密码仅用于本地身份校验(SHA-1 摘要存储),对象存储访问凭证是 AK/SK;AK 是 16 位、SK 是 32 位的字母数字串,也可由调用方显式指定。
  • 授权操作对同一卷是整体覆盖语义,追加新权限前请先查询用户当前authorized_vols,避免误覆盖既有策略。
  • 卷所有权转移涉及卷元数据的 Raft 持久化,建议在业务低峰期执行,并确认目标用户已存在;force=true可用于修复卷 Owner 与实际属主不一致的历史遗留数据。
  • 存储
  • 分布式文件系统
  • 对象存储
  • 云原生

【免费下载链接】cubefs

cloud-native distributed storage

项目地址:https://gitcode.com/gh_mirrors/cu/cubefs
点击查看免费下载

相关推荐

上一篇:如何高效转换3D VR视频:专业创作者必备的完整指南
下一篇:音频转MIDI终极指南:用Spotify开源工具实现专业级音乐转录

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询