MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中最像关系数据库的。支持类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。本文介绍了如何使用Docker搭建MongoDB集群。

本文我会向大家介绍如何使用Docker部署一个MongoDB集群,具体如下:

2.6.5版本的MongoDB

有3个节点的副本集(Replica set)

身份验证

持久化数据到本地文件系统

首先要准备三个运行的Docker服务器,这意味着你要准备一个安装了Docker的本地Vagrant Box虚拟机(系统可以使用CoreOS)或者使用AWS或者其它的你喜欢的方式。

步骤

Step1:你要拿到3台Docker服务器的IP地址,并且将下面给出的IP地址配置到所有的服务器上面,每一台服务器都要执行如下命令(记得要替换掉IP地址哦):

root@node *:/# export node1=10.11.32.174

root@node *:/# export node2=10.11.33.37

root@node *:/# export node3=10.11.31.176

理想情况下你并不需要这么做,这些IP都是可以通过DNS自动配置好的。但是这样会更加简单,毕竟这只是一次安装测试。

Step2:为每个节点创建密钥文件。在其中某一台服务器上面执行如下的命令,然后把密钥文件复制到其余两个服务器的同样的位置。

在这个教程中,我将把所有的东西都放在“/home/core”文件夹中。

root@node *:/# mkdir -p /home/core

root@node *:/# cd /home/core

root@node *:/# openssl rand -base64 741 > mongodb-keyfile

root@node *:/# chmod 600 mongodb-keyfile

root@node *:/# sudo chown 999 mongodb-keyfile

这个密钥文件的所有者被设置成id为“999”的用户了,因为在MongoDB的Docker容器中,这个用户需要有操作密钥文件的权限。

Step3:启动node1(即第一台Docker服务器)的MongoDB容器。它会启动一个没有身份验证机制的容器,所以我们要设置一个用户。

root@node1:/# docker run --name mongo \

-v /home/core/mongo-files/data:/data/db \

-v /home/core/mongo-files:/opt/keyfile \

--hostname="node1.example.com" \

-p 27017:27017 \

-d mongo:2.6.5 --smallfiles

现在创建一个admin用户。我们可以连接到刚刚启动的mongoDB容器,并进入一个交互式的shell环境.

root@node1:/# docker exec -it mongo /bin/bash

这时候,我们就进到MongoDB的Docker容器里面了,然后我们要打开一个mongo shell环境:

root@node1:/# mongo

上面的命令可以打开mongo shell环境。执行后你会看到这样的输出:

MongoDB shell version: 2.6.5

connecting to: test

Welcome to the MongoDB shell.

For interactive help, type "help".

For more comprehensive documentation, see

http://docs.mongodb.org/

Questions? Try the support group

http://groups.google.com/group/mongodb-user

>

切换到admin用户:

> use admin

switched to db admin

创建一个新的site admin 用户

> db.createUser( {

user: "siteUserAdmin",

pwd: "password",

roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]

});

创建成功的话你会看到如下的成功信息:

Successfully added user: {

"user" : "siteUserAdmin",

"roles" : [

{

"role" : "userAdminAnyDatabase",

"db" : "admin"

}

]

}

创建一个root用户:

> db.createUser( {

user: "siteRootAdmin",

pwd: "password",

roles: [ { role: "root", db: "admin" } ]

});

你会看到如下的成功信息:

Successfully added user: {

"user" : "siteRootAdmin",

"roles" : [

{

"role" : "root",

"db" : "admin"

}

]

}

我们已经创建好了我们以后要使用的几个用户,现在我们不会退出交互式shell环境(mongo和Docker容器的环境)。

> exit

bye

root@node1:/# exit

Step4:停止第一个MongoDB实例:

root@node1:/# docker stop mongo

Step5:这次使用密钥文件启动第一台MongoDB实例(还是在node1上面操作的)。

root@node1:/# docker rm mongo

root@node1:/# docker run \

--name mongo \

-v /home/core/mongo-files/data:/data/db \

-v /home/core/mongo-files:/opt/keyfile \

--hostname="node1.example.com" \

--add-host node1.example.com:${node1} \

--add-host node2.example.com:${node2} \

--add-host node3.example.com:${node3} \

-p 27017:27017 -d mongo:2.6.5 \

--smallfiles \

--keyFile /opt/keyfile/mongodb-keyfile \

--replSet "rs0"

注意:

--keyFile的路径是/opt/keyfile/mongodb-keyfile,这是正确的。这是密钥文件在Docker内部的地址,我们用-v选项将密钥文件映射到容器内部的那个路径上(即:/opt/keyfile/mongodb-keyfile)。

--add-host把这些信息添加到Docker容器的/etc/hosts文件中,所以我们可以使用域名而不是IP地址了。在实际的生产环境中这些信息都是DNS,这些参数都可以忽略。

Step6:连接到副本集上并且安装配置好它。这还是在node1上面进行的。我们要开启另外一个新的交互式shell环境进入mongo容器,同时开启一个mongo shell环境:

root@node1:/# docker exec -it mongo /bin/bash

root@node1:/# mongo

MongoDB shell version: 2.6.5

>

切换到admin用户下:

> use admin

switched to db admin

因为我们已经设置了一个密码,所以这次我们不得不做身份验证。我们把密码设置为:password。

> db.auth("siteRootAdmin", "password");

1

现在我们可以开启副本集:

> rs.initiate()

{

"info2" : "no configuration explicitly specified -- making one",

"me" : "node1.example.com:27017",

"info" : "Config now saved locally.  Should come online in about a minute.",

"ok" : 1

}

>

Step7:验证已经初始化的副本集的配置:

>

rs0:PRIMARY> rs.conf()

{

"_id" : "rs0",

"version" : 1,r

"members" : [

{

"_id" : 0,

"host" : "node1.example.com:27017"

}

]

}

Step8:在其余的两个节点启动MongoDB。

在node2上面执行命令:

root@node2:/# docker run \

--name mongo \

-v /home/core/mongo-files/data:/data/db \

-v /home/core/mongo-files:/opt/keyfile \

--hostname="node2.example.com" \

--add-host node1.example.com:${node1} \

--add-host node2.example.com:${node2} \

--add-host node3.example.com:${node3} \

-p 27017:27017 -d mongo:2.6.5 \

--smallfiles \

--keyFile /opt/keyfile/mongodb-keyfile \

--replSet "rs0"

在node3上面执行命令:

root@node3:/# docker run \

--name mongo \

-v /home/core/mongo-files/data:/data/db \

-v /home/core/mongo-files:/opt/keyfile \

--hostname="node3.example.com" \

--add-host node1.example.com:${node1} \

--add-host node2.example.com:${node2} \

--add-host node3.example.com:${node3} \

-p 27017:27017 -d mongo:2.6.5 \

--smallfiles \

--keyFile /opt/keyfile/mongodb-keyfile \

--replSet "rs0"

Step 9:将那两个节点加到副本集上。

回到node1节点,如果你在这里按了几次回车键(enter)的话,你会看到下面的提示:“rs0:PRIMARY”。这是因为这个节点是副本集“rso”的主节点。

rs0:PRIMARY> rs.add("node2.example.com")

rs0:PRIMARY> rs.add("node3.example.com")

我们可以通过执行下面的命令来验证其它两个节点是否正确的加到这个副本集当中:

rs0:PRIMARY> rs.status()

可能会花几分钟的时间来将node1上面的数据同步到其余的两个节点上面。你可以通过查看日志来观察每一个MongoDB的Docker容器里面发生了什么。在任意一个服务器上面执行下面的命令就可以了:

root@node*:/# docker logs -ft mongo

结论

现在你拥有了一个MongoDB集群。你可以自由的在任何时刻添加节点到这个集群上。你甚至可以关闭其中的一个节点,包括主节点,然后观察一个另外一个节点重新变成了主节点。由于这些数据都被写在了你的本机文件系统当中了,所以重启任何一个节点都不是什么大问题。

手把手教你用Docker部署一个MongoDB集群的更多相关文章

  1. Docker 部署 RocketMQ Dledger 集群模式( 版本v4.7.0)

    文章转载自:http://www.mydlq.club/article/97/ 系统环境: 系统版本:CentOS 7.8 RocketMQ 版本:4.7.0 Docker 版本:19.03.13 一 ...

  2. Kubernetes 学习笔记(二):本地部署一个 kubernetes 集群

    前言 前面用到过的 minikube 只是一个单节点的 k8s 集群,这对于学习而言是不够的.我们需要有一个多节点集群,才能用到各种调度/监控功能.而且单节点只能是一个加引号的"集群&quo ...

  3. kubeadm部署一个Kubernetes集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具.这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 $ kubeadm in ...

  4. 用kubeadm+dashboard部署一个k8s集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: 1. 安装要求 在开始之前,部署Kubernetes集群 ...

  5. 第3章:快速部署一个Kubernetes集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点$ kubeadm in ...

  6. 使用docker快速部署一个consul集群

    作为一个开发者,有时候需要一个集群环境,之前的做法要么就是使用多个虚拟机,要么就是采用不同的端口来模拟,但是虚拟机比较占内存,而且启动慢,采用不同的端口来模拟,管理起来比较麻烦一些,程序隔离性差一些. ...

  7. 使用 Docker, 7 个命令部署一个 Mesos 集群

    这个教程将给你展示怎样使用 Docker 容器提供一个单节点的 Mesos 集群(未来的一篇文章将展示怎样很容易的扩展这个到多个节点或者是见底部更新).这意味着你可以使用 7 个命令启动整个集群!不需 ...

  8. docker部署Ceph分布式存储集群

    1.环境准备 3台virtualbox虚拟机,用来安装ceph集群,已用docker-machine安装上了docker,每台虚拟机虚拟创建一个5G的硬盘,用于存储osd数据,例如:/dev/sdb ...

  9. Linux Centos7 环境搭建Docker部署Zookeeper分布式集群服务实战

    Zookeeper完全分布式集群服务 准备好3台服务器: [x]A-> centos-helios:192.168.19.1 [x]B-> centos-hestia:192.168.19 ...

随机推荐

  1. php总结_1

    ?php //检测变量类型,自己用的最多的是is_array()了,其他的几乎没用过 $array = array(1,9.9,'abc',array(1,2,3),true,null,); v(is ...

  2. [C++]C,C++中使用可变参数

    可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是int,double还可以是char*,类,结构体等等.可变参数是实现printf(),sprintf()等函数的关键之处, ...

  3. MySQL中的正则表达式

    正则表达式是用正则表达式语言来建立 基本字符的匹配 .是正则表达式语言中的一个特殊的字符,它表示匹配任意一个字符 在LIKE和REGEXP之间有一个重要的差别,LIKE匹配整个列,如果被匹配的文本仅在 ...

  4. 定时器详解和应用、js加载阻塞、css加载阻塞

    1.setTimeout().setInterval()详解和应用 1.1 详解: setTimeout.setInterval执行时机 1.2 存在问题: setInterval重复定时器可能存在的 ...

  5. java二分法查找实现代码

    package util; class BinarySearch { static int binarySearch(int[] array,int goal){//传入排好序的数组和目标数字 int ...

  6. Kubernetes基本概念之Name和NameSpace

    在Kubernetes中,所有对象都会被指定一个唯一的Name和UID. 用户还可以指定一些不要求唯一性的数据附加到对象上,例如Label和Annotation. 1. Name Name是创建一个K ...

  7. jmeter csv中获取带引号的数据详情(转)

    最近在工作中,对jmeter实践的点滴的记录这里分享,不一定正确,仅供参考和讨论,有想法的欢迎留言.谈论. 1技巧1:从csv中获取带引号的数据详情 背景:我们从csv中获取数据,在jmeter中使用 ...

  8. ES6工作中常用知识点

    好久不动笔了 第一个知识点:import 和 export import导入模块.export导出模块 //全部导入 import people from './example' //有一种特殊情况, ...

  9. [转]深入探讨C语言中局部变量与全局变量的作用域与存储类别

    C语言中局部变量和全局变量变量的作用域与存储类别(auto,static,extern,register) 1.局部变量和全局变量在讨论函数的形参变量时曾经提到,形参变量只在被调用期间才分配内存单元, ...

  10. 平衡树合集(Treap,Splay,替罪羊,FHQ Treap)

    今天翻了翻其他大佬的博客,发现自己有些...颓废... 有必要洗心革面,好好学习 序:正常的BST有可能退化,成为链,大大降低效率,所以有很多方法来保持左右size的平衡,本文将简单介绍Treap,S ...