我写了一篇有关如何使用DevOps时尚风格部署mongodb集群的新文章,在本文中,我正在使用Terraform,Ansible,Packer和更酷的技术,我强烈建议您阅读它。
以DevOps时尚风格(将基础架构作为代码)部署MongoDB副本集。
本文将逐步介绍如何使用Docker设置带有身份验证的MongoDB副本集。
我们将在本文中使用的是:
在上图中,我们看到了使用docker复制集的结果。
#先决条件
如果您使用的是Mac或windows,请考虑使用虚拟机。我将在MacOS Sierra上使用VirtualBox运行我们的mongoDB实例。
要创建docker机器,我们需要在终端中发出下一个命令:
此命令将使用virtualbox作为我们的虚拟化提供程序创建一个名为manager1的计算机。
现在让我们创建两个左 docker-machine
$ docker-machine create -d virtualbox worker1 $ docker-machine create -d virtualbox worker2
要验证是否创建了我们的机器,让我们运行以下命令:
$ docker-machine ls // the result will be NAME ACTIVE DRIVER STATE URL manager1 - virtualbox Running tcp://192.168.99.100:2376 worker1 - virtualbox Running tcp://192.168.99.101:2376 worker2 - virtualbox Running tcp://192.168.99.102:2376
现在我们有了三台机器,让我们将其放置在第一台机器上以启动mongodb配置,让我们运行下一个命令:
$ eval `docker-machine env manager1`
创建我们的MongoDB容器之前,还有一个已经存在了很长讨论了非常重要的课题数据库持久的ocker containers,并为实现这一挑战,我们所要做的是创建一个docker volume。
$ docker volume create --name mongo_storage
现在,让我们附加创建的卷以启动我们的第一个mongo容器并设置配置。
$ docker run --name mongoNode1 -v mongo_storage:/data -d mongo --smallfiles
接下来,我们需要创建密钥文件。
密钥文件的内容用作副本集成员的共享密码。对于副本集的所有成员,密钥文件的内容必须相同。
$ openssl rand -base64 741 > mongo-keyfile $ chmod 600 mongo-keyfile
接下来,我们创建一个文件夹,用于存放mongo_storage卷中的数据,密钥文件和配置:
$ docker exec mongoNode1 bash -c 'mkdir /data/keyfile /data/admin'
下一步是创建一些管理员用户,让我们创建一个看起来像这样的admin.js和copy.js文件:
// admin.js admin = db.getSiblingDB("admin") // creation of the admin user admin.createUser( { user: "cristian", pwd: "cristianPassword2017", roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } ) // let's authenticate to create the other user db.getSiblingDB("admin").auth("cristian", "cristianPassword2017" ) // creation of the replica set admin user db.getSiblingDB("admin").createUser( { "user" : "replicaAdmin", "pwd" : "replicaAdminPassword2017", roles: [ { "role" : "clusterAdmin", "db" : "admin" } ] } )
//replica.js rs.initiate({ _id: 'rs1', members: [{ _id: 0, host: 'manager1:27017' }] })
IMPORTANT
密码应随机,长且复杂,以确保系统安全并防止或延迟恶意访问。有关内置角色的完整列表,请参见数据库用户角色,这些角色与数据库管理操作有关。
我们所做的直到知道:
好的,让我们继续将文件传递到容器。
$ docker cp admin.js mongoNode1:/data/admin/ $ docker cp replica.js mongoNode1:/data/admin/ $ docker cp mongo-keyfile mongoNode1:/data/keyfile/
// change folder owner to the user container $ docker exec mongoNode1 bash -c 'chown -R mongodb:mongodb /data'
我们所做的是,我们需要传递到容器中的文件,然后修改 了 / data文件夹所有者 到容器的用户,因为容器用户是需要访问这个文件夹和文件的用户。
现在,所有内容都已设置好,我们准备使用副本集配置重新启动mongod实例。
在启动经过身份验证的mongo容器之前,让我们创建一个env文件来设置我们的用户和密码。
MONGO_USER_ADMIN=cristian MONGO_PASS_ADMIN=cristianPassword2017 MONGO_REPLICA_ADMIN=replicaAdmin MONGO_PASS_REPLICA=replicaAdminPassword2017
现在我们需要删除容器并开始一个新的容器。为什么?,因为我们需要提供副本集和身份验证参数,并且为此,我们需要运行以下命令:
// first let's remove our container $ docker rm -f mongoNode1 // now lets start our container with authentication $ docker run --name mongoNode1 --hostname mongoNode1 -v mongo_storage:/data --env-file env --add-host manager1:192.168.99.100 --add-host worker1:192.168.99.101 --add-host worker2:192.168.99.102 -p 27017:27017 -d mongo --smallfiles --keyFile /data/keyfile/mongo-keyfile --replSet 'rs1' --storageEngine wiredTiger --port 27017
这里发生了什么………似乎是在滥用旗帜。
让我分两部分向您解释:
Docker标志:
要更深入地了解docker run命令,请阅读Docker文档。
Docker Flags
为了设置mongo副本集,我们需要各种mongo标志
为了对mongo副本集有更深入的了解,请阅读MongoDB文档,我也建议使用MongoUniversity课程以了解有关此主题的更多信息。
mongoNode1容器的最后一步是启动副本集,我们将通过运行以下命令来做到这一点:
$ docker exec mongoNode1 bash -c 'mongo < /data/admin/replica.js'
您应该会看到以下内容:
MongoDB shell version v3.4.1 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.1 { "ok" : 1 } bye
现在,让我们使用以下命令创建管理员用户:
$ docker exec mongoNode1 bash -c 'mongo < /data/admin/admin.js'
您应该会看到以下内容:
MongoDB shell version v3.4.1 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.1 admin Successfully added user: { "user" : "cristian", ... Successfully added user: { "user" : "replicaAdmin", ... bye
现在,要进入副本,请运行以下命令:
$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA --eval "rs.status()" --authenticationDatabase "admin"'
您应该已经准备好,看到类似以下内容:
MongoDB shell version v3.4.1 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.1 { "set" : "rs1", ... "members" : [ { "_id" : 0, "name" : "manager1:27017", ... "ok" : 1 }
现在一切就绪,让我们再启动2个节点并将它们加入副本集。
要添加第一个节点,我们将其更改为worker1 docker计算机,如果您使用的是本地计算机,请运行以下命令:
eval `docker-machine env worker1`
如果您不在本地运行,只需将终端指向下一个服务器即可。
现在,由于我们将重复几乎为mongoNode1所做的所有步骤,因此让我们创建一个脚本来为我们运行所有命令。
让我们创建一个名为create-replica-set.sh的文件,然后看看如何组成main函数:
function main { init_mongo_primary init_mongo_secondaries add_replicas manager1 mongoNode1 check_status manager1 mongoNode1 } main
现在,让我向您展示此功能的组成:
INIT MONGO Main Function
function init_mongo_primary { # [@params](http://twitter.com/params) name-of-keyfile createKeyFile mongo-keyfile # [@params](http://twitter.com/params) server container volume createMongoDBNode manager1 mongoNode1 mongo_storage # [@params](http://twitter.com/params) container init_replica_set mongoNode1 }
该函数内部也有对函数的调用,没有添加任何新内容,我们之前已经看过所有功能,让我为您描述它的作用:
INIT MONGO SECONDARY FUNCTION
function init_mongo_secondaries { # [@Params](http://twitter.com/Params) server container volume createMongoDBNode worker1 mongoNode1 mongo_storage createMongoDBNode worker2 mongoNode2 mongo_storage }
此功能的作用是为副本集创建其他2个mongo容器,并执行与mongoNode1相同的步骤,但是这里我们不包括副本集实例化和admin用户创建,因为这些不是必需的,因为副本集将与副本的所有节点共享数据库配置,以后再将它们添加到主数据库中。
添加复制功能
function add_replicas { echo '·· adding replicas >>>> '$1' ··' switchToServer $1 for server in worker1 worker2 do rs="rs.add('$server:27017')" add='mongo --eval "'$rs'" -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA --authenticationDatabase="admin"' sleep 2 wait_for_databases $server docker exec -i $2 bash -c "$add" done }
在这里,我们要做的是最后将另外两个mongo容器添加到副本集配置上的主数据库中,首先我们遍历剩下的机器以添加容器,在循环中我们准备配置,然后检查容器是否准备好了,我们通过调用函数来做到这一点wait_for_databases,然后将机器作为参数传递给我们,然后在主数据库中执行配置,然后我们应该收集如下消息:
MongoDB shell version v3.4.1 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.1 { "ok" : 1 }
这意味着mongo容器已成功添加到副本。
最后,我们使用main中的最后一个功能检查副本集的状态:
# [@params](http://twitter.com/params) server container function check_status { switchToServer $1 cmd='mongo -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA --eval "rs.status()" --authenticationDatabase "admin"' docker exec -i $2 bash -c "$cmd" }
既然我们已经了解了自动化脚本的功能并且知道将要执行的操作,那么现在该执行自动化bash脚本了,如下所示:
请注意,如果已完成上述所有步骤,则需要重置我们已实现的所有内容,以避免任何冲突名称问题,要重置配置,请在github存储库中找到一个reset.sh文件
# and this how we can execute the script that will configure # everything for us. $ bash < create-replica-set.sh
如果一切设置正确,我们应该看到来自mongodb的消息,如下所示:
MongoDB shell version v3.4.1 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.1 { "set" : "rs1", ... }, "members" : [ { "_id" : 0, "name" : "manager1:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", ... }, { "_id" : 1, "name" : "worker1:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", ... }, { "_id" : 2, "name" : "worker2:27017", "health" : 1, "state" : 0, "stateStr" : "STARTUP", ... } ], "ok" : 1 }
正如您所看到的,每个容器现在都已正确配置,需要注意的是,我们--add-host像以前一样使用了来自docker 的标志,并将这些条目添加到Docker容器的/ etc / hosts文件中,因此我们可以使用主机名代替IP地址。
两个节点都可能需要一分钟才能完成从mongoNode1的同步。
您可以通过查看日志来查看每个mongo Docker容器中发生的情况。您可以通过在任何docker-machine服务器上运行此命令来执行此操作。
$ docker logs -ft mongoContainerName
现在我们已经启动并运行了一个MongoDB副本设置服务,让我们修改用户,或者您可以创建另一个用户并授予一些权限来对数据库执行Crud操作,因此,仅出于说明目的,这是一个不好的做法,让我添加一个的管理员用户的超级角色。
# we are going to assign the root role to our admin user # we enter to the container $ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"' # Then we execute the following in the mongo shell # Mongo 3.4.1 shell > use admin > db.grantRolesToUser( "cristian", [ "root" , { role: "root", db: "admin" } ] ) >
现在,他拥有一个可以做任何事情的超级用户,因此让我们创建一个数据库并插入一些数据。
$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"' # Mongo 3.4.1 shell > use movies > db.movies.insertMany([{ id: '1', title: 'Assasins Creed', runtime: 115, format: 'IMAX', plot: 'Lorem ipsum dolor sit amet', releaseYear: 2017, releaseMonth: 1, releaseDay: 6 }, { id: '2', title: 'Aliados', runtime: 124, format: 'IMAX', plot: 'Lorem ipsum dolor sit amet', releaseYear: 2017, releaseMonth: 1, releaseDay: 13 }, { id: '3', title: 'xXx: Reactivado', runtime: 107, format: 'IMAX', plot: 'Lorem ipsum dolor sit amet', releaseYear: 2017, releaseMonth: 1, releaseDay: 20 }, { id: '4', title: 'Resident Evil: Capitulo Final', runtime: 107, format: 'IMAX', plot: 'Lorem ipsum dolor sit amet', releaseYear: 2017, releaseMonth: 1, releaseDay: 27 }, { id: '5', title: 'Moana: Un Mar de Aventuras', runtime: 114, format: 'IMAX', plot: 'Lorem ipsum dolor sit amet', releaseYear: 2016, releaseMonth: 12, releaseDay: 2 }]) # inserted 5 documents >
现在,我们有了一个电影数据库,其中包含包含5部电影:D的电影集合。
我们所做的…
我们使用自动脚本使用Docker配置并启动带有身份验证的MongoDB副本集。
在安全方面,我们创建:
如果为数据库正确配置了访问控制,则攻击者应该无法访问您的数据。查看我们的安全检查表,以帮助发现潜在的漏洞。— @MongoDB文件
如果我们想为我们的架构增加更多的安全性,我们可以使用docker-machines 创建一个Swarm集群,并且docker swarm可以很好地处理网络通信,还可以在容器中创建非root用户,并且可以启用加密数据在mongoDB中,但是此主题不在本文的范围之内。
现在,我们有了一个可用的MongoDB复制集。您可以随时将节点添加到此副本集。您甚至可以停止mongo容器或主要mongoNode1中的一个,然后看着另一个mongoNode接管新的主要容器。由于数据写在docker卷上,因此重启这些节点中的任何一个都不是问题。数据将保留并重新加入副本集。
给我们带来的好处是,我们看到了如何使用bash文件使整个过程自动化。
您面临的一个挑战是修改bash脚本并使其更加动态,因为该脚本非常适合本文的规范,而另一个挑战是向体系结构中添加一个任意Mongo节点。
要获取本文的完整脚本文件,可以在以下仓库中进行检查。
github-Crizstian / mongo-replica-with-docker:如何使用Docker部署MongoDB副本集github.com
翻译自:https://towardsdatascience.com/how-to-deploy-a-mongodb-replica-set-using-docker-6d0b9ac00e49
0人点赞
Mongodb