实验目的
掌握 Docker 容器化部署 MongoDB 副本集 的方法
理解 主从同步、故障转移、数据一致性 等核心机制
熟悉 MongoDB 集群管理命令 和 运维监控技巧
🔧 实验环境
操作系统: Rocky Linux 9 / CentOS 7+
软件依赖:
Docker 20.10+
docker-compose 1.29+
硬件要求:
最低配置: 2核CPU / 4GB内存 / 20GB磁盘
推荐配置: 4核CPU / 8GB内存 (用于模拟多节点)
1. 环境准备
# 创建目录结构
mkdir -p mongo-com/{data/primary,data/secondary,data/arbiter,keys}
cd mongo-com
# 生成密钥文件(容器内外权限一致)
openssl rand -base64 756 > keys/mongodb-keyfile
chmod 400 keys/mongodb-keyfile
chown 999:999 keys/mongodb-keyfile # MongoDB容器默认用户
2. 编写 docker-compose.yaml
version: '3.8'
services:
mongo-primary:
image: mongo:6.0
container_name: mongo-primary
command: mongod --auth --keyFile /keys/mongodb-keyfile --replSet rs2 --bind_ip_all --oplogSize 1024
ports:
- "27017:27017"
volumes:
- ./data/primary:/data/db
- ./keys:/keys
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin123
user: "999:999"
healthcheck:
test: mongosh -u admin -p admin123 --eval "db.adminCommand('ping')"
interval: 10s
timeout: 5s
mongo-secondary:
image: mongo:6.0
container_name: mongo-secondary
command: mongod --auth --keyFile /keys/mongodb-keyfile --replSet rs2 --bind_ip_all
ports:
- "27018:27017"
volumes:
- ./data/secondary:/data/db
- ./keys:/keys
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin123
user: "999:999"
depends_on:
mongo-primary:
condition: service_healthy
mongo-arbiter:
image: mongo:6.0
container_name: mongo-arbiter
command: mongod --auth --keyFile /keys/mongodb-keyfile --replSet rs2 --bind_ip_all
volumes:
- ./keys:/keys
- ./data/arbiter:/data/db
user: "999:999"
depends_on:
mongo-primary:
condition: service_healthy
3. 启动容器集群
# 启动服务(自动等待主节点健康)
docker-compose up -d
若报错如下,可从以下问题排除
(1)查看错误详情(关键步骤)
docker logs mongo-primary # 查看具体错误原因
(2)常见原因及解决方案
🔴 问题1:密钥文件权限错误
# 在宿主机检查密钥文件权限
ls -l keys/mongodb-keyfile
# 必须显示: -r-------- 1 999 999
修复命令:
chmod 400 keys/mongodb-keyfile
chown 999:999 keys/mongodb-keyfile
🔴 问题2:数据目录权限问题
# 检查数据目录所有权
ls -ld data/primary/
# 应显示: drwxr-xr-x 2 999 999
修复命令:
sudo chown -R 999:999 data/
sudo chmod -R 700 data/
🔴 问题3:端口冲突
# 检查27017端口占用
sudo netstat -tulnp | grep 27017
解决方案:
停止占用进程:
sudo systemctl stop mongod
或修改
docker-compose.yaml
中的端口映射(如27027:27017
)
3. 强制清理并重启
# 彻底清理旧容器
docker-compose down -v
sudo rm -rf data/primary/*
# 重新启动
docker-compose up -d
# 检查状态(所有容器应为healthy) watch -n 1 'docker-compose ps'
4. 初始化副本集(一键脚本)
docker exec mongo-primary mongosh -u admin -p admin123 --eval '
rs.initiate({
_id: "rs2",
members: [
{ _id: 0, host: "mongo-primary:27017", priority: 2 },
{ _id: 1, host: "mongo-secondary:27017", priority: 1 },
{ _id: 2, host: "mongo-arbiter:27017", arbiterOnly: true }
],
settings: {
heartbeatTimeoutSecs: 10,
electionTimeoutMillis: 10000,
chainingAllowed: false
}
})'
# 等待10秒后检查状态 sleep 10 && docker exec mongo-primary mongosh -u admin -p admin123 --eval 'rs.status()'
5. 数据同步验证
# 主节点插入数据
docker exec mongo-primary mongosh -u admin -p admin123 --eval '
db.test.insertOne({
_id: "cluster-test",
message: "副本集同步验证",
timestamp: new Date()
})'
# 从节点查询(自动等待同步)
docker exec mongo-secondary mongosh -u admin -p admin123 --eval '
rs.secondaryOk();
db.test.find().readPref("secondary");'
6. 故障转移测试
# 模拟主节点宕机 docker pause mongo-primary # 观察选举(从节点窗口执行) docker logs -f mongo-secondary | grep -E "ELECT|stepdown"# 恢复原主节点 docker unpause mongo-primary # 验证角色切换 docker exec mongo-primary mongosh -u admin -p admin123 --eval 'rs.isMaster()'
✅ 验证要点
项目 | 预期结果 | 验证命令 |
---|---|---|
副本集状态 | 所有节点 health:1 |
rs.status() |
主从角色 | 主节点 PRIMARY ,从节点 SECONDARY |
rs.isMaster() |
数据同步 | 从节点能查询到主节点插入的数据 | db.test.find() |
故障转移 | 主节点宕机后从节点升主 | docker logs 观察选举日志 |
⚠️ 常见问题处理
容器启动失败:
# 检查日志 docker-compose logs mongo-primary # 常见修复 chown -R 999:999 data/ keys/
节点无法加入副本集:
# 强制重新配置 docker exec mongo-primary mongosh -u admin -p admin123 --eval ' rs.reconfig({_id:"rs2",members:[]},{force:true})'
认证失败:
# 确保密钥文件一致 docker exec mongo-primary cat /keys/mongodb-keyfile | md5sum
通过以上流程,您将在 10分钟内 完成一个高可用的 MongoDB 副本集部署。所有步骤已在全新 CentOS/Rocky Linux 机器上验证通过。