根本原因是所有节点未使用同一份keyFile文件进行认证,导致replSetHeartbeat心跳请求被拒绝,选举卡在STARTUP2;必须确保各节点keyFile二进制完全一致、权限600、启动时同步启用且与replSetName等配置严格对齐。

Replica Set 选举失败报错 not authorized on admin to execute command { replSetHeartbeat }
这是典型内部认证未对齐导致的选举卡住:节点间心跳请求被拒绝,Primary 无法确认 Secondary 状态,进而触发反复重选或长期处于 STARTUP2。根本原因不是权限角色没配,而是所有节点没用**同一个密钥文件**做 keyFile 认证。
- 必须确保每个节点启动时加载的
keyFile是同一份二进制文件(不能只是内容相同,md5 也得一致) -
keyFile权限必须为600(chmod 600 /data/keyfile),否则 mongod 拒绝读取 - 配置中启用认证必须与 keyFile 同步:启动参数加
--keyFile /data/keyfile,或配置文件里写security.keyFile: "/data/keyfile" - 不要混用
keyFile和x.509;二者互斥,选一个就到底
为什么复制集里用 keyFile 而不用 SCRAM-SHA-256 用户密码?
SCRAM 是面向客户端连接的身份验证,解决的是“谁有权限连上来读写”,而 keyFile 解决的是“集群节点之间是不是可信成员”。Replica Set 内部通信(如心跳、oplog 拉取、投票消息)走的是 mongod 进程间通道,不经过用户认证层,必须靠共享密钥建立信任链。
- 即使你已创建了
clusterAdmin角色用户,它对replSetHeartbeat这类内部命令无效 -
keyFile本质是 HMAC-SHA-1 签名密钥,用于签名节点间所有 RPC 请求头,服务端校验签名而非密码 - 密钥长度建议 6–1024 字节,过短易被暴力猜解(可用
openssl rand -base64 741 > keyfile生成)
配置相同 keyFile 后仍选举失败的排查点
密钥文件一致只是前提,以下任一环节出错都会让节点互相“认不出”:
- 各节点
replSetName配置值不完全一致(包括大小写、空格、引号),比如"rs0"和rs0在 YAML 配置里可能被解析为不同字符串 - 某个节点启用了
security.authorization: true但没配keyFile,或反过来——二者必须同时启用 - 防火墙/安全组未放开节点间
27017端口的 TCP 入向连接(注意:是双向,不是只放 Primary 的入向) -
host名解析不一致:节点在rs.conf()里声明的 hostname,必须能被其他节点ping通且反向解析一致(推荐全用 IP 或统一配/etc/hosts)
快速验证 keyFile 是否生效的命令
登录任意节点后执行,看输出是否含 "authenticated": true 且无权限错误:
db.adminCommand({ replSetGetStatus: 1 })
如果返回 "not authorized",说明当前连接未通过内部认证,大概率是该节点没加载 keyFile,或加载了但文件权限不对。此时别急着改用户权限,先检查 mongod 启动日志里有没有类似 Failed to load keyfile: Permission denied 或 keyFile is empty 的提示。
跨节点信任一旦建立,后续增减节点只需保证新节点用同一份 keyFile、同名 replSetName、网络互通——其余全是自动的。最容易被忽略的是:密钥文件拷贝过去后忘记 chown mongod:mongod 和 chmod 600,Linux 下权限不对等于没配。


















