根本原因是分片集群任一节点解析其他成员host字段失败:config server、shard、mongos的/etc/hosts或dns必须双向解析所有成员全限定域名(大小写敏感),且bindip与防火墙需放行,nscd/systemd-resolved负缓存需清理。

rs.initiate() 或 addShard() 报 getaddrinfo name or service not known
根本原因不是 DNS 服务器挂了,而是分片集群里任一节点(config server、shard、mongos)在解析其他成员的 host 字段时失败。MongoDB 启动、初始化、添加分片时会主动调用系统 getaddrinfo(),只要返回 AI_NONAME 就直接报错退出,不重试也不降级。
- 检查点不止是 mongos —— config server 和每个 shard 节点自己的
/etc/hosts也必须能解析所有成员名(包括自己) - 常见漏项:mongos 配置里写的是
mongo1.example.com:27017,但 config server 的/etc/hosts只写了mongo1,没写全限定域名 - 大小写敏感:
Mongo1.example.com和mongo1.example.com是两个不同主机名 - 别只测 ping,用
getent hosts mongo1.example.com,它走的是系统 NSS 配置链,和 MongoDB 实际行为一致
mongos 连不上 config server 导致 sharding 初始化卡住
执行 sh.addShard() 前,mongos 必须先连上 config server 副本集并读取元数据。如果 config server 成员名解析失败,mongos 日志会出现反复重连 + Failed to connect to configReplSet/xxx:27019: HostNotFound,最终 addShard() 直接抛异常。
- config server 副本集本身也要满足「所有节点互相可解析」——哪怕你只启动一个 config server,它启动时也会查自己
hostname -f,解析失败会导致STARTUP2卡死 - mongos 的连接字符串里写的 config server 地址(如
mongodb://cfg1.example.com:27019,cfg2.example.com:27019/...)必须和 config server 自己rs.conf()里的members[n].host完全一致 - 不要混用 IP 和域名:如果 config server 配置用的是
192.168.10.20:27019,mongos 就不能写cfg1.example.com:27019,反之亦然
防火墙 + bindIp 双重阻断导致解析“成功”但连接失败
看似 getent hosts 能查到 IP,telnet cfg1.example.com 27019 却不通——这时候错误仍会表现为「主机名解析失败」,因为 MongoDB 在建立 TCP 连接前,会把解析出的 IP 传给 socket 层,而 socket 连接超时后,驱动层常把底层错误统一包装成 getaddrinfo 类错误。
免费 DNS 与邮件安全分析(IntoDNS.ai):包括 DNSSEC、SPF、DKIM、DMARC、MTA-STS、BIMI、SMTP STARTTLS、FCrDNS、黑名单、发件人要求及报告。
- 确认 config server 的
bindIp包含真实网卡 IP(如192.168.10.20),不是仅127.0.0.1或localhost - 检查 iptables/nftables 是否放行目标端口:
iptables -L -n | grep 27019;云环境额外查安全组规则 - mongos 本机也要能路由到该 IP:如果 config server 在内网
192.168.10.0/24,而 mongos 在10.0.1.0/24且无路由,getent成功但telnet必败
为什么改完 /etc/hosts 还是报错
Linux 下 nscd 或 systemd-resolved 可能缓存了旧的解析结果,尤其当之前解析失败过,缓存的是负向结果(NXDOMAIN),重启 mongod 也无效。
- 临时停掉缓存服务:
sudo systemctl stop nscd或sudo systemctl stop systemd-resolved - 或清空缓存:
sudo nscd -i hosts(nscd);sudo systemd-resolve --flush-caches(systemd-resolved) - 验证是否生效:改完 hosts 后立刻跑
getent hosts cfg1.example.com,必须返回新 IP,不能是空或旧值 - 注意:Docker 容器内修改
/etc/hosts对宿主机无效,宿主机改了对容器也无效,需分别处理
实际搭建时最容易被忽略的是:config server 副本集成员之间、mongos 与 config server、mongos 与各个 shard,这三类通信路径上的 每台机器 都要能双向解析对方主机名——少配一台,整个分片初始化就停在第一步。










