尽管依然是一片陌生的蓝海,老鸟还是花了几天时间实践研究了一下Mongodb replica set。 一切依然从官网文档出发,踩过官网文档中的坑,最后成功搭建了一个Primary, Secondary 和arbiter 三元Replica Set集群,主要目的是为了提供高可靠的数据服务。
首先介绍一下应用场景,根据实际情况,将跟官网文档一些具体的步骤区分开来,当然有心人依然可以从官网中找到本文中论述的一些步骤的一些线索。首先老鸟公司在产品环境中已经使用单实例Mongodb数据库,并伴有一定量的数据,且做了必要的权限控制(Role-Based Access Control)。然后老鸟需要把单实例Mongodb转成Mongodb Replica Set 三元集群。 如果你遇到和我一样的目前数据库有数据并且做了必要的权限控制,然后想转成Mongodb Replica Set,那么本文的有些信息兴许可以帮到你。如果没有,请乖乖遵循官方文档步骤进行。
本次实践大体步骤如下:准备Security Key File > 删除原有单例Mongodb所有用户 > 配置Mongodb Replica Member > 启动Replica Set > 创建用户权限
一、系统环境以及必要依赖软件
- 操作系统: Ubuntu 16 LTS +
- 数据库: Mongodb Enterprise
- 服务器:阿里云或腾讯云共计3台
二、准备Security Key File
Security Key File 是一个密文文件用于Mongodb Replica Set集群内部各节点做授权认证用和权限控制(Role-Based Access Control)配合使用来做Mongodb Replica Set 集群权限配置控制。如果你需要在集群中做权限控制,这个是必须的,当然Security Key File有很多种,具体看官方文档(docs.mongodb.com/manual/tuto…),这里只使用最简单的一种。
- 生成Security Key File原始密本
openssl rand-base64 756 > <path-to-keyfile>
- 将文件通过某种途径(ssh, Filezilla 等)拷贝到所有目标服务器目录中
在这里我将密本文件拷到各服务器中的/var/lib/mongodb-keyfile目录中。因为默认mongodb文件默认在/var/lib/mongodb目录中,这样安排统一清除,也是借鉴了mysql的目录安排。
- 赋予Security Key File必要权限
Mongodb数据某人是以mongodb用户和用户组下运行的。而我们拷贝Security Key File使用的用户通常是管理员而非mongodb用户。所以这里需要修改Security Key File的用户和用户组
- 修改用户和用户组
sudo chown –R mongodb /var/lib/mongodb-keyfile
sudo chgrp –R mongodb /var/lib/mongodb-keyfile
- 赋予Security Key File 读写执行权限
官网文档中有这么一段话“uses chmod to change file permissions to provide read permissions for the file owner only”。然后官网给出的权限设置是“chmod 400 <path-to-keyfile>”
但通过实践发现400的只读权限可能会报错,通过日志显示mongodb启动时操作Security Key File无权限。所以改为chmod 700 <path-to-keyfile parent folder>.
另外不要给组和其他人赋予任何权限,不然会报permission too open错误。请用ll命令查看Security Key File文件的权限是如下模式drwx------
三、删除原有单例Mongodb所有用户
删除原旧Mongodb所有用户是目前我找到一个可行的方案,因为Mongodb Replica Set初始化的时候需要保证没有用户,不然会报无权限错误。根据官方文档,没有用户被Mongodb认为是某种特殊状态,当添加第一用户后,那么Mongodb的状态会变迁。具体阐述如下:
“Connect to a member of the replica set over the localhost interface.
Connect a mongo shell to one of the mongod instances over the localhost interface. You must run the mongo shell on the same physical machine as the mongod instance.
The localhost interface is only available since no users have been created for the deployment. The localhost interface closes after the creation of the first user.”
- 取消旧mongodb安全认证模式并重启
#security:
# authorization:enabled
- 删除所有已有用户
使用dropAllUsers删除admin库中所有用户:docs.mongodb.com/manual/refe…
四、配置Mongodb Replica Member
- 除了旧服务器,所有的其他服务器上安装mongodb-enterprise
- 修改每台服务器上mongodb配置文件,通常在/etc/mongod.conf
Net:
bindIP: 0.0.0.0
security:
keyFile: /var/lib/mongodb-keyfile/securityKeyFile
replication:
replSetName: xxx
- 启动每台服务上的mongodb
sudo service mongod start
五、启动Replica Set
只需要在一台服务上的mongo shell中执行一次rs.initiate即可,不用再每台服务上都执行。
rs.initiate( {
_id : "xxx",
members: [
{ _id: 0, host:
"第一台服务器公网IP:27017", priority:3 }, // priority 设高保证该实例初始化一定被选为primary
{ _id: 1, host:
"第二台服务器公网IP:27017" },
{ _id: 2, host:
"第三台服务器公网IP:27017", arbiterOnly:true}
]
})
六、创建用户权限
通常需要创建三个必要用户及其权限:超级管理员,集群管理员和应用用户。 超级管理员用于用户权限创建管理。集群管理员用于集群配置管理。应用用户用于数据操作。
- 超级管理员:
admin = db.getSiblingDB("admin")admin.createUser( { user: "fred", pwd: "changeme1", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] })
- 集群管理员:
admin = db.getSiblingDB("admin")
admin.auth("超级管理员账号","密码")admin.createUser( { user: "fred", pwd: "changeme1", roles: [ { role: "clusterAdmin", db: "admin" } ] })
- 应用用户:
admin = db.getSiblingDB("admin")
admin.auth("超级管理员账号","密码")
admin.createUser( { user: "fred", pwd: "changeme1", roles: [ { role: "readWrite", db: "xxx" } ] })