我寫了一篇有關如何使用DevOps時尚風格部署mongodb集群的新文章,在本文中,我正在使用Terraform,Ansible,Packer和更酷的技術,我強烈建議您閱讀它。
以DevOps時尚風格(將基礎架構作為代碼)部署MongoDB副本集。
本文將逐步介紹如何使用Docker設置帶有身份驗證的MongoDB副本集。
我們將在本文中使用的是:
- MongoDB 3.4.1
- 適用于mac 1.12.6的Docker
副本集的體系結構
帶有docker的副本集的架構
在上圖中,我們看到了使用docker復制集的結果。
#先決條件
- docker基礎知識
- 安裝了docker和docker-machine
- mongoDB的基礎知識
- bash腳本編寫的基礎知識
如果您使用的是Mac或windows,請考慮使用虛擬機。我將在MacOS Sierra上使用VirtualBox運行我們的mongoDB實例。
#步驟1 —創建我們的3個docker-machines
要創建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
#步驟2 — MongoDB主節點的配置
現在我們有了三臺機器,讓我們將其放置在第一臺機器上以啟動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
密碼應隨機,長且復雜,以確保系統安全并防止或延遲惡意訪問。有關內置角色的完整列表,請參見數據庫用戶角色,這些角色與數據庫管理操作有關。
我們所做的直到知道:
- 創建了mongo_storagedocker volume。
- 創建了mongo-keyfile,openssl密鑰生成。
- 為mongoDB創建了admin.js文件 admin用戶。
- 創建了copy.js文件,以初始化副本集。
好的,讓我們繼續將文件傳遞到容器。
$ 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標志:
- 該--env-file讀取ENV文件,并設置environment在容器內的變量。
- 該--add-host標志將條目添加到Docker容器的/etc/hosts文件中,因此我們可以使用主機名代替IP地址。在這里,我們映射了我們之前創建的3個docker-machines。
要更深入地了解docker run命令,請閱讀Docker文檔。
Docker Flags
為了設置mongo副本集,我們需要各種mongo標志
- --keyFile 這個標志是用來告訴mongo在哪里 mongo-keyfile.
- --replSet 該標志用于設置副本集的名稱。
- --storageEngine由于mongoDB 3.4.1的默認引擎為wiredTiger,因此不需要此標志用于設置mongoDB的引擎。
為了對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 }
#步驟3 —再添加2個mongo節點容器
現在一切就緒,讓我們再啟動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 }
該函數內部也有對函數的調用,沒有添加任何新內容,我們之前已經看過所有功能,讓我為您描述它的作用:
- 為副本集身份驗證創建密鑰文件。
- 創建一個mongodb容器,并接收2個參數:a)待定位的服務器,b)容器的名稱,c)docker卷的名稱,所有我們之前看到的功能。
- 最后,它將使用與我們之前完全相同的步驟來啟動副本。
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倉庫
要獲取本文的完整腳本文件,可以在以下倉庫中進行檢查。
github-Crizstian / mongo-replica-with-docker:如何使用Docker部署MongoDB副本集github.com
進一步閱讀
- 使用密鑰文件訪問控制部署副本集 — MongoDB文檔。
- 將成員添加到副本集中 -MongoDB文檔。
- MongoDB Docker Hub — Docker Docs.
- 如何避免勒索數據的惡意攻擊
- 如何在Ubuntu 16.04上設置安全的mongoDB 3.4服務器
翻譯自:https://towardsdatascience.com/how-to-deploy-a-mongodb-replica-set-using-docker-6d0b9ac00e49
0人點贊
Mongodb