必须通过mongos连接并指定admin认证库才能执行sh.命令;clusterAdmin不提供数据操作权限,需额外授权业务库角色;首次创建管理员用户须从localhost连接且bindIp包含localhost;权限为并集而非覆盖。

clusterAdmin 用户连 mongos 才能执行 sh. 命令
在分片集群中,clusterAdmin 权限不是“连上任意节点就能用”的。如果你用 mongo --host shard1:27017 直接连某个分片节点,sh.status()、sh.addShard() 这类命令会报错:ReferenceError: sh is not defined 或 not authorized on config to execute command。这是因为 sh 是 mongos 提供的 shell 辅助对象,只在路由层生效。
必须通过 mongos 实例连接,并显式指定认证数据库:
mongo --host mongos01:27017 -u clustermgr -p strongPass123 --authenticationDatabase admin
否则即使用户拥有 clusterAdmin,也会因连接上下文缺失而无法触发分片逻辑。
给 clusterAdmin 用户加业务库权限要显式 grantRolesToUser
clusterAdmin 只管集群结构,不管数据。它不能 insertOne、find 任何业务集合——哪怕你已经用 use myapp 切换过去,执行 db.users.insertOne({}) 仍会失败,报错:not authorized on myapp to execute command { insert: "users", ... }。
解决办法不是改角色定义,而是额外授权:
- 必须先
use admin - 再运行
db.grantRolesToUser("clustermgr", [{ role: "readWrite", db: "myapp" }]) - 如果还要查报表库,追加
{ role: "read", db: "reporting" }
注意:不能在创建用户时一次性写全所有角色(比如把 clusterAdmin 和 readWrite 都塞进 createUser 的 roles 数组),因为 clusterAdmin 要求 db: "admin",而 readWrite 要求 db: "myapp",MongoDB 不允许跨库角色混写在同一 createUser 调用中。
避免用 localhost 创建用户导致权限不生效
分片集群里,首次创建 clusterAdmin 这类高权用户,必须满足一个隐藏条件:连接必须来自 localhost,且配置文件中 net.bindIp 必须包含 localhost,例如:
net: bindIp: localhost,192.168.0.253 port: 27017
如果只写了 192.168.0.253,即使你从本机用 127.0.0.1 连,MongoDB 也会拒绝创建管理员用户,报错:not authorized on admin to execute command { createUser: ... }。
这个限制只对“首次创建第一个管理员用户”生效;后续用已有管理员用户调用 createUser 或 grantRolesToUser 就不再受此约束。
权限叠加不等于自动继承,role 冲突时以显式声明为准
MongoDB 不会因为你给了 readWriteAnyDatabase 就自动覆盖 clusterAdmin 的限制——它们作用域完全不同:readWriteAnyDatabase 控制数据读写,clusterAdmin 控制分片/副本集元操作。但两者可以共存于同一用户。
容易被忽略的一点是:权限不自动降级。比如你先给用户 readWriteAnyDatabase,再单独给 myapp 库的 read 角色,这个 read 不会撤掉它对 myapp 的写权限。MongoDB 的权限模型是“并集”,不是“覆盖”。要收权限,必须用 revokeRolesFromUser 显式移除。

















