Docker部署MongoDB 5+/6.0.4集群启动失败问题求助
问题背景
在Docker上部署MongoDB分片集群时,使用MongoDB 5及以上版本镜像,沿用旧版(4.4.18及以下)的docker-compose配置,当添加MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD环境变量后,分片节点(shardsvr)和配置节点(configsvr)无法启动,日志报错:
BadValue: Cannot start a shardsvr as a standalone server. Please use the option --replSet to start the node as a replica set.
BadValue: Cannot start a configsvr as a standalone server. Please use the option --replSet to start the node as a replica set.
即使启动命令中已经配置了--replSet参数,仍会触发该错误。经排查,这是官方MongoDB Docker镜像的已知问题,相关修复尚未发布,在此之前无法直接通过上述环境变量初始化管理员用户。
可行解决方案
需要移除节点的初始化用户环境变量,改为在副本集和路由初始化完成后,通过脚本手动创建管理员用户,具体步骤如下:
1. 修改docker-compose配置
移除所有分片节点、配置节点和路由节点的MONGO_INITDB_ROOT_USERNAME、MONGO_INITDB_ROOT_PASSWORD环境变量,确保节点能正常启动。修改后的节点配置示例(以配置节点为例):
mongo-config-01: command: mongod --port 27017 --configsvr --replSet ${MONGO_RS_CONFIG_NAME} --keyFile /etc/mongo-cluster.key container_name: ${MONGO_CONFIG_SERVER}-01-${ENVIRONMENT_NAME} image: mongo:${MONGO_VERSION} networks: - mongo-network restart: always volumes: - ./keys/preprod/mongo-cluster.key:/etc/mongo-cluster.key - ./volumes/${ENVIRONMENT_NAME}/${MONGO_CONFIG_SERVER}-01/db:/data/db - ./volumes/${ENVIRONMENT_NAME}/${MONGO_CONFIG_SERVER}-01/configdb:/data/configdb
2. 初始化副本集和路由
启动所有容器后,依次完成以下初始化操作:
- 初始化配置节点副本集:进入任意一个配置节点容器,执行副本集初始化命令:
docker exec -it mongo-config-01-${ENVIRONMENT_NAME} mongosh --port 27017
在MongoShell中执行:
rs.initiate({ _id: "${MONGO_RS_CONFIG_NAME}", configsvr: true, members: [ { _id: 0, host: "mongo-config-01:27017" }, { _id: 1, host: "mongo-config-02:27017" }, { _id: 2, host: "mongo-config-03:27017" } ] })
等待副本集初始化完成,确认状态正常:rs.status()
- 初始化分片节点副本集:进入任意一个分片数据节点容器,执行副本集初始化:
docker exec -it mongo-data-01-${ENVIRONMENT_NAME} mongosh --port 27017
在MongoShell中执行:
rs.initiate({ _id: "${MONGO_RS_DATA_NAME}", members: [ { _id: 0, host: "mongo-data-01:27017" }, { _id: 1, host: "mongo-data-02:27017" }, { _id: 2, host: "mongo-arbiter-01:27017", arbiterOnly: true } ] })
确认副本集状态正常:rs.status()
- 添加分片到路由:进入任意一个路由节点容器,连接到mongos并添加分片:
docker exec -it mongo-router-01-${ENVIRONMENT_NAME} mongosh --port 27017
在MongoShell中执行:
sh.addShard("${MONGO_RS_DATA_NAME}/mongo-data-01:27017,mongo-data-02:27017,mongo-arbiter-01:27017")
3. 创建管理员用户
在路由节点的MongoShell中,切换到admin数据库,创建root用户:
use admin db.createUser({ user: "${MONGO_ADMIN_USER}", pwd: "${MONGO_ADMIN_PASSWORD}", roles: [ { role: "root", db: "admin" } ] })
创建完成后,验证用户登录:
db.auth("${MONGO_ADMIN_USER}", "${MONGO_ADMIN_PASSWORD}")
返回1表示认证成功。
4. (可选)自动化初始化脚本
为了避免手动操作,可以编写Shell脚本自动化完成上述步骤。示例脚本init-mongo-cluster.sh:
#!/bin/bash # 初始化配置副本集 docker exec -it mongo-config-01-${ENVIRONMENT_NAME} mongosh --port 27017 <<EOF rs.initiate({ _id: "${MONGO_RS_CONFIG_NAME}", configsvr: true, members: [ { _id: 0, host: "mongo-config-01:27017" }, { _id: 1, host: "mongo-config-02:27017" }, { _id: 2, host: "mongo-config-03:27017" } ] }) rs.status() EOF # 等待配置副本集初始化完成 sleep 10 # 初始化分片副本集 docker exec -it mongo-data-01-${ENVIRONMENT_NAME} mongosh --port 27017 <<EOF rs.initiate({ _id: "${MONGO_RS_DATA_NAME}", members: [ { _id: 0, host: "mongo-data-01:27017" }, { _id: 1, host: "mongo-data-02:27017" }, { _id: 2, host: "mongo-arbiter-01:27017", arbiterOnly: true } ] }) rs.status() EOF # 等待分片副本集初始化完成 sleep 10 # 添加分片到路由并创建管理员用户 docker exec -it mongo-router-01-${ENVIRONMENT_NAME} mongosh --port 27017 <<EOF sh.addShard("${MONGO_RS_DATA_NAME}/mongo-data-01:27017,mongo-data-02:27017,mongo-arbiter-01:27017") use admin db.createUser({ user: "${MONGO_ADMIN_USER}", pwd: "${MONGO_ADMIN_PASSWORD}", roles: [ { role: "root", db: "admin" } ] }) db.auth("${MONGO_ADMIN_USER}", "${MONGO_ADMIN_PASSWORD}") EOF echo "MongoDB集群初始化完成"
给脚本添加执行权限:chmod +x init-mongo-cluster.sh,然后运行脚本即可。
内容的提问来源于stack exchange,提问作者Ankou

