http://blog.0x01.site/2017/01/13/MongoDB%E7%9A%84Replica-Set%E4%BB%A5%E5%8F%8AAuth%E7%9A%84%E9%85%8D%E7%BD%AE/

MongoDB事件出现后,公司要给MongoDB加Auth,于是我就调研了一番。

现在MongoDB在生产中一般使用Replica Set的方式部署,如果一台宕机,另外一台Secondary会变成Master继续服务,提高可用性。

使用docker搭个集群测试,首先建个network bridge

1
docker network new mongo-network

然后就是运行MongoDB的容器,集群名为test-rep

1
2
3
docker run --rm -it --name mongo1 --net=mongo-network mongo --replSet test-rep
docker run --rm -it --name mongo2 --net=mongo-network mongo --replSet test-rep
docker run --rm -it --name mongo3 --net=mongo-network mongo --replSet test-rep

然后再运行一个连接到上述三个MongoDB的容器

1
docker run --rm -it --name mongo-client --net=mongo-network mongo /bin/bash

然后在容器中执行

1
mongo --host mongo1

发现连接上了,说明MongoDB的配置没有问题,然后是配置Replica Set。Replica Set要求配置的members中不能有localhost,而我配置为mongo2,mongo3这种一直都报类似的错误,我索性找出了几个容器的IP,配置上去

1
docker network inspect mongo-network

可以看到几个容器的IP

然后就可以使用IP地址配置了

1
2
config = {_id:"test-rep", version:1, members:[{_id:0, host:"172.19.0.5:27017", priority:5}, {_id:1, host:"172.19.0.3:27017", priority:2}, {_id:2, host:"172.19.0.4:27017", priority:3}]}
rs.initiate(config)

再去看mongod的log,发现集群同步成功

把mongo1停掉,mongo2会成为primary


然后按照MongoDB的文档增加用户

1
2
3
4
5
6
7
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)

重启mongod的进程,增加–auth参数,表示启用权限校验

1
2
3
docker run --rm -it --name mongo1 --net=mongo-network mongo --replSet test-rep --auth
docker run --rm -it --name mongo2 --net=mongo-network mongo --replSet test-rep --auth
docker run --rm -it --name mongo3 --net=mongo-network mongo --replSet test-rep --auth

发现一直报Error in heartbeat request to 172.19.0.5:27017; Unauthorized: not authorized on admin to execute command的错误,查了很久,发现Replica Set要使用keyFile的校验方式,让集群的member之间同步,也就是说,通过keyFile获得__system用户在local上的权限。local存放着Replica Set的配置和同步信息。
MongoDB官方推荐的keyFile的生产方式

1
2
openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>

先结束掉mongod的进程,因为要放入keyFile,于是我启动docker的时候,默认不启动mongod

1
docker run --rm -it --name mongo1 --net=mongo-network mongo /bin/bash

容器里没有装openssl,我偷懒使用了以下命令

1
2
echo 'I8au1RERvEQkIiIB7vhTMhfceA8oH/L0mT6xxeVgaJg/mYnnZe89dGWjMrQSXI7A' > /data/key_file
chmod 400 /data/key_file

然后启动mongod进程

1
mongod --replSet test-rep --auth --keyFile=/data/key_file

在mongo2,mongo3上按照上述命令,依次启动。发现漂亮的同步成功的标志

收工


生产上的MongoDB,切换到需要Auth,是否可以在不停机的状况下进行呢?

某同学猜想,mongod不采用Auth的时候,客户端使用密码,可不可以呢?Python连接MongoDB的代码很简单

pymongo.MongoClient('mongodb://user:user1@mongo1:27017,mongo2:27017,mongo3:27017/mydb?authMechanism=SCRAM-SHA-1')

访问mydb的时候,直接就抛Authentication failed错误了。如果我先添加了user呢?在mongo shell中执行

1
2
3
4
5
6
7
8
db.createUser(
{
user: "user",
pwd: "user1",
roles: [ { role: "readWrite", db: "mydb" },
{ role: "readWrite", db: "mydb2" } ]
}
)

刚刚的admin,只是访问admin库的用户名和密码,可以管理用户信息,user用户可以用来读写相应的库。此时,mongod依然没有使用--auth启动,因此是没有权限检查的,再次连接,一切正常。

因此配置步骤如下

  • 创建MongoDB用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use admin
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" },
]
}
) use mydb
db.createUser(
{
user: "user",
pwd: "user1",
roles: [ { role: "dbOwner", db: "mydb" },
{ role: "dbOwner", db: "mydb2" } ]
}
)
  • 修改应用,更改MongoDB的URI
1
pymongo.MongoClient('mongodb://user:user1@mongo1:27017,mongo2:27017,mongo3:27017/mydb?authMechanism=SCRAM-SHA-1')
  • mongod增加keyFile
1
2
openssl rand -base64 756 > /data/key_file
chmod 400 /data/key_file
  • 把key_file上传到其他mongod服务器上,修改mongod配置,一般是/etc/mongodb.conf
