Docker部署MongoDB副本集:主机无法连接副本集但可连独立实例
Docker部署MongoDB副本集:主机无法连接副本集问题
背景
我通过docker-compose.yml搭建了包含3个实例的MongoDB副本集,已通过rs.initiate(config)成功初始化副本集。
主机可连接单个实例
在同一主机上,我能够通过mongosh成功连接单个MongoDB实例:
# 主机端执行 $ mongosh localhost:3001 ... Connecting to: mongodb://localhost:3001/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.10.6 ... rs0 [direct: primary] test> rs.status() { set: 'rs0', ... members: [ { _id: 0, name: 'mongo1:27017', stateStr: 'PRIMARY', ... }, { _id: 1, name: 'mongo2:27017', stateStr: 'SECONDARY', ... }, { _id: 2, name: 'mongo3:27017', stateStr: 'SECONDARY', ... }, ], ok: 1, ... }
容器内可正常连接副本集
进入MongoDB容器的shell后,能够成功连接整个副本集:
# 主机端执行 $ docker compose exec -it mongo1 bash # 在mongo1容器内执行 $ mongosh mongodb://mongo1,mongo2,mongo3?replicaSet=rs0 ... 连接成功 rs0 [primary] test>
主机连接副本集失败
但在主机上尝试连接副本集时,无论是使用mongosh、pymongo还是NodeJS的mongodb驱动均失败,执行以下命令都会报错:
# 主机端执行,全部失败 $ mongosh mongodb://localhost:3001?replicaSet=rs0 $ mongosh mongodb://localhost:3001,localhost:3002,localhost:3003?replicaSet=rs0 $ mongosh "mongodb://localhost:3001,localhost:3002,localhost:3003?replicaSet=rs0&authSource=admin" # 统一报错信息: MongoServerSelectionError: Server selection timed out after 2000 ms
疑问
我猜测该问题与网络绑定配置有关,启动mongod时已指定--bind_ip_all,这个配置对单个实例的连接有效,但对副本集的连接无效。
复现方式
执行docker compose up即可复现问题,相关配置文件内容如下:
docker-compose.yml
version: '3.8' services: mongo1: image: mongo:6.0 container_name: mongo1 command: mongod --replSet rs0 --bind_ip_all ports: - "3001:27017" volumes: - mongo1_data:/data/db - ./rs-init.sh:/scripts/rs-init.sh networks: - mongo_cluster mongo2: image: mongo:6.0 container_name: mongo2 command: mongod --replSet rs0 --bind_ip_all ports: - "3002:27017" volumes: - mongo2_data:/data/db networks: - mongo_cluster mongo3: image: mongo:6.0 container_name: mongo3 command: mongod --replSet rs0 --bind_ip_all ports: - "3003:27017" volumes: - mongo3_data:/data/db networks: - mongo_cluster volumes: mongo1_data: mongo2_data: mongo3_data: networks: mongo_cluster: driver: bridge
rs-init.sh
#!/bin/bash # 等待MongoDB启动完成 sleep 10 # 初始化副本集 mongosh --host mongo1:27017 <<EOF rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "mongo1:27017" }, { _id: 1, host: "mongo2:27017" }, { _id: 2, host: "mongo3:27017" } ] }) EOF
内容的提问来源于stack exchange,提问作者Henry Fung
相关产品推荐
相关产品推荐

