docker-compose 部署MongoDB4.0 部署replica set(副本集)集群 多服务器

本文详细介绍了如何在三台服务器上使用Docker和docker-compose搭建MongoDB副本集,包括keyFile的生成、docker-compose配置以及副本集的初始化和故障转移。通过设置副本集,实现了数据的高可用性和容灾能力。
摘要由CSDN通过智能技术生成

docker以及docker-compose安装请点击

 

准备三台服务器 192.168.0.11  192.168.0.12  192.168.0.13

 

生成keyFile

MongoDB使用keyfile认证,副本集中的每个mongod实例使用keyfile内容作为认证其他成员的共享密码。mongod实例只有拥有正确的keyfile才可以加入副本集。
keyFile的内容必须是6到1024个字符的长度,且副本集所有成员的keyFile内容必须相同。
有一点要注意是的:在UNIX系统中,keyFile必须没有组权限或完全权限(也就是权限要设置成X00的形式)。Windows系统中,keyFile权限没有被检查。
可以使用任意方法生成keyFile。例如,如下操作使用openssl生成复杂的随机的1024个字符串。然后使用chmod修改文件权限,只给文件拥有者提供读权限。
这是MongoDB官方推荐keyFile的生成方式:
 

# 400权限是要保证安全性,否则mongod启动会报错
openssl rand -base64 756 > mongodb.key
chmod 400 mongodb.key

 

生成完之后需要在三台机器上面配置keyFile文件  副本集全靠这个来实现

在三台服务器都复制一份mongodb.key ,创建docker-compose.yml

主192.168.0.11 docker-compose.yml

version: '3.1'

services:
  mongodb1:
    image: mongo
    restart: always
    container_name: mongo1
    volumes:
      - ./data/db/mongo1:/data/db
      - ./mongodb.key:/data/mongodb.key
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: zeqingev
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@

从192.168.0.12 docker-compose.yml

version: '3.1'

services:
  mongodb2:
    image: mongo
    restart: always
    container_name: mongo2
    volumes:
      - ./data/db/mongo2:/data/db
      - ./mongodb.key:/data/mongodb.key
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: zeqingev
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@

 

从192.168.0.13 docker-compose.yml

version: '3.1'

services:
  mongodb13:
    image: mongo
    restart: always
    container_name: mongo3
    volumes:
      - ./data/db/mongo3:/data/db
      - ./mongodb.key:/data/mongodb.key
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: zeqingev
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@

文件详解
chown 999:999 /data/mongodb.key 999用户是容器中的mongod用户,通过chown修改文件用户权限
mongod --replSet mongos --keyFile /data/mongodb.key 启动命令,--replSet mongos 以副本集形式启动并将副本集名字命名为 mongos ,--keyFile /data/mongodb.key 设置keyFile,用于副本集通信,文件通过 volumes 映射到容器内
networks 创建容器在同一局域网下,容器之间通信
 

配置副本集
切换到docker-compose.yml所在目录,执行命令docker-compose up -d启动数据库,-d 表示后台启动并运行所有的容器。
通过命令 docker exec -it mongo1 /bin/bash 进入容器进行配置


