根本原因是mongos与shard认证机制不一致:mongos用config server用户,shard需在自身admin库显式创建同名同密用户,且全集群必须共用同一keyFile并启用auth。

mongos 连接 shard 报 unauthorized 的根本原因
不是网络不通,也不是密码输错,而是 mongos 和 shard 之间**认证机制不一致**:mongos 认证用的是 config server 里的用户(通过 db.createUser 在 mongos 上创建),而 shard 节点根本不读 config server 的用户表。每个 shard 是独立的副本集,必须在它自己的 admin 数据库里显式创建同名、同角色、同密码的用户。
直连 shard 时必须用 shard 自己的用户,不能复用 mongos 创建的用户
常见错误是:在 mongos 上执行 use admin; db.createUser(...) 后,就以为所有节点都能用这个账号登录。实际一试 mongo --port 27001 -u admin -p xxx --authenticationDatabase admin 就报 not authorized on admin to execute command。
- 必须分别连接每个 shard 主节点(如
mongo --port 27001),在它的本地admin库中创建用户 - 角色建议统一用
root或至少包含clusterAdmin+userAdminAnyDatabase,否则sh.status()等运维命令会失败 - 密码必须完全一致 —— mongos 和 shard 之间不共享密码哈希,靠人工对齐
- 如果 shard 是副本集,只需在主节点执行
db.createUser,从节点会自动同步用户数据
keyFile 和 auth 启动参数必须同时生效且全集群统一
只加 security.authorization: enabled 不够,shard/mongos/config 三类节点还必须共用同一个 keyFile,否则内部通信(比如 mongos 向 shard 转发写请求)直接被拒绝。
- 生成密钥:
openssl rand -base64 753 > /data/mongodb/keyfile,权限设为600,属主为运行 mongod 的用户 - 所有节点配置中都要显式指定:
--keyFile /data/mongodb/keyfile(命令行)或security.keyFile: /data/mongodb/keyfile(YAML) - config server 和 shard 必须先停服务、加 keyFile、再重启;mongos 同理 —— 顺序错会导致 config 无法识别 shard
- 验证是否生效:
db.runCommand({getCmdLineOpts: 1})查看输出中是否有keyFile字段
如何快速验证 mongos 与 shard 的认证链路是否打通
不要等应用报错才排查,用最简命令逐层确认:
- 先确认 mongos 能连 config:
mongo --port 27017 --eval "printjson(db.runCommand({listShards: 1}))",返回ok: 1才算 config 通 - 再确认 mongos 能连 shard:
mongo --port 27017 --eval "sh.status()",如果卡住或报unauthorized,说明某个 shard 用户缺失或 keyFile 不匹配 - 最后直连单个 shard 主节点:
mongo --port 27001 -u root -p xxx --authenticationDatabase admin --eval "db.runCommand({ping: 1})",成功返回{"ok": 1}才算该 shard 认证就绪
最容易被忽略的是:config server 本身也要单独建用户、也要配 keyFile —— 它既是元数据服务,也是普通副本集,缺一不可。


