1
2
3
security:
authorization: enabled
keyFile: /data/key_file
  • 然后同时重启三台mongod

这样只有重启的那一刹那不可用

MongoDB的Replica Set以及Auth的配置的更多相关文章

  1. MongoDB 维护Replica Set

    在每个MongoDB(版本 3.2.9) Instance中,都有一个本地数据库(local),用于存储 Replication 进程的信息和本地数据.local 数据库的特性是:位于local数据库 ...

  2. 部署Replica Sets及查看相关配置

    MongoDB 支持在多个机器中通过异步复制达到故障转移和实现冗余.多机器中同一时刻只有一台是用于写操作.正是由于这个情况,为MongoDB 提供了数据一致性的保障.担当Primary 角色的机器能把 ...

  3. mongodb的学习-3-在Mac上的安装配置

    1.使用homebrew安装: brew install mongodb 查看安装好的版本: mongo --version MongoDB shell version v3.6.4 git vers ...

  4. MongoDB之Replica Sets环境搭建

    最近学习MongoDB,这两天在搭建复制集的时候碰到了不少问题,也踩了好多坑,现在在这里记录下来,以供自己和他人参考 (因为本人是初学者,所以遇到的问题也会比较初级,所以本文也比较适合初学者查阅) 背 ...

  5. 学习MongoDB(二) Replica Set集群配置

    1.官方网址:https://docs.mongodb.org/manual/tutorial/deploy-replica-set-for-testing/ 2.Replica Set介绍: htt ...

  6. mongodb主从以及auth主从 配置详解

    1.主服务器配置   #auth = true   dbpath = /data/mongodb/db logpath = /data/mongodb/log/mongodb.log   port = ...

  7. MongoDB搭建Replica Set Shard Cluster步骤

    本文记录从头搭建一个MongoDB 副本集分片集群的过程. 我们要创建一个这样子的分布式集群:有两个shard,每个shard都是一个replica set,各有两个副本(实际产品应用中还应加上一个仅 ...

  8. mongodb系列之--分片的原理与配置

    1.分片的原理概述 分片就是把数据分成块,再把块存储到不同的服务器上,mongodb的分片是自动分片的,当用户发送读写数据请求的时候,先经过mongos这个路由层,mongos路由层去配置服务器请求分 ...

  9. mongodb数据库集群及sharding分片配置

    复制集群的配置 1.安装mongodb数据库 在主节点和从节点上都安装mongodb # rpm -ivh mongo-10gen-2.4.6-mongodb_1.x86_64.rpm mongo-1 ...

随机推荐

  1. MPI 集合通信函数 MPI_Reduce(),MPI_Allreduce(),MPI_Bcast(),MPI_Scatter(),MPI_Gather(),MPI_Allgather(),MPI_Scan(),MPI_Reduce_Scatter()

    ▶ 八个常用的集合通信函数 ▶ 规约函数 MPI_Reduce(),将通信子内各进程的同一个变量参与规约计算,并向指定的进程输出计算结果 ● 函数原型 MPI_METHOD MPI_Reduce( _ ...

  2. kettle中文乱码问题

    db连接->选项 配置参数 characterEncoding,设置值为gbk/utf8.

  3. oracle SQL多表查询

    SQL多表查询 1.集合理论 1.1 什么是集合 具有某种特定性质的事物的总体. 集合的特性:无序性.互异性.确定性. 一个集合可以小到从一个表中取出一行中的一列.              1 ro ...

  4. 为什么对string调用swap会导致迭代器失效

    一般来说,swap操作将容器内容交换不会导致容器的指针.引用.迭代器失效. 但当容器类型为array和string时除外. 原因在于:SSO  (Short String Optimization 指 ...

  5. 一个PHP session的误区,自己留着长记性看看

    最近在研究PHP session相关的东西,销毁session根据手册使用session_destroy()就可以了,但是天真的以为销毁了会话就可以把会话内容也销毁,但是实际上会话的内容还保存在内存里 ...

  6. js:一些基础

    JavaScript 基础(一)   JavaScript的引入方式 直接编写 <!DOCTYPE html> <html lang="en"> <h ...

  7. Mysql的隔离级别

    一.首先什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事 ...

  8. Codeforces Round #436 C. Bus

    题意:一辆车在一条路上行驶,给你路的总长度a,油箱的容量b,加油站在距离起点的距离f,以及需要走多少遍这条路k(注意:不是往返) 问你最少加多少次油能走完. Examples Input 6 9 2 ...

  9. cordova/ionic打包流程

    ionic android 手工打包指令手册 [工作平台要求] 安装 node.js.cordova.ionic(非必须) 等前端相关软件与组件(1)安装 Java-SDK,正确配置系统环境变量 JA ...

  10. Masonry与AmazeUI结合实现瀑布流

    做一个图片列表展示,由于照片数量太多,决定用瀑布流来实现 由于之前没有接触过瀑布流,不知从何下手 百度一下大家都在用Masonry 官网 https://masonry.desandro.com/ 这 ...