構建步驟

腳步:

  1. 為 Mongo 節點身份驗證生成 Base 64 金鑰檔案。將此檔案放在 chef data_bags 中

  2. 去廚師 suppermarket 並下載 docker cookbook。生成自定義菜譜(例如 custom_mongo)並將 docker,“〜> 2.0”新增到菜譜的 metadata.rb 中

  3. 在自定義菜譜中建立屬性和配方

  4. 初始化 Mongo 以形成 Rep Set 叢集

第 1 步:建立金鑰檔案

建立名為 mongo-keyfile 的 data_bag 和名為 keyfile 的項。這將在 chef 的 data_bags 目錄中。專案內容如下

openssl rand -base64 756 > <path-to-keyfile>

金鑰檔案專案內容

{
  "id": "keyfile",
  "comment": "Mongo Repset keyfile",
  "key-file": "generated base 64 key above"
}

第 2 步:從廚師晚餐市場下載 docker cookbook,然後建立 custom_mongo cookbook

knife cookbook site download docker 
knife cookbook create custom_mongo

在 custom_mongo 的 metadat.rb 中新增

depends          'docker', '~> 2.0'

第 3 步:建立屬性和配方

屬性

default['custom_mongo']['mongo_keyfile'] = '/data/keyfile' 
default['custom_mongo']['mongo_datadir'] = '/data/db'
default['custom_mongo']['mongo_datapath'] = '/data'
default['custom_mongo']['keyfilename'] = 'mongodb-keyfile'

食譜

#
# Cookbook Name:: custom_mongo
# Recipe:: default
#
# Copyright 2017, Innocent Anigbo
#
# All rights reserved - Do Not Redistribute
#

data_path = "#{node['custom_mongo']['mongo_datapath']}"
data_dir = "#{node['custom_mongo']['mongo_datadir']}"
key_dir = "#{node['custom_mongo']['mongo_keyfile']}"
keyfile_content = data_bag_item('mongo-keyfile', 'keyfile')
keyfile_name = "#{node['custom_mongo']['keyfilename']}"

#chown of keyfile to docker user
execute 'assign-user' do
 command "chown 999 #{key_dir}/#{keyfile_name}"
 action :nothing
end

#Declaration to create Mongo data DIR and Keyfile DIR
%W[ #{data_path} #{data_dir} #{key_dir} ].each do |path|
directory path do
  mode '0755'
  end
end

#declaration to copy keyfile from data_bag to keyfile DIR on your mongo server
file "#{key_dir}/#{keyfile_name}" do
  content keyfile_content['key-file']
  group 'root'
  mode '0400'
  notifies :run, 'execute[assign-user]', :immediately
end

#Install docker
docker_service 'default' do
  action [:create, :start]
end

#Install mongo 3.4.2
docker_image 'mongo' do
  tag '3.4.2'
  action :pull
end

在角色目錄中建立名為 mongo-role 的角色

{
  "name": "mongo-role",
  "description": "mongo DB Role",
  "run_list": [
    "recipe[custom_mongo]"
  ]
}

將上面的角色新增到三個 mongo 節點執行列表中

knife node run_list add FQDN_of_node_01 'role[mongo-role]'
knife node run_list add FQDN_of_node_02 'role[mongo-role]'
knife node run_list add FQDN_of_node_03 'role[mongo-role]'

步驟 4:初始化三個節點 Mongo 以形成 repset

我假設上面的角色已經應用於所有三個 Mongo 節點。僅在節點 01 上,使用 –auth 啟動 Mongo 以啟用身份驗證

docker run --name mongo -v /data/db:/data/db -v /data/keyfile:/opt/keyfile --hostname="mongo-01.example.com" -p 27017:27017 -d mongo:3.4.2 --keyFile /opt/keyfile/mongodb-keyfile --auth

訪問節點 01 上執行 docker container 的互動式 shell 並建立 admin 使用者

docker exec -it mongo /bin/sh
    mongo
    use admin
    db.createUser( {
         user: "admin-user",
         pwd: "password",
         roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
       });

建立 root 使用者

db.createUser( {
         user: "RootAdmin",
         pwd: "password",
         roles: [ { role: "root", db: "admin" } ]
       });

停止並刪除節點 01 上面建立的 Docker 容器。這不會影響主機 DIR 中的資料和金鑰檔案。刪除後再次在節點 01 上啟動 Mongo,但這次使用 repset 標誌

docker rm -fv mongo
docker run --name mongo-uat -v /data/db:/data/db -v /data/keyfile:/opt/keyfile --hostname="mongo-01.example.com" -p 27017:27017 -d mongo:3.4.2 --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"

現在使用 rep set 標誌在節點 02 和 03 上啟動 mongo

docker run --name mongo -v /data/db:/data/db -v /data/keyfile:/opt/keyfile --hostname="mongo-02.example.com" -p 27017:27017 -d mongo:3.4.2 --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"
docker run --name mongo -v /data/db:/data/db -v /data/keyfile:/opt/keyfile --hostname="mongo-03.example.com" -p 27017:27017 -d mongo:3.4.2 --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"

在節點 01 上使用 root 使用者進行身份驗證並啟動副本集

use admin
db.auth("RootAdmin", "password");
rs.initiate()

在節點 01 上,將節點 2 和 3 新增到副本集以形成 repset0 叢集

rs.add("mongo-02.example.com")
rs.add("mongo-03.example.com")

測試

在主執行 db.printSlaveReplicationInfo() 並觀察主要時間的 SyncedTo 和 Behind。後者應為 0 秒,如下所示

輸出

 rs0:PRIMARY> db.printSlaveReplicationInfo()
    source: mongo-02.example.com:27017
            syncedTo: Mon Mar 27 2017 15:01:04 GMT+0000 (UTC)
            0 secs (0 hrs) behind the primary
    source: mongo-03.example.com:27017
            syncedTo: Mon Mar 27 2017 15:01:04 GMT+0000 (UTC)
            0 secs (0 hrs) behind the primary

我希望這可以幫助別人