openssl
生成复杂的随机的1024个字符串。然后使用chmod修改文件权限,只给文件拥有者提供读权限。# 400权限是要保证安全性,否则mongod启动会报错
openssl rand -base64 756 > mongodb.key
chmod 400 mongodb.key
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: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
networks:
- mongoNet
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 $$@
mongodb2:
image: mongo
restart: always
container_name: mongo2
volumes:
- ./data/db/mongo2:/data/db
- ./mongodb.key:/data/mongodb.key
ports:
- 27018:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
networks:
- mongoNet
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 $$@
mongodb3:
image: mongo
restart: always
container_name: mongo3
volumes:
- ./data/db/mongo3:/data/db
- ./mongodb.key:/data/mongodb.key
ports:
- 27019:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
networks:
- mongoNet
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 $$@
networks:
mongoNet:
driver: bridge
.env
文件,主要作用是初始化数据库账密
MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=admin
mongodb.key
文件,用于副本集之间授权验证
6iB3VOV1eUQKodAhMyqdQQxdVvvaL5dBr7k/TIYf0csRGpLX0NyvL3f3M3G6kuI0
yRXiLlPJBzZ0GqmLNeo8jZ0rso/938qK5rU7pv9GmyEMGbAs75edl3OpfQCxjKUX
iq/+qgYN4R+Slw9klfMOaiFepAdeKHpCY66AqoM9YsjEW04evF9K0SlRzez3rfdA
HOqoovkOqWjhi6wDNan2JjYCb1jgjx6wDnwrq/GOoFIoqUIUMF9xdFXavlRO+jVc
sAow0U2+svvSbSiokCR023CqL618N5jYiq8/v4ztkHjFQ797TTJR6O69VHQ9hyMp
jUzjyA2+NXdXUbnMMoVfVRq104G4ux75nwsjnIAW2lpUKNPGbEQtYpWiCn0Ey2J9
3Zo2MF/SKgY4rj5FHdztP0d30SvFWsoCThwgEs3z1SwR2KJEDTu+UOQy3icEAPoJ
F0ya0C4J398a2gqVnDh+HxT/lhI3OVp1T846LlhRPnLpLbUvUR3kpGvXerGVryyZ
mzxG0cxEHM/Ede26iqWGXRQA7BgYhDx/1SFYWhqrvt3gNI9WR0jDe2B4m4r0TrPK
qyjbgXrb4E3P8HigDbgvm54DBnbkkbCd3+sONuNOpwpg2RPiVK5fVkJPxoNR+dzi
CCsixN6CvY5yRBquow10eCCLHRgYcJ8axyB1e772uHQFlyo4tJTm3kXsPaHg1KVA
rP/v1H4FW8RjQDVUHs1n5V3RAZwVEC6cprKqo6t2ygwiMMgRHVuYiMJRaN+yd1ap
QFnfQnw+iGgaKcl6Cgr3sFYEeO3FOTwLBPs24lk/pimIJn7rzyQ8T+/APMJBsMog
2oLZ/rTzbFbfOxccrfZQpc2/ozvnjvLSUPnePEDE3bfHREmOAJwPBMI7BQQgNZS9
y1NHWGR3v0qkmcnu3O0nmutxdS/TraOLpQYImLPQ++8axQKVjcRkoKCTPcWdjwDw
+mR0XL/H/UR9obDcTZLb1MCKD+tBw2UC07WP6LzmcNREk40/
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
配置文件中设置了数据库账密,不输入账密会无法进行设置,查看副本集配置时会提示无权限。biao@centos:~$ docker exec -it mongo1 /bin/bash
root@00aee3c527c3:/# mongo
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("6f8c9ba7-ef16-4caf-8582-a3d1f19c341e") }
MongoDB server version: 4.0.10
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> rs.status()
{
"ok" : 0,
"errmsg" : "command replSetGetStatus requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
root@00aee3c527c3:/# mongo -u root -p admin
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("02d0d226-f23e-41c2-af9f-c34610d93797") }
MongoDB server version: 4.0.10
Server has startup warnings:
2019-07-14T05:58:43.055+0000 I STORAGE [initandlisten]
2019-07-14T05:58:43.055+0000 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2019-07-14T05:58:43.055+0000 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
rs.status()
会提示没有配置副本集> rs.status()
{
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94,
"codeName" : "NotYetInitialized"
}
>
_id
的值是 docker-compose
配置文件启动命令设置的 --replSet mongos
副本集名称,这是最基础的配置, rs.initiate()
触发选举,并选举出一个成员作为primary
。rs.initiate({
_id: "mongos",
members: [
{ _id : 0, host : "192.168.1.111:27017" },
{ _id : 1, host : "192.168.1.111:27018" },
{ _id : 2, host : "192.168.1.111:27019" }
]
});
{ "ok" : 1 }
就代表已经成功了,等待一会儿就会选举出PRIMARY
节点,可以用rs.status()
查看当前副本集状态。> rs.initiate({
... _id: "mongos",
... members: [
... { _id : 0, host : "192.168.1.111:27017" },
... { _id : 1, host : "192.168.1.111:27018" },
... { _id : 2, host : "192.168.1.111:27019" }
... ]
... });
{ "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.1.111: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.1.111:27018",
"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.1.111:27017",
"syncSourceHost" : "192.168.1.111:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.1.111:27019",
"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.1.111:27017",
"syncSourceHost" : "192.168.1.111: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>
biao@centos:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00aee3c527c3 mongo "bash -c 'chmod 400 …" 2 hours ago Up 2 hours 0.0.0.0:27017->27017/tcp mongo1
a0adb341e83c mongo "bash -c 'chmod 400 …" 2 hours ago Up 2 hours 0.0.0.0:27019->27017/tcp mongo3
76f1792ae9ed mongo "bash -c 'chmod 400 …" 2 hours ago Up 2 hours 0.0.0.0:27018->27017/tcp mongo2
biao@centos:~$ docker stop mongo11
mongo11
biao@centos:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0adb341e83c mongo "bash -c 'chmod 400 …" 2 hours ago Up 2 hours 0.0.0.0:27019->27017/tcp mongo3
76f1792ae9ed mongo "bash -c 'chmod 400 …" 2 hours ago Up 2 hours 0.0.0.0:27018->27017/tcp mongo2
biao@centos:~$ docker exec -it mongo2 /bin/bash
root@76f1792ae9ed:/# mongo -u root -p admin
mongos:PRIMARY>
mongos:PRIMARY> rs.status()
{
"set" : "mongos",
# ...省略
"members" : [
{
"_id" : 0,
"name" : "192.168.1.111:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2019-07-14T08:01:48.362Z"),
"lastHeartbeatRecv" : ISODate("2019-07-14T08:00:58.421Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Error connecting to 192.168.1.111:27017 :: caused by :: Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "192.168.1.111:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 7386,
"optime" : {
"ts" : Timestamp(1563091300, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-07-14T08:01:40Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1563091258, 1),
"electionDate" : ISODate("2019-07-14T08:00:58Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "192.168.1.111:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 7227,
"optime" : {
"ts" : Timestamp(1563091300, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1563091300, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-07-14T08:01:40Z"),
"optimeDurableDate" : ISODate("2019-07-14T08:01:40Z"),
"lastHeartbeat" : ISODate("2019-07-14T08:01:48.353Z"),
"lastHeartbeatRecv" : ISODate("2019-07-14T08:01:49.067Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.111:27018",
"syncSourceHost" : "192.168.1.111:27018",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1563091300, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1563091300, 1),
"signature" : {
"hash" : BinData(0,"X0eYxSxcFjZZpMEEkunHgtnhJVg="),
"keyId" : NumberLong("6713395051742887937")
}
}
}
mongo1
的状态是not reachable/healthy
,现在将已经停掉的容器重新启动,可以看到状态改变,重新加回副本集列表mongodb.key
和.env
文件一起复制过去,端口根据实际情况修改映射docker-compsoe.yaml
文件version: '3.1'
services:
mongodb1:
image: mongo
restart: always
container_name: mongo4
volumes:
- ./data/db/mongo4:/data/db
- ./mongodb.key:/data/mongodb.key
ports:
- 27020:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
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 $$@
Primary
节点数据库中,进入shell添加新创建的容器,服务器IP和端口mongos:PRIMARY> rs.add("192.168.1.111:27020")
{
"ok" : 1,
"operationTime" : Timestamp(1563095185, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1563095185, 1),
"signature" : {
"hash" : BinData(0,"jMFzkKdSymJWZIBXPq+C094jk8w="),
"keyId" : NumberLong("6713395051742887937")
}
}
}
mongos:PRIMARY> rs.status()
{
"set" : "mongos",
# ...省略
"members" : [
{
"_id" : 0,
"name" : "192.168.1.111:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 4150,
"optime" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-07-14T09:11:36Z"),
"optimeDurableDate" : ISODate("2019-07-14T09:11:36Z"),
"lastHeartbeat" : ISODate("2019-07-14T09:11:41.876Z"),
"lastHeartbeatRecv" : ISODate("2019-07-14T09:11:41.881Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.111:27018",
"syncSourceHost" : "192.168.1.111:27018",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 2
},
{
"_id" : 1,
"name" : "192.168.1.111:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 11580,
"optime" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-07-14T09:11:36Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1563091258, 1),
"electionDate" : ISODate("2019-07-14T08:00:58Z"),
"configVersion" : 2,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "192.168.1.111:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11421,
"optime" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-07-14T09:11:36Z"),
"optimeDurableDate" : ISODate("2019-07-14T09:11:36Z"),
"lastHeartbeat" : ISODate("2019-07-14T09:11:41.890Z"),
"lastHeartbeatRecv" : ISODate("2019-07-14T09:11:41.967Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.111:27018",
"syncSourceHost" : "192.168.1.111:27018",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 2
},
{
"_id" : 3,
"name" : "192.168.1.111:27020",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 317,
"optime" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1563095496, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-07-14T09:11:36Z"),
"optimeDurableDate" : ISODate("2019-07-14T09:11:36Z"),
"lastHeartbeat" : ISODate("2019-07-14T09:11:41.886Z"),
"lastHeartbeatRecv" : ISODate("2019-07-14T09:11:41.505Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.111:27018",
"syncSourceHost" : "192.168.1.111:27018",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 2
}
],
"ok" : 1,
"operationTime" : Timestamp(1563095496, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1563095496, 1),
"signature" : {
"hash" : BinData(0,"00FWYUxtXfPcvL/wKox4JZ7y7tI="),
"keyId" : NumberLong("6713395051742887937")
}
}
}
mongos:PRIMARY>
切换Primary节点为其他节点,参考文章mongodb4.0 replica set(副本集) 切换主节点 配置主从