返回

在本地设置 MongoDB 7 三节点副本集:使用密码、用户名和安全密钥文件

Linux

使用密码、用户名和安全密钥文件在本地设置 MongoDB 7 三节点副本集

简介

MongoDB 是一个高性能、可扩展的开源数据库,在需要安全性、冗余性和可用性的应用程序中广泛使用。为了增强 MongoDB 部署的这些特性,建议配置副本集。本教程将逐步指导您如何在本地使用密码、用户名和安全密钥文件设置一个三节点 MongoDB 7 副本集。

先决条件

您需要满足以下先决条件才能继续:

  • Docker 已安装并正在运行
  • Portainer 已安装并运行在您的 localhost 上
  • MongoDB 客户端(例如 MongoDB Compass 或 Robo3T)

设置

1. 创建 Docker Compose 文件

创建一个名为 docker-compose.yml 的文件,其中包含以下内容:

version: '3.8'

services:
  mongo1:
    image: mongo:7
    volumes:
      - /home/user/ducker/mongo-three-replica/rep1/data:/data/db
      - /home/user/ducker/mongo/rep.key:/opt/keyfile/mongo-keyfile
    environment:
      MONGO_INITDB_ROOT_USERNAME: your_username
      MONGO_INITDB_ROOT_PASSWORD: your_password
    command: "--replSet rs0 --keyFile /opt/keyfile/mongo-keyfile"
    ports:
      - "27017:27017"
    networks:
      - mongo-cluster

  mongo2:
    image: mongo:7
    volumes:
      - /home/user/ducker/mongo-three-replica/rep2/data:/data/db
      - /home/user/ducker/mongo/rep.key:/opt/keyfile/mongo-keyfile
    environment:
      MONGO_INITDB_ROOT_USERNAME: your_username
      MONGO_INITDB_ROOT_PASSWORD: your_password
    command: "--replSet rs0 --keyFile /opt/keyfile/mongo-keyfile"
    ports:
      - "27018:27017"
    networks:
      - mongo-cluster

  mongo3:
    image: mongo:7
    volumes:
      - /home/user/ducker/mongo-three-replica/rep3/data:/data/db
      - /home/user/ducker/mongo/rep.key:/opt/keyfile/mongo-keyfile
    environment:
      MONGO_INITDB_ROOT_USERNAME: your_username
      MONGO_INITDB_ROOT_PASSWORD: your_password
    command: "--replSet rs0 --keyFile /opt/keyfile/mongo-keyfile"
    ports:
      - "27019:27017"
    networks:
      - mongo-cluster

  rs-init:
    image: mongo:7
    depends_on:
      - mongo1
      - mongo2
      - mongo3
    networks:
      - mongo-cluster
    command: >
      bash -c "until mongosh --host mongo1:27017 --username your_username --password your_password --eval 'print(\"waiting for mongo1\")'; do sleep 2; done &&
             until mongosh --host mongo2:27017 --username your_username --password your_password --eval 'print(\"waiting for mongo2\")'; do sleep 2; done &&
             until mongosh --host mongo3:27017 --username your_username --password your_password --eval 'print(\"waiting for mongo3\")'; do sleep 2; done &&
             mongosh --host mongo1:27017 --username your_username --password your_password --eval '
             rs.initiate({
               _id: \"rs0\",
               members: [
                 { _id: 0, host: \"mongo1:27017\" },
                 { _id: 1, host: \"mongo2:27017\" },
                 { _id: 2, host: \"mongo3:27017\" }
               ]
             })'"
    restart: "no"

networks:
  mongo-cluster:
    driver: bridge

2. 生成安全密钥文件

使用以下命令生成一个安全密钥文件:

openssl rand -base64 64 > /home/user/ducker/mongo/rep.key

3. 启动 MongoDB 副本集

  • 将 Docker Compose 文件保存在您的项目目录中。
  • 导航到项目目录并运行以下命令:
docker-compose up -d

这将启动 MongoDB 副本集和初始化脚本。

验证副本集

1. 连接到 MongoDB 客户端

使用以下连接字符串连接到 MongoDB Compass 或 Robo3T:

mongodb://your_username:your_password@localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0

2. 检查副本集状态

在 MongoDB 客户端中运行以下命令以查看副本集状态:

rs.status()

输出应该类似于:

{
  set: 'rs0',
  date: <Date object>,
  myState: 1,
  term: Long('1'),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long('2000'),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {
    lastCommittedOpTime: { ts: <Timestamp object>, t: Long('1') },
    lastCommittedWallTime: <Date object>,
    readConcernMajorityOpTime: { ts: <Timestamp object>, t: Long('1') },
    appliedOpTime: { ts: <Timestamp object>, t: Long('1') },
    durableOpTime: { ts: <Timestamp object>, t: Long('1') },
    lastAppliedWallTime: <Date object>,
    lastDurableWallTime: <Date object>
  },
  lastStableRecoveryTimestamp: <Timestamp object>,
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: <Date object>,
    electionTerm: Long('1'),
    lastCommittedOpTimeAtElection: { ts: <Timestamp object>, t: Long('-1') },
    lastSeenOpTimeAtElection: { ts: <Timestamp object>, t: Long('-1') },
    numVotesNeeded: 2,
    priorityAtElection: 1,
    electionTimeoutMillis: Long('10000'),
    numCatchUpOps: Long('0'),
    newTermStartDate: <Date object>,
    wMajorityWriteAvailabilityDate: <Date object>
  },
  members: [
    {
      _id: 0,
      name: 'mongo1:27017',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: <Seconds>,
      optime: [Object],
      optimeDate: <Date object>,
      lastAppliedWallTime: <Date object>,
      lastDurableWallTime: <Date object>,
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: <Timestamp object>,
      electionDate: <Date object>,
      configVersion: 1,
      configTerm: 1,
      self: true,
      lastHeartbeatMessage: ''
    },
    {
      _id: 1,
      name: 'mongo2:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: <Seconds>,
      optime: [Object],
      optimeDurable: [Object],
      optimeDate: <Date object>,
      optimeDurableDate: <Date object>,
      lastAppliedWallTime: <Date object>,
      lastDurableWallTime: <Date object>,
      lastHeartbeat: <Date object>,
      lastHeartbeatRecv: <Date object>,
      pingMs: Long('0'),
      lastHeartbeatMessage: '',
      syncSourceHost: 'mongo1:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    },
    {
      _id: 2,
      name: 'mongo3:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: <Seconds>,
      optime: [Object],
      optimeDurable: [Object],
      optimeDate: <Date object>,
      optimeDurableDate: <Date object>,