Docker部署MongoDB分片集群无法连接至MongoDB路由器问题求助
看起来你已经搭好了分片集群的基础容器架构,但连接mongos失败通常和初始化顺序、副本集配置、脚本执行环境这几个核心点有关。我帮你梳理关键问题和修复方案:
一、先排查核心错误:查看mongos日志
首先得确认mongos自身是否正常启动,执行这条命令拉取日志:
docker logs mongorouter
如果日志里出现类似Could not reach any servers in mongorsconf/mongoconf:27017的报错,那就是配置副本集的初始化或通信出了问题,这是最常见的诱因。
二、修复初始化脚本的关键问题
你的setup.sh存在几个明显的执行逻辑问题,导致集群没有正确完成初始化:
1. 移除docker exec的-it参数
脚本属于非交互式执行环境,-it会强制要求终端交互,直接导致命令执行失败。把所有docker exec -it改成docker exec即可。
2. 延长等待时间,确保服务就绪
3秒的休眠时间远远不足以让Mongo服务完全启动并完成副本集初始化,建议改成10秒以上,或者后续可以用wait-for-it工具做精准的就绪检测,先通过延长时间解决基础问题。
3. 副本集初始化时指定端口(避免环境变量冲突)
你的shard和config服务都用了环境变量指定端口,如果后续修改了端口值,初始化命令里的host必须带上对应端口,否则副本集内部无法正常通信。比如:
- config副本集初始化:
host : "mongoconf:${MONGO_CONFIG_PORT:-27017}" - shard1副本集初始化:
host : "mongoshard1:${MONGO_SHARD_PORT:-27017}" - shard2同理
4. 调整初始化顺序:先完成副本集初始化,再启动mongos
mongos启动时依赖已就绪的config副本集,如果mongos先于config副本集启动,会一直处于等待连接的状态。所以先启动config和shard服务,完成副本集初始化后再启动mongos,确保它能正确连接到配置集群。
修复后的setup.sh脚本:
#!/bin/bash # 先启动config和shard服务,暂时不启动mongos docker-compose up -d mongoconf mongoshard1 mongoshard2 seconds=10 echo "等待服务启动就绪..." sleep $seconds # 初始化config副本集,指定端口 cmd="echo 'rs.initiate({_id: \"mongorsconf\", configsvr: true, members: [{ _id : 0, host : \"mongoconf:${MONGO_CONFIG_PORT:-27017}\" }]})' | mongo --port ${MONGO_CONFIG_PORT:-27017}" docker exec mongoconf bash -c "$cmd" # 初始化shard1副本集 cmd="echo 'rs.initiate({_id : \"mongors1\", members: [{ _id : 0, host : \"mongoshard1:${MONGO_SHARD_PORT:-27017}\" }]})' | mongo --port ${MONGO_SHARD_PORT:-27017}" docker exec mongoshard1 bash -c "$cmd" # 初始化shard2副本集 cmd="echo 'rs.initiate({_id : \"mongors2\", members: [{ _id : 0, host : \"mongoshard2:${MONGO_SHARD_PORT:-27017}\" }]})' | mongo --port ${MONGO_SHARD_PORT:-27017}" docker exec mongoshard2 bash -c "$cmd" echo "等待副本集初始化完成..." sleep $seconds # 启动mongos服务 docker-compose up -d mongorouter sleep $seconds echo "添加分片到mongos..." # 添加shard到mongos,注意指定副本集的端口 cmd="echo 'sh.addShard(\"mongors1/mongoshard1:${MONGO_SHARD_PORT:-27017}\")' | mongo --port ${MONGO_ROUTER_PORT:-27017}" docker exec mongorouter bash -c "$cmd" cmd="echo 'sh.addShard(\"mongors2/mongoshard2:${MONGO_SHARD_PORT:-27017}\")' | mongo --port ${MONGO_ROUTER_PORT:-27017}" docker exec mongorouter bash -c "$cmd" # 验证分片是否添加成功 cmd="echo 'sh.status()' | mongo --port ${MONGO_ROUTER_PORT:-27017}" docker exec mongorouter bash -c "$cmd" echo "集群初始化完成!"
三、检查docker-compose配置的细节
- mongos的
--configdb参数:你的配置里mongorsconf/mongoconf:${MONGO_CONFIG_PORT:-27017}是正确的,只要确保config副本集的_id确实是mongorsconf即可。 - 端口映射:mongos的
ports配置${MONGO_ROUTER_PORT:-27017}:${MONGO_ROUTER_PORT:-27017}没问题,外部可以通过localhost:27017(默认端口)正常访问。
四、验证连接的步骤
- 执行修复后的
setup.sh,确保所有命令都没有报错。 - 用MongoDB Compass连接
mongodb://localhost:27017,注意你的集群没有开启认证,无需填写用户名密码。 - 或者用命令行测试:
mongo --port 27017
进入后执行sh.status(),如果能看到分片信息,说明集群已经正常工作。
如果还是有问题,把docker logs mongorouter的错误信息贴出来,我再帮你进一步排查!
内容的提问来源于stack exchange,提问作者Gianmarco

