Skip to content

MongoDB 自动化安装

自动化安装 MongoDB 可以提高部署效率、减少人为错误、确保配置一致性,并支持大规模部署。常见的自动化安装方式包括:脚本安装、配置管理工具、容器化部署、容器编排和云服务提供商的托管服务。

脚本安装

Shell 脚本安装(Linux)

单实例安装脚本

bash
#!/bin/bash

# MongoDB 单实例自动化安装脚本

# 配置变量
MONGODB_VERSION="7.0"
MONGO_REPO_FILE="/etc/yum.repos.d/mongodb-org-${MONGODB_VERSION}.repo"
DB_PATH="/var/lib/mongo"
LOG_PATH="/var/log/mongodb"
CONFIG_FILE="/etc/mongod.conf"

# 1. 添加 MongoDB 官方仓库
echo "添加 MongoDB 官方仓库..."
cat > ${MONGO_REPO_FILE} << EOF
[mongodb-org-${MONGODB_VERSION}]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/${MONGODB_VERSION}/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-${MONGODB_VERSION}.asc
EOF

# 2. 安装 MongoDB
echo "安装 MongoDB..."
yum install -y mongodb-org

# 3. 创建数据和日志目录
echo "创建数据和日志目录..."
mkdir -p ${DB_PATH} ${LOG_PATH}
chown -R mongod:mongod ${DB_PATH} ${LOG_PATH}

# 4. 配置 MongoDB
echo "配置 MongoDB..."
cat > ${CONFIG_FILE} << EOF
storage:
  dbPath: ${DB_PATH}
  journal:
    enabled: true

systemLog:
  destination: file
  logAppend: true
  path: ${LOG_PATH}/mongod.log

net:
  port: 27017
  bindIp: 127.0.0.1

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod.pid

security:
  authorization: disabled
EOF

# 5. 启动 MongoDB 服务
echo "启动 MongoDB 服务..."
systemctl enable mongod
systemctl start mongod

# 6. 验证安装
echo "验证 MongoDB 安装..."
sleep 5
mongosh --eval "db.version()" 2>/dev/null

if [ $? -eq 0 ]; then
    echo "MongoDB 安装成功!"
else
    echo "MongoDB 安装失败,请检查日志。"
    exit 1
fi
EOF

复制集安装脚本

bash
#!/bin/bash

# MongoDB 复制集自动化安装脚本

# 配置变量
MONGODB_VERSION="7.0"
REPLICA_SET_NAME="rs0"
PRIMARY_IP="192.168.1.101"
SECONDARY1_IP="192.168.1.102"
SECONDARY2_IP="192.168.1.103"
DB_PATH="/var/lib/mongo"
LOG_PATH="/var/log/mongodb"
CONFIG_FILE="/etc/mongod.conf"
KEYFILE_PATH="/etc/mongodb/keyfile"

# 1. 安装 MongoDB(省略,参考单实例安装脚本)

# 2. 配置复制集
echo "配置复制集..."
cat > ${CONFIG_FILE} << EOF
storage:
  dbPath: ${DB_PATH}
  journal:
    enabled: true

systemLog:
  destination: file
  logAppend: true
  path: ${LOG_PATH}/mongod.log

net:
  port: 27017
  bindIp: 0.0.0.0

replication:
  replSetName: ${REPLICA_SET_NAME}

security:
  authorization: enabled
  keyFile: ${KEYFILE_PATH}
EOF

# 3. 创建密钥文件
echo "创建密钥文件..."
mkdir -p /etc/mongodb
openssl rand -base64 756 > ${KEYFILE_PATH}
chmod 400 ${KEYFILE_PATH}
chown mongod:mongod ${KEYFILE_PATH}

# 4. 启动 MongoDB 服务
echo "启动 MongoDB 服务..."
systemctl enable mongod
systemctl start mongod