进入容器之后,通过mongo命令行进入数据库,因为在docker-compose 配置文件中设置了数据库账密,不输入账密会无法进行设置,查看副本集配置时会提示无权限。

  • 此时输入 rs.status() 会提示没有配置副本集
  • > rs.status()
    {
    	"ok" : 0,
    	"errmsg" : "no replset config has been received",
    	"code" : 94,
    	"codeName" : "NotYetInitialized"
    }
    > 
    

    复制以下内容初始化副本集配置,其中ip是服务器的公网IP,如果设置了容器IP,数据库之间能进行通信,但是通过连接无法正确连接副本集,_id 的值是 docker-compose 配置文件启动命令设置的 --replSet mongos 副本集名称,这是最基础的配置, rs.initiate() 触发选举,并选举出一个成员作为primary。
     

    rs.initiate({
        _id: "mongos",
        members: [
            { _id : 0, host : "192.168.0.11:27017" },
            { _id : 1, host : "192.168.0.12:27017" },
            { _id : 2, host : "192.168.0.13:27017" }
        ]
    });
    

     

  • 执行初始化配置命令,显示{ "ok" : 1 }就代表已经成功了,等待一会儿就会选举出PRIMARY节点,可以用rs.status()查看当前副本集状态。
  • > rs.initiate({
    ...     _id: "mongos",
    ...     members: [
    ...         { _id : 0, host : "192.168.0.11:27017" },
    ...         { _id : 1, host : "192.168.0.12:27017" },
    ...         { _id : 2, host : "192.168.0.13:27017" }
    ...     ]
    ... });
    { "ok" : 1 }
    mongos:SECONDARY> 
    mongos:PRIMARY> 
    mongos:PRIMARY> rs.status()
    {
    	"set" : "mongos",
    	"date" : ISODate("2019-07-14T06:01:48.574Z"),
    	"myState" : 1,
    	"term" : NumberLong(1),
    	"syncingTo" : "",
    	"syncSourceHost" : "",
    	"syncSourceId" : -1,
    	"heartbeatIntervalMillis" : NumberLong(2000),
    	"optimes" : {
    		"lastCommittedOpTime" : {
    			"ts" : Timestamp(1563084092, 1),
    			"t" : NumberLong(1)
    		},
    		"readConcernMajorityOpTime" : {
    			"ts" : Timestamp(1563084092, 1),
    			"t" : NumberLong(1)
    		},
    		"appliedOpTime" : {
    			"ts" : Timestamp(1563084092, 1),
    			"t" : NumberLong(1)
    		},
    		"durableOpTime" : {
    			"ts" : Timestamp(1563084092, 1),
    			"t" : NumberLong(1)
    		}
    	},
    	"lastStableCheckpointTimestamp" : Timestamp(1563084091, 1),
    	"members" : [
    		{
    			"_id" : 0,
    			"name" : "192.168.0.11:27017",
    			"health" : 1,
    			"state" : 1,
    			"stateStr" : "PRIMARY",
    			"uptime" : 185,
    			"optime" : {
    				"ts" : Timestamp(1563084092, 1),
    				"t" : NumberLong(1)
    			},
    			"optimeDate" : ISODate("2019-07-14T06:01:32Z"),
    			"syncingTo" : "",
    			"syncSourceHost" : "",
    			"syncSourceId" : -1,
    			"infoMessage" : "could not find member to sync from",
    			"electionTime" : Timestamp(1563084090, 1),
    			"electionDate" : ISODate("2019-07-14T06:01:30Z"),
    			"configVersion" : 1,
    			"self" : true,
    			"lastHeartbeatMessage" : ""
    		},
    		{
    			"_id" : 1,
    			"name" : "192.168.0.12:27017",
    			"health" : 1,
    			"state" : 2,
    			"stateStr" : "SECONDARY",
    			"uptime" : 28,
    			"optime" : {
    				"ts" : Timestamp(1563084092, 1),
    				"t" : NumberLong(1)
    			},
    			"optimeDurable" : {
    				"ts" : Timestamp(1563084092, 1),
    				"t" : NumberLong(1)
    			},
    			"optimeDate" : ISODate("2019-07-14T06:01:32Z"),
    			"optimeDurableDate" : ISODate("2019-07-14T06:01:32Z"),
    			"lastHeartbeat" : ISODate("2019-07-14T06:01:48.252Z"),
    			"lastHeartbeatRecv" : ISODate("2019-07-14T06:01:48.519Z"),
    			"pingMs" : NumberLong(0),
    			"lastHeartbeatMessage" : "",
    			"syncingTo" : "192.168.0.11:27017",
    			"syncSourceHost" : "192.168.0.11:27017",
    			"syncSourceId" : 0,
    			"infoMessage" : "",
    			"configVersion" : 1
    		},
    		{
    			"_id" : 2,
    			"name" : "192.168.0.13:27017",
    			"health" : 1,
    			"state" : 2,
    			"stateStr" : "SECONDARY",
    			"uptime" : 28,
    			"optime" : {
    				"ts" : Timestamp(1563084092, 1),
    				"t" : NumberLong(1)
    			},
    			"optimeDurable" : {
    				"ts" : Timestamp(1563084092, 1),
    				"t" : NumberLong(1)
    			},
    			"optimeDate" : ISODate("2019-07-14T06:01:32Z"),
    			"optimeDurableDate" : ISODate("2019-07-14T06:01:32Z"),
    			"lastHeartbeat" : ISODate("2019-07-14T06:01:48.252Z"),
    			"lastHeartbeatRecv" : ISODate("2019-07-14T06:01:48.512Z"),
    			"pingMs" : NumberLong(0),
    			"lastHeartbeatMessage" : "",
    			"syncingTo" : "192.168.0.11:27017",
    			"syncSourceHost" : "192.168.0.11:27017",
    			"syncSourceId" : 0,
    			"infoMessage" : "",
    			"configVersion" : 1
    		}
    	],
    	"ok" : 1,
    	"operationTime" : Timestamp(1563084092, 1),
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1563084092, 1),
    		"signature" : {
    			"hash" : BinData(0,"5XoSC0ilUaKemlTAx+Cx/xkoKc8="),
    			"keyId" : NumberLong("6713395051742887937")
    		}
    	}
    }
    mongos:PRIMARY> 
    

    故障转移

  • 在副本集模式下,如果Primary节点宕机不可用,集群会选举出新的Primary节点  所以手动停止主节点的mongo1  等待30s 再重新启动主mongo1  再去查看当前的节点状态 rs.status()
  • {
    	"set" : "mongos",
    	"date" : ISODate("2021-04-08T04:15:24.485Z"),
    	"myState" : 2,
    	"term" : NumberLong(6),
    	"syncSourceHost" : "192.168.0.12:27017",
    	"syncSourceId" : 2,
    	"heartbeatIntervalMillis" : NumberLong(2000),
    	"majorityVoteCount" : 2,
    	"writeMajorityCount" : 2,
    	"votingMembersCount" : 3,
    	"writableVotingMembersCount" : 3,
    	"optimes" : {
    		"lastCommittedOpTime" : {
    			"ts" : Timestamp(1617855317, 1),
    			"t" : NumberLong(6)
    		},
    		"lastCommittedWallTime" : ISODate("2021-04-08T04:15:17.584Z"),
    		"readConcernMajorityOpTime" : {
    			"ts" : Timestamp(1617855317, 1),
    			"t" : NumberLong(6)
    		},
    		"readConcernMajorityWallTime" : ISODate("2021-04-08T04:15:17.584Z"),
    		"appliedOpTime" : {
    			"ts" : Timestamp(1617855317, 1),
    			"t" : NumberLong(6)
    		},
    		"durableOpTime" : {
    			"ts" : Timestamp(1617855317, 1),
    			"t" : NumberLong(6)
    		},
    		"lastAppliedWallTime" : ISODate("2021-04-08T04:15:17.584Z"),
    		"lastDurableWallTime" : ISODate("2021-04-08T04:15:17.584Z")
    	},
    	"lastStableRecoveryTimestamp" : Timestamp(1617855317, 1),
    	"electionParticipantMetrics" : {
    		"votedForCandidate" : true,
    		"electionTerm" : NumberLong(6),
    		"lastVoteDate" : ISODate("2021-04-08T03:58:37.425Z"),
    		"electionCandidateMemberId" : 1,
    		"voteReason" : "",
    		"lastAppliedOpTimeAtElection" : {
    			"ts" : Timestamp(1617854283, 1),
    			"t" : NumberLong(4)
    		},
    		"maxAppliedOpTimeInSet" : {
    			"ts" : Timestamp(1617854283, 1),
    			"t" : NumberLong(4)
    		},
    		"priorityAtElection" : 1,
    		"newTermStartDate" : ISODate("2021-04-08T03:58:37.562Z"),
    		"newTermAppliedDate" : ISODate("2021-04-08T03:58:38.553Z")
    	},
    	"members" : [
    		{
    			"_id" : 0,
    			"name" : "192.168.0.11:27017",
    			"health" : 1,
    			"state" : 2,
    			"stateStr" : "SECONDARY",
    			"uptime" : 1026,
    			"optime" : {
    				"ts" : Timestamp(1617855317, 1),
    				"t" : NumberLong(6)
    			},
    			"optimeDate" : ISODate("2021-04-08T04:15:17Z"),
    			"syncSourceHost" : "192.168.0.12:27017",
    			"syncSourceId" : 2,
    			"infoMessage" : "",
    			"configVersion" : 1,
    			"configTerm" : 6,
    			"self" : true,
    			"lastHeartbeatMessage" : ""
    		},
    		{
    			"_id" : 1,
    			"name" : "192.168.0.13:27017",
    			"health" : 1,
    			"state" : 1,
    			"stateStr" : "PRIMARY",
    			"uptime" : 1021,
    			"optime" : {
    				"ts" : Timestamp(1617855317, 1),
    				"t" : NumberLong(6)
    			},
    			"optimeDurable" : {
    				"ts" : Timestamp(1617855317, 1),
    				"t" : NumberLong(6)
    			},
    			"optimeDate" : ISODate("2021-04-08T04:15:17Z"),
    			"optimeDurableDate" : ISODate("2021-04-08T04:15:17Z"),
    			"lastHeartbeat" : ISODate("2021-04-08T04:15:24.337Z"),
    			"lastHeartbeatRecv" : ISODate("2021-04-08T04:15:22.572Z"),
    			"pingMs" : NumberLong(2),
    			"lastHeartbeatMessage" : "",
    			"syncSourceHost" : "",
    			"syncSourceId" : -1,
    			"infoMessage" : "",
    			"electionTime" : Timestamp(1617854317, 1),
    			"electionDate" : ISODate("2021-04-08T03:58:37Z"),
    			"configVersion" : 1,
    			"configTerm" : 6
    		},
    		{
    			"_id" : 2,
    			"name" : "192.168.0.12:27017",
    			"health" : 1,
    			"state" : 2,
    			"stateStr" : "SECONDARY",
    			"uptime" : 1016,
    			"optime" : {
    				"ts" : Timestamp(1617855317, 1),
    				"t" : NumberLong(6)
    			},
    			"optimeDurable" : {
    				"ts" : Timestamp(1617855317, 1),
    				"t" : NumberLong(6)
    			},
    			"optimeDate" : ISODate("2021-04-08T04:15:17Z"),
    			"optimeDurableDate" : ISODate("2021-04-08T04:15:17Z"),
    			"lastHeartbeat" : ISODate("2021-04-08T04:15:23.991Z"),
    			"lastHeartbeatRecv" : ISODate("2021-04-08T04:15:23.799Z"),
    			"pingMs" : NumberLong(2),
    			"lastHeartbeatMessage" : "",
    			"syncSourceHost" : "192.168.0.13:27017",
    			"syncSourceId" : 1,
    			"infoMessage" : "",
    			"configVersion" : 1,
    			"configTerm" : 6
    		}
    	],
    	"ok" : 1,
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1617855317, 1),
    		"signature" : {
    			"hash" : BinData(0,"8fZvmnfsJBWwRNvcKCNCK3zjvAw="),
    			"keyId" : NumberLong("6948597425195974659")
    		}
    	},
    	"operationTime" : Timestamp(1617855317, 1)
    }
    

     

  • 可以看到mongo1的状态是重新加回副本集列表,现在是192.168.0.12这台服务器的节点变为主节点  其他两台成了副本了 

这个是多服务器添加mongo副本集的方法  要是在一台服务器上面请参考博主

ps:感谢这位博主的借鉴  下面一篇讲解一下springboot配置mongodb副本集

所有的内部ip连接我使用的是内网  你要保证所有的内网相互都能访问到 (可以使用命令ping ip)如果是外网ip的话  记得开放一下所需要的端口

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值