外观
MongoDB Docker 部署
Docker 基础知识
Docker 概念
容器化技术:
- Docker 是一种容器化平台,允许将应用程序及其依赖打包到容器中
- 容器是轻量级、可移植的,提供隔离的运行环境
- 支持跨平台部署,确保应用在不同环境中运行一致
核心组件:
- Docker 镜像:包含应用程序及其依赖的只读模板
- Docker 容器:从镜像创建的可运行实例
- Docker 仓库:存储和分发镜像的地方(如 Docker Hub)
- Docker Compose:用于定义和运行多容器 Docker 应用的工具
MongoDB Docker 镜像
官方镜像:
- MongoDB 官方提供的 Docker 镜像:
mongo - 支持多个版本标签,如
latest、5.0、6.0、7.0 - 基于 Alpine Linux 或 Debian,体积小,性能好
- 定期更新,包含最新的安全补丁
镜像选择:
- 生产环境建议使用特定版本标签,避免自动更新导致的兼容性问题
- 测试环境可以使用
latest标签 - 考虑镜像大小和性能需求选择基础镜像
单节点部署
基本部署
简单启动:
bash
# 拉取 MongoDB 镜像
docker pull mongo:6.0
# 启动单节点 MongoDB
docker run -d \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongo:6.0参数说明:
-d:后台运行容器--name:指定容器名称-p:端口映射,将容器内的 27017 端口映射到主机的 27017 端口-e:设置环境变量,初始化 root 用户
数据持久化
挂载数据卷:
bash
docker run -d \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v mongodb_data:/data/db \
-v mongodb_config:/data/configdb \
mongo:6.0使用主机目录:
bash
docker run -d \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v /host/path/data:/data/db \
-v /host/path/config:/data/configdb \
mongo:6.0注意事项:
- 确保主机目录权限正确,MongoDB 容器内使用
mongod用户(UID 999) - 使用数据卷比主机目录更安全,避免权限问题
- 定期备份数据卷或主机目录
自定义配置
使用配置文件:
bash
docker run -d \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v /host/path/mongod.conf:/etc/mongod.conf \
-v mongodb_data:/data/db \
mongo:6.0 --config /etc/mongod.confmongod.conf 示例:
yaml
storage:
dbPath: /data/db
journal:
enabled: true
net:
port: 27017
bindIp: 0.0.0.0
security:
authorization: enabled
replication:
replSetName: rs0副本集部署
基本副本集
步骤 1:创建网络
bash
docker network create mongodb-net步骤 2:启动副本集节点
bash
# 主节点
docker run -d \
--name mongodb-primary \
--network mongodb-net \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v mongodb-primary:/data/db \
mongo:6.0 --replSet rs0
# 从节点 1
docker run -d \
--name mongodb-secondary1 \
--network mongodb-net \
-p 27018:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v mongodb-secondary1:/data/db \
mongo:6.0 --replSet rs0
# 从节点 2
docker run -d \
--name mongodb-secondary2 \
--network mongodb-net \
-p 27019:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v mongodb-secondary2:/data/db \
mongo:6.0 --replSet rs0步骤 3:初始化副本集
bash
# 连接到主节点
docker exec -it mongodb-primary mongosh -u admin -p password --authenticationDatabase admin
# 初始化副本集
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongodb-primary:27017" },
{ _id: 1, host: "mongodb-secondary1:27017" },
{ _id: 2, host: "mongodb-secondary2:27017" }
]
})带仲裁节点的副本集
添加仲裁节点:
bash
docker run -d \
--name mongodb-arbiter \
--network mongodb-net \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-v mongodb-arbiter:/data/db \
mongo:6.0 --replSet rs0 --smallfiles
# 连接到主节点并添加仲裁节点
docker exec -it mongodb-primary mongosh -u admin -p password --authenticationDatabase admin
rs.addArb("mongodb-arbiter:27017")仲裁节点作用:
- 不存储数据,只参与选举
- 用于偶数节点的副本集,确保能选出主节点
- 降低硬件成本
Docker Compose 部署
单节点部署
docker-compose.yml 示例:
yaml
version: '3.8'
services:
mongodb:
image: mongo:6.0
container_name: mongodb
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongodb_data:/data/db
- mongodb_config:/data/configdb
restart: unless-stopped
volumes:
mongodb_data:
mongodb_config:启动命令:
bash
docker-compose up -d副本集部署
docker-compose.yml 示例:
yaml
version: '3.8'
services:
mongodb-primary:
image: mongo:6.0
container_name: mongodb-primary
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongodb-primary:/data/db
- ./mongod.conf:/etc/mongod.conf
command: --config /etc/mongod.conf --replSet rs0
restart: unless-stopped
mongodb-secondary1:
image: mongo:6.0
container_name: mongodb-secondary1
ports:
- "27018:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongodb-secondary1:/data/db
- ./mongod.conf:/etc/mongod.conf
command: --config /etc/mongod.conf --replSet rs0
restart: unless-stopped
depends_on:
- mongodb-primary
mongodb-secondary2:
image: mongo:6.0
container_name: mongodb-secondary2
ports:
- "27019:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongodb-secondary2:/data/db
- ./mongod.conf:/etc/mongod.conf
command: --config /etc/mongod.conf --replSet rs0
restart: unless-stopped
depends_on:
- mongodb-primary
mongodb-arbiter:
image: mongo:6.0
container_name: mongodb-arbiter
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongodb-arbiter:/data/db
- ./mongod.conf:/etc/mongod.conf
command: --config /etc/mongod.conf --replSet rs0 --smallfiles
restart: unless-stopped
depends_on:
- mongodb-primary
volumes:
mongodb-primary:
mongodb-secondary1:
mongodb-secondary2:
mongodb-arbiter:初始化脚本:
bash
#!/bin/bash
echo "等待 MongoDB 启动..."
sleep 10
echo "初始化副本集..."
docker exec -i mongodb-primary mongosh -u admin -p password --authenticationDatabase admin <<EOF
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongodb-primary:27017" },
{ _id: 1, host: "mongodb-secondary1:27017" },
{ _id: 2, host: "mongodb-secondary2:27017" },
{ _id: 3, host: "mongodb-arbiter:27017", arbiterOnly: true }
]
})
EOF
echo "副本集初始化完成!"分片集群部署
基本架构
分片集群组件:
- 配置服务器副本集:存储集群元数据
- 分片副本集:存储实际数据
- mongos 路由:处理客户端请求
docker-compose.yml 示例:
yaml
version: '3.8'
services:
# 配置服务器副本集
configsvr01:
image: mongo:6.0
container_name: configsvr01
command: --configsvr --replSet configReplSet --port 27019
volumes:
- configsvr01:/data/db
ports:
- "27019:27019"
restart: unless-stopped
configsvr02:
image: mongo:6.0
container_name: configsvr02
command: --configsvr --replSet configReplSet --port 27019
volumes:
- configsvr02:/data/db
ports:
- "27020:27019"
restart: unless-stopped
configsvr03:
image: mongo:6.0
container_name: configsvr03
command: --configsvr --replSet configReplSet --port 27019
volumes:
- configsvr03:/data/db
ports:
- "27021:27019"
restart: unless-stopped
# 分片 1 副本集
shard1svr01:
image: mongo:6.0
container_name: shard1svr01
command: --shardsvr --replSet shard1ReplSet --port 27018
volumes:
- shard1svr01:/data/db
ports:
- "27022:27018"
restart: unless-stopped
shard1svr02:
image: mongo:6.0
container_name: shard1svr02
command: --shardsvr --replSet shard1ReplSet --port 27018
volumes:
- shard1svr02:/data/db
ports:
- "27023:27018"
restart: unless-stopped
shard1svr03:
image: mongo:6.0
container_name: shard1svr03
command: --shardsvr --replSet shard1ReplSet --port 27018
volumes:
- shard1svr03:/data/db
ports:
- "27024:27018"
restart: unless-stopped
# mongos 路由
mongos01:
image: mongo:6.0
container_name: mongos01
command: mongos --configdb configReplSet/configsvr01:27019,configsvr02:27019,configsvr03:27019 --port 27017
ports:
- "27017:27017"
restart: unless-stopped
depends_on:
- configsvr01
- configsvr02
- configsvr03
volumes:
configsvr01:
configsvr02:
configsvr03:
shard1svr01:
shard1svr02:
shard1svr03:初始化步骤:
- 启动所有容器
- 初始化配置服务器副本集
- 初始化分片副本集
- 将分片添加到集群
- 为集合启用分片
容器管理
基本操作
容器生命周期管理:
bash
# 查看容器状态
docker ps
# 停止容器
docker stop mongodb
# 启动容器
docker start mongodb
# 重启容器
docker restart mongodb
# 删除容器
docker rm mongodb
# 查看容器日志
docker logs -f mongodb
# 进入容器
docker exec -it mongodb bash数据管理:
bash
# 备份数据
docker exec -it mongodb mongodump -u admin -p password --authenticationDatabase admin --out /backup
# 恢复数据
docker exec -it mongodb mongorestore -u admin -p password --authenticationDatabase admin /backup
# 复制文件到容器
docker cp /host/path/file mongodb:/container/path/
# 从容器复制文件
docker cp mongodb:/container/path/file /host/path/监控与日志
Docker 监控:
bash
# 查看容器资源使用情况
docker stats mongodb
# 查看容器详细信息
docker inspect mongodbMongoDB 监控:
bash
# 连接到 MongoDB
docker exec -it mongodb mongosh -u admin -p password --authenticationDatabase admin
# 查看状态
show dbs
use admin
db.runCommand({ serverStatus: 1 })日志管理:
- MongoDB 日志默认输出到容器标准输出
- 可以通过
docker logs查看 - 建议配置日志驱动,将日志发送到集中式日志管理系统
最佳实践
生产环境建议
安全配置:
- 启用认证和授权
- 配置 TLS/SSL 加密
- 限制容器网络访问
- 定期更新镜像,应用安全补丁
- 使用 secrets 管理敏感信息,避免在环境变量中明文存储密码
性能优化:
- 使用 SSD 存储
- 配置适当的资源限制(CPU、内存)
- 优化 MongoDB 配置参数
- 合理设置索引
- 监控性能指标,及时调整
高可用性:
- 使用副本集部署
- 配置适当的副本集成员数(建议 3 个或 5 个节点)
- 考虑跨可用区部署
- 配置自动故障转移
备份与恢复
定期备份:
- 制定备份策略,包括全量备份和增量备份
- 验证备份的完整性和可恢复性
- 存储备份到安全的位置,考虑异地备份
- 定期测试恢复流程
恢复测试:
- 定期在测试环境中测试恢复流程
- 记录恢复时间,确保符合 RTO 要求
- 验证恢复后的数据完整性
常见问题(FAQ)
Q1: Docker 部署的 MongoDB 性能如何?
A1: Docker 部署的 MongoDB 性能接近裸机部署,主要影响因素包括:
- 存储驱动:建议使用 overlay2 或 zfs
- 磁盘 I/O:使用 SSD 存储
- 资源限制:合理配置 CPU 和内存限制
- 网络:使用桥接网络或主机网络,避免容器网络开销
Q2: 如何在 Docker 中升级 MongoDB 版本?
A2: 升级步骤包括:
- 备份现有数据
- 拉取新版本镜像
- 停止旧容器
- 使用新版本镜像启动容器,挂载相同的数据卷
- 执行版本升级命令(如
db.adminCommand({ setFeatureCompatibilityVersion: "6.0" })) - 验证升级结果
Q3: 如何处理 Docker 容器中的 MongoDB 数据?
A3: 数据管理建议:
- 使用 Docker 数据卷或绑定挂载持久化数据
- 定期备份数据卷或挂载目录
- 考虑使用外部存储系统,如 NFS 或 SAN
- 避免在容器内直接修改数据文件
Q4: 如何配置 MongoDB 容器的资源限制?
A4: 可以使用 Docker 的资源限制参数:
bash
docker run -d \
--name mongodb \
--cpus 4 \
--memory 16g \
--memory-swap 32g \
mongo:6.0或在 Docker Compose 中配置:
yaml
services:
mongodb:
image: mongo:6.0
deploy:
resources:
limits:
cpus: '4'
memory: 16gQ5: 如何在 Docker 中部署 MongoDB Atlas?
A5: MongoDB Atlas 是云托管服务,不需要在 Docker 中部署。如果需要本地模拟 Atlas 环境,可以使用 MongoDB Enterprise 镜像,或考虑使用 MongoDB Atlas Local Development Environment。
Q6: 如何处理 Docker 容器重启后 MongoDB 无法启动的问题?
A6: 常见原因和解决方法:
- 数据文件损坏:使用备份恢复
- 配置错误:检查配置文件
- 权限问题:确保数据目录权限正确
- 端口冲突:检查端口占用情况
- 资源不足:调整资源限制
Q7: 如何监控 Docker 中的 MongoDB 集群?
A7: 监控方案:
- 使用 Docker stats 监控容器资源使用
- 使用 MongoDB 内置的监控工具(如 mongostat、mongotop)
- 集成第三方监控工具,如 Prometheus + Grafana
- 使用 MongoDB Atlas 监控(如果使用 Atlas)
Q8: 如何实现 MongoDB Docker 容器的自动扩展?
A8: 自动扩展方案:
- 使用 Kubernetes 部署 MongoDB,利用 Kubernetes 的自动扩缩容功能
- 结合监控系统,当达到特定阈值时自动添加节点
- 对于分片集群,可以自动添加新分片
- 考虑使用 MongoDB Atlas,它提供自动扩展功能