# 5. 初始化复制集(仅在主节点执行)
if [ "$(hostname -i)" == "${PRIMARY_IP}" ]; then
    echo "初始化复制集..."
    sleep 10
    mongosh --eval "
        rs.initiate({
            _id: \"${REPLICA_SET_NAME}\",
            members: [
                { _id: 0, host: \"${PRIMARY_IP}:27017\" },
                { _id: 1, host: \"${SECONDARY1_IP}:27017\" },
                { _id: 2, host: \"${SECONDARY2_IP}:27017\" }
            ]
        })
    "
    
    # 创建管理员用户
    echo "创建管理员用户..."
    mongosh --eval "
        use admin
        db.createUser({
            user: \"admin\",
            pwd: \"admin123\",
            roles: [{ role: \"root\", db: \"admin\" }]
        })
    "
fi

# 6. 验证安装
echo "验证 MongoDB 复制集安装..."
sleep 5
mongosh --eval "rs.status()" --username admin --password admin123 --authenticationDatabase admin 2>/dev/null

if [ $? -eq 0 ]; then
    echo "MongoDB 复制集安装成功!"
else
    echo "MongoDB 复制集安装失败,请检查日志。"
    exit 1
fi
EOF

PowerShell 脚本安装(Windows)

powershell
# MongoDB 自动化安装脚本(Windows)

# 配置变量
$MongoDBVersion = "7.0.5"
$MongoDBUrl = "https://fastdl.mongodb.org/win32/mongodb-windows-x86_64-${MongoDBVersion}-symbols.msi"
$MongoDBMsiPath = "C:\temp\mongodb.msi"
$InstallPath = "C:\Program Files\MongoDB\Server\${MongoDBVersion}"
$DataPath = "C:\data\db"
$LogPath = "C:\data\log"

# 创建临时目录
New-Item -ItemType Directory -Path "C:\temp" -Force

# 下载 MongoDB MSI 安装包
Write-Host "下载 MongoDB ${MongoDBVersion}..."
Invoke-WebRequest -Uri $MongoDBUrl -OutFile $MongoDBMsiPath

# 安装 MongoDB
Write-Host "安装 MongoDB..."
msiexec.exe /i $MongoDBMsiPath /quiet ADDLOCAL="all" INSTALLLOCATION="${InstallPath}"

# 等待安装完成
Start-Sleep -Seconds 30

# 添加 MongoDB 到环境变量
$env:PATH += ";${InstallPath}\bin"
[Environment]::SetEnvironmentVariable("PATH", $env:PATH, [EnvironmentVariableTarget]::Machine)

# 创建数据和日志目录
New-Item -ItemType Directory -Path $DataPath -Force
New-Item -ItemType Directory -Path $LogPath -Force

# 创建配置文件
Write-Host "创建 MongoDB 配置文件..."
$ConfigContent = @"
storage:
  dbPath: ${DataPath}
  journal:
    enabled: true

systemLog:
  destination: file
  logAppend: true
  path: ${LogPath}\mongod.log

net:
  port: 27017
  bindIp: 127.0.0.1

processManagement:
  windowsService:
    serviceName: MongoDB
    displayName: MongoDB
    description: MongoDB Database Server
    startupType: auto
"@

$ConfigContent | Out-File -FilePath "${InstallPath}\bin\mongod.cfg" -Encoding ASCII

# 安装并启动 MongoDB 服务
Write-Host "安装 MongoDB 服务..."
& "${InstallPath}\bin\mongod.exe" --config "${InstallPath}\bin\mongod.cfg" --install

Write-Host "启动 MongoDB 服务..."
Start-Service MongoDB

# 验证安装
Write-Host "验证 MongoDB 安装..."
Start-Sleep -Seconds 10
& "${InstallPath}\bin\mongosh.exe" --eval "db.version()" 2>$null

if ($LASTEXITCODE -eq 0) {
    Write-Host "MongoDB 安装成功!"
} else {
    Write-Host "MongoDB 安装失败,请检查日志。"
    exit 1
}

Ansible 自动化安装

单实例安装 Playbook

yaml
---
- name: MongoDB 单实例安装
  hosts: mongodb_servers
  become: yes
  vars:
    mongodb_version: "7.0"
    mongodb_db_path: "/var/lib/mongo"
    mongodb_log_path: "/var/log/mongodb"
    mongodb_bind_ip: "127.0.0.1"
    mongodb_port: 27017
    mongodb_authorization: "disabled"

  tasks:
    - name: 添加 MongoDB YUM 仓库
      template:
        src: mongodb.repo.j2
        dest: "/etc/yum.repos.d/mongodb-org-{{ mongodb_version }}.repo"
        owner: root
        group: root
        mode: 0644

    - name: 安装 MongoDB 包
      yum:
        name: mongodb-org
        state: present
        update_cache: yes

    - name: 创建 MongoDB 数据目录
      file:
        path: "{{ mongodb_db_path }}"
        state: directory
        owner: mongod
        group: mongod
        mode: 0755

    - name: 创建 MongoDB 日志目录
      file:
        path: "{{ mongodb_log_path }}"
        state: directory
        owner: mongod
        group: mongod
        mode: 0755

    - name: 配置 MongoDB
      template:
        src: mongod.conf.j2
        dest: /etc/mongod.conf
        owner: root
        group: root
        mode: 0644
      notify: restart mongod

    - name: 启动并启用 MongoDB 服务
      service:
        name: mongod
        state: started
        enabled: yes

    - name: 验证 MongoDB 安装
      command: mongosh --eval "db.version()"
      register: mongodb_version_check
      changed_when: false
      ignore_errors: true

    - name: 显示 MongoDB 版本
      debug:
        msg: "MongoDB 版本: {{ mongodb_version_check.stdout }}"
      when: mongodb_version_check.rc == 0

  handlers:
    - name: restart mongod
      service:
        name: mongod
        state: restarted

复制集安装 Playbook

yaml
---
- name: MongoDB 复制集安装
  hosts: mongodb_replicas
  become: yes
  vars:
    mongodb_version: "7.0"
    mongodb_replica_set_name: "rs0"
    mongodb_keyfile_path: "/etc/mongodb/keyfile"
    mongodb_admin_user: "admin"
    mongodb_admin_password: "admin123"
    mongodb_replica_members:
      - { host: "192.168.1.101", port: 27017, priority: 10 }
      - { host: "192.168.1.102", port: 27017, priority: 5 }
      - { host: "192.168.1.103", port: 27017, priority: 5 }

  tasks:
    # 安装 MongoDB 包和创建目录(省略,参考单实例安装)

    - name: 创建密钥文件目录
      file:
        path: "/etc/mongodb"
        state: directory
        owner: mongod
        group: mongod
        mode: 0700

    - name: 生成密钥文件
      command: openssl rand -base64 756
      register: mongodb_keyfile_content
      run_once: true

    - name: 配置密钥文件
      copy:
        content: "{{ mongodb_keyfile_content.stdout }}"
        dest: "{{ mongodb_keyfile_path }}"
        owner: mongod
        group: mongod
        mode: 0400

    - name: 配置 MongoDB 复制集
      template:
        src: mongod.replica.conf.j2
        dest: /etc/mongod.conf
        owner: root
        group: root
        mode: 0644
      notify: restart mongod

    - name: 启动并启用 MongoDB 服务
      service:
        name: mongod
        state: started
        enabled: yes

    - name: 等待 MongoDB 服务启动
      wait_for:
        port: 27017
        delay: 10
        timeout: 60

    - name: 初始化复制集(仅在主节点执行)
      mongodb_replica_set:
        login_host: "{{ inventory_hostname }}"
        replica_set: "{{ mongodb_replica_set_name }}"
        members:
          "{{ mongodb_replica_members }}"
        state: present
      when: inventory_hostname == "192.168.1.101"

    - name: 创建管理员用户(仅在主节点执行)
      mongodb_user:
        login_host: "{{ inventory_hostname }}"
        replica_set: "{{ mongodb_replica_set_name }}"
        database: admin
        name: "{{ mongodb_admin_user }}"
        password: "{{ mongodb_admin_password }}"
        roles:
          - { role: "root", db: "admin" }
        state: present
      when: inventory_hostname == "192.168.1.101"

Docker 安装

Docker 单实例部署

基本部署

bash
# 拉取 MongoDB 镜像
docker pull mongodb/mongodb-community-server:7.0-ubi8

# 运行 MongoDB 容器
docker run -d \
  --name mongodb \
  -p 27017:27017 \
  -v mongodb_data:/data/db \
  -v mongodb_log:/var/log/mongodb \
  -e MONGODB_INITDB_ROOT_USERNAME=admin \
  -e MONGODB_INITDB_ROOT_PASSWORD=admin123 \
  mongodb/mongodb-community-server:7.0-ubi8

使用自定义配置文件

bash
# 创建配置目录
mkdir -p ~/mongodb/config ~/mongodb/data ~/mongodb/log

# 创建配置文件
cat > ~/mongodb/config/mongod.conf << EOF
storage:
  dbPath: /data/db
  journal:
    enabled: true

systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

net:
  port: 27017
  bindIp: 0.0.0.0

security:
  authorization: enabled
EOF

# 运行 MongoDB 容器,使用自定义配置
docker run -d \
  --name mongodb \
  -p 27017:27017 \
  -v ~/mongodb/config/mongod.conf:/etc/mongod.conf:ro \
  -v ~/mongodb/data:/data/db \
  -v ~/mongodb/log:/var/log/mongodb \
  mongodb/mongodb-community-server:7.0-ubi8 \
  --config /etc/mongod.conf

Docker Compose 复制集部署

yaml
version: '3.8'

services:
  mongodb-primary:
    image: mongodb/mongodb-community-server:7.0-ubi8
    container_name: mongodb-primary
    ports:
      - 27017:27017
    volumes:
      - mongodb_primary_data:/data/db
      - mongodb_primary_log:/var/log/mongodb
      - ./mongod.conf:/etc/mongod.conf:ro
    environment:
      - MONGODB_INITDB_ROOT_USERNAME=admin
      - MONGODB_INITDB_ROOT_PASSWORD=admin123
    command: --config /etc/mongod.conf --replSet rs0
    networks:
      - mongodb_replica_set

  mongodb-secondary1:
    image: mongodb/mongodb-community-server:7.0-ubi8
    container_name: mongodb-secondary1
    ports:
      - 27018:27017
    volumes:
      - mongodb_secondary1_data:/data/db
      - mongodb_secondary1_log:/var/log/mongodb
      - ./mongod.conf:/etc/mongod.conf:ro
    command: --config /etc/mongod.conf --replSet rs0
    networks:
      - mongodb_replica_set
    depends_on:
      - mongodb-primary

  mongodb-secondary2:
    image: mongodb/mongodb-community-server:7.0-ubi8
    container_name: mongodb-secondary2
    ports:
      - 27019:27017
    volumes:
      - mongodb_secondary2_data:/data/db
      - mongodb_secondary2_log:/var/log/mongodb
      - ./mongod.conf:/etc/mongod.conf:ro
    command: --config /etc/mongod.conf --replSet rs0
    networks:
      - mongodb_replica_set
    depends_on:
      - mongodb-primary

volumes:
  mongodb_primary_data:
  mongodb_primary_log:
  mongodb_secondary1_data:
  mongodb_secondary1_log:
  mongodb_secondary2_data:
  mongodb_secondary2_log:

networks:
  mongodb_replica_set:
    driver: bridge

初始化复制集

bash
# 进入主节点容器
docker exec -it mongodb-primary mongosh -u admin -p admin123 --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" }
  ]
})

# 查看复制集状态
rs.status()

Kubernetes 部署

StatefulSet 部署单实例

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: mongodb

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
  namespace: mongodb
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
  namespace: mongodb
spec:
  serviceName: mongodb
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
        - name: mongodb
          image: mongodb/mongodb-community-server:7.0-ubi8
          ports:
            - containerPort: 27017
          env:
            - name: MONGODB_INITDB_ROOT_USERNAME
              value: admin
            - name: MONGODB_INITDB_ROOT_PASSWORD
              value: admin123
          volumeMounts:
            - name: mongodb-data
              mountPath: /data/db
            - name: mongodb-log
              mountPath: /var/log/mongodb
      volumes:
        - name: mongodb-data
          persistentVolumeClaim:
            claimName: mongodb-pvc
        - name: mongodb-log
          emptyDir: {}

---
apiVersion: v1
kind: Service
metadata:
  name: mongodb
  namespace: mongodb
spec:
  selector:
    app: mongodb
  ports:
    - port: 27017
      targetPort: 27017
  type: ClusterIP

Helm 部署 MongoDB

安装 Helm 图表

bash
# 添加 MongoDB Helm 仓库
helm repo add mongodb https://mongodb.github.io/helm-charts
helm repo update

# 安装 MongoDB 复制集
helm install mongodb mongodb/mongodb-replicaset \
  --namespace mongodb \
  --create-namespace \
  --set architecture=replicaset \
  --set replicaSetName=rs0 \
  --set replicaCount=3 \
  --set auth.rootPassword=admin123 \
  --set auth.username=admin \
  --set auth.password=admin123 \
  --set persistence.size=10Gi

# 查看部署状态
kubectl get all -n mongodb

# 连接到 MongoDB
kubectl exec -it mongodb-0 -n mongodb -- mongosh -u admin -p admin123 --authenticationDatabase admin

云服务提供商的托管服务

AWS MongoDB Atlas

bash
# 使用 AWS CLI 创建 MongoDB Atlas 集群
aws atlas clusters create \
  --profile atlas \
  --name my-cluster \
  --num-shards 1 \
  --provider AWS \
  --region us-east-1 \
  --cluster-type REPLICASET \
  --mdb-version "7.0" \
  --instance-size M10 \
  --disk-size-gb 100 \
  --replica-set-num-nodes 3

Azure Cosmos DB for MongoDB

bash
# 使用 Azure CLI 创建 Cosmos DB for MongoDB 账户
az cosmosdb create \
  --name my-cosmosdb \
  --resource-group my-resource-group \
  --kind MongoDB \
  --server-version "4.2" \
  --default-consistency-level Session \
  --enable-automatic-failover true \
  --locations regionName=eastus failoverPriority=0 isZoneRedundant=false \
  --locations regionName=westus failoverPriority=1 isZoneRedundant=false

自动化安装最佳实践

1. 配置管理

  • 使用版本控制系统管理安装脚本和配置文件
  • 采用基础设施即代码(IaC)原则
  • 对配置进行加密,特别是密码和密钥

2. 安全性

  • 启用访问控制和认证
  • 使用 TLS/SSL 加密连接
  • 配置适当的防火墙规则
  • 定期更新 MongoDB 版本和补丁

3. 监控和告警

  • 集成监控系统(如 Prometheus + Grafana)
  • 设置关键指标告警(CPU、内存、磁盘、连接数等)
  • 配置日志收集和分析

4. 扩展性

  • 设计支持水平扩展的架构
  • 考虑分片集群部署方案
  • 预留足够的资源余量

5. 可靠性

  • 采用复制集确保高可用性
  • 配置自动故障转移
  • 定期备份数据
  • 测试恢复流程

6. 文档和自动化测试

  • 详细记录安装流程和配置
  • 编写自动化测试验证安装结果
  • 定期演练安装流程

常见问题(FAQ)

Q1: 如何选择合适的自动化安装方式?

A1: 选择自动化安装方式应考虑:

  • 部署规模:小规模部署可使用脚本或Docker,大规模部署建议使用Ansible或Kubernetes
  • 技术栈:根据现有技术栈选择(如已有Ansible环境则优先使用Ansible)
  • 维护成本:托管服务维护成本最低,自建Kubernetes维护成本最高
  • 定制化需求:需要高度定制化时,脚本或Ansible更灵活
  • 团队技能:选择团队熟悉的技术栈

Q2: 如何确保自动化安装的安全性?

A2: 确保自动化安装安全性的方法:

  • 使用加密的方式存储敏感信息(如密码、密钥)
  • 启用访问控制和认证
  • 配置TLS/SSL加密连接
  • 限制MongoDB监听的IP地址
  • 定期更新MongoDB版本和补丁

Q3: 如何验证自动化安装的结果?

A3: 验证自动化安装结果的方法:

  • 检查MongoDB服务是否正常运行
  • 验证MongoDB版本是否正确
  • 测试连接和认证
  • 检查复制集状态(如适用)
  • 运行基本查询测试
  • 检查日志中是否有错误信息

Q4: 如何处理自动化安装中的错误?

A4: 处理自动化安装错误的方法:

  • 查看详细日志信息
  • 检查配置文件是否正确
  • 验证依赖项是否已安装
  • 检查权限设置
  • 参考官方文档的故障排除指南
  • 在测试环境中重现和调试问题

Q5: 如何升级自动化部署的MongoDB?

A5: 升级自动化部署的MongoDB的方法:

  • 脚本部署:更新脚本中的版本号,重新运行脚本
  • Ansible:更新Playbook中的版本变量,重新执行Playbook
  • Docker:更新镜像标签,重新部署容器
  • Kubernetes:更新镜像标签,重新部署StatefulSet或使用Helm升级
  • 托管服务:使用云提供商的控制台或CLI进行升级

Q6: 如何自动化备份MongoDB?

A6: 自动化备份MongoDB的方法:

  • 使用mongodump命令编写备份脚本
  • 配置cron作业定期执行备份
  • 使用Ansible或其他配置管理工具部署备份脚本
  • 在Docker/Kubernetes中使用sidecar容器执行备份
  • 使用云提供商的备份服务

Q7: 如何在多环境中管理不同的配置?

A7: 在多环境中管理配置的方法:

  • 使用配置文件模板,根据环境变量动态生成配置
  • 在Ansible中使用inventory变量或group_vars/host_vars
  • 在Kubernetes中使用ConfigMaps和Secrets
  • 使用配置管理工具(如Consul、etcd)存储配置

Q8: 如何监控自动化部署的MongoDB实例?

A8: 监控自动化部署的MongoDB实例的方法:

  • 集成Prometheus和Grafana
  • 使用MongoDB Exporter收集指标
  • 配置日志收集(如ELK Stack、Graylog)
  • 设置关键指标告警
  • 使用云提供商的监控服务(如AWS CloudWatch、Azure Monitor)

Q9: 如何实现MongoDB的自动化扩展?

A9: 实现MongoDB自动化扩展的方法:

  • 使用Kubernetes的Horizontal Pod Autoscaler(HPA)
  • 配置分片集群,自动添加分片
  • 使用云提供商的自动扩展功能
  • 编写扩展脚本,根据指标自动调整实例大小

Q10: 如何确保自动化安装的一致性?

A10: 确保自动化安装一致性的方法:

  • 使用版本控制系统管理所有配置和脚本
  • 采用基础设施即代码(IaC)原则
  • 在所有环境中使用相同的安装流程
  • 实施配置漂移检测
  • 定期验证环境配置一致性