rs.status()报“not authorized”错误根本原因不是用户权限缺失,而是副本集节点间未建立信任链:keyfile未统一、权限非600、或未与security.authorization同步启用,导致replsetheartbeat心跳被拒,节点卡在startup2。

为什么rs.status()报“not authorized on admin to execute command { replSetHeartbeat }”
这不是用户权限没配好,而是副本集节点间根本没建立起信任链。replSetHeartbeat是内部心跳命令,不走SCRAM用户认证层,只认keyFile签名。报这个错,说明至少有一个节点没加载keyFile,或加载了但内容/权限/路径不对。
keyFile必须满足的三个硬性条件
缺一不可,否则节点互相“视而不见”:
-
chmod 600 /path/to/keyfile—— Linux下权限必须是600,哪怕700都不行,mongod启动时会直接拒绝读取 - 所有节点用的是**同一份二进制文件** —— 不是“内容一样”,而是
md5sum输出完全一致;用openssl rand -base64 741 > keyfile生成一次,scp分发,别各生成一份 - 配置必须同步启用 —— 不能A节点用
--keyFile,B节点只开了security.authorization: true;二者必须共存,且replSetName值(包括大小写、引号、空格)在所有节点配置中完全一致
防火墙和host解析这两个隐形杀手
即使keyFile全对,节点仍卡在STARTUP2,大概率是网络层没通透:
- 检查所有节点27017端口是否双向放开 —— 不只是Primary允许入向,Secondary也必须能主动连到Primary的27017,防火墙规则要双向配
- 每个节点
rs.conf()里写的host字段,必须能被其他节点ping通且nslookup反向解析一致 —— 比如写"node1:27017",那所有节点的/etc/hosts里都得有192.168.1.10 node1,不能有的写IP、有的写hostname - MongoDB 5.0+强制要求用DNS名而非IP —— 如果配置里硬写了
"192.168.1.10:27017",启动会直接失败
验证keyFile是否真正生效的最快方法
别等选举,登录任一节点后立刻执行:
db.runCommand({connectionStatus: 1})
看返回里有没有"authenticated": true和"authInfo"字段;再跑:
rs.status()
如果仍报Unauthorized,说明认证根本没加载成功 —— 此时回看日志里有没有Failed to load keyfile或permissions too open这类提示,比反复改配置更省时间。
真正麻烦的不是生成密钥,而是让所有节点在启动瞬间就用同一把钥匙、同一套地址、同一份信任契约说话。任何一环松动,整个复制集就停在STARTUP2不动。











