必须同步修改bindIp和rs.conf()中的host字段,否则节点间握手失败、状态卡在STARTUP2或RECOVERING;bindIp决定谁能连进来,host字段决定别人怎么连你,二者缺一不可。

直接改 bindIp 配置并重载服务即可,但必须同步更新副本集成员配置里的 host 字段,否则节点间握手失败、状态卡在 STARTUP2 或 RECOVERING。
修改 mongod.conf 的 bindIp 项
这是让 mongod 实际监听内网地址的第一步。不能只改副本集配置而忽略这一步,否则即使 rs.conf() 里写了内网 IP,进程本身仍只监听 127.0.0.1 或未绑定任何地址。
-
bindIp必须显式列出所有要监听的地址,例如:bindIp: 127.0.0.1,192.168.1.30(多个用英文逗号分隔) - 禁止同时设置
bindIp和bindIpAll: true,二者互斥,mongod 启动会报错 - 若用主机名(如
mongodb0),需确保所有节点的/etc/hosts中已正确映射该名到内网 IP,且 DNS 不解析为公网 IP - 改完后必须重启 mongod:不支持热重载
bindIp,kill -SIGUSR1或mongod --shutdown均无效
更新 rs.conf() 中每个成员的 host 字段
副本集元数据里存的是「对外宣称的连接地址」,和 mongod 实际监听地址是两回事。客户端、其他成员都按这个 host 去连 —— 如果它还是旧的公网 IP,就会连不上或超时。
- 先执行
cfg = rs.conf()拿到当前配置 - 逐个检查
cfg.members[i].host,把类似203.208.60.1:27017的公网地址替换成对应内网 IP,例如192.168.1.30:27017 - 务必确认端口一致;如果某节点用了非默认端口(如
22400),host字段也得带对端口 - 执行
rs.reconfig(cfg, {force: true})强制生效(主节点不可用时可能需要force) - 执行后立刻用
rs.status().members看各成员stateStr是否变为PRIMARY/SECONDARY,而非DOWN或UNKNOWN
验证节点间能否互相解析和连通
光改配置不够,Linux 层面的网络可达性与名称解析必须闭环,否则副本集心跳失败。
- 在每个节点上执行
ping -c 3 mongodb0(或对应主机名),确认能通且走的是内网路径(看返回的 IP 是否为内网) - 用
telnet 192.168.1.31 27017测试端口连通性,避免被防火墙或安全组拦截 - 检查系统防火墙:
sudo ufw status(Ubuntu)或sudo firewall-cmd --list-ports(CentOS),确保内网端口开放 - 云服务器(如阿里云/腾讯云)还需在安全组中放行内网网段(如
192.168.1.0/24)到目标端口,公网安全组规则不影响内网通信
为什么不能只改 bindIp 或只改 rs.conf?
两者缺一不可:前者决定「谁能连进来」,后者决定「别人怎么连你」。常见翻车点就是只改了 rs.conf(),结果 rs.status() 显示所有成员都是 DOWN,因为 mongod 根本没在那个 IP 上监听。
- 如果
bindIp是127.0.0.1,但rs.conf()写了192.168.1.30:其他节点尝试连192.168.1.30:27017,但该地址上无服务,连接拒绝 - 如果
bindIp正确,但rs.conf()还是公网 IP:客户端和从节点仍试图用公网 IP 连接,可能被防火墙丢弃或路由到错误机器 - MongoDB 5.0+ 对纯 IP 地址配置更敏感,若集群中混用 IP 和主机名,部分节点可能启动失败或拒绝加入副本集
最易被忽略的是 hosts 文件和安全组的双重校验 —— 改完配置后,别急着跑 rs.status(),先在每台机器上手动 telnet 对方内网 IP + 端口,通了再动副本集配置。

















