一、安装docker。
请参考:http://www.cnblogs.com/hehexiaoxia/p/6150584.html
二、编写dockerfile。
1、在根目录下创建mongod的dockerfile。
$ vi dockerfile
#version 1.0 from ubuntu #maintainer maintainer hdx #install run apt-get clean run apt-get update run apt-get install -y vim run apt-get install -y openssh-server run mkdir -p /var/run/sshd #open port 22 20001 expose 22 expose 20001 #cmd ["/usr/sbin/sshd","-D"] run apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 run echo "deb http://repo.mongodb.org/apt/debian wheezy/mongodb-org/3.2 main">/etc/apt/sources.list.d/mongodb-org.list #install mongodb run apt-get update run apt-get install -y mongodb-org #create the mongodb data directory run mkdir -p /data/db entrypoint ["usr/bin/mongod"]
2、在根目录下创建mongod的dockerfile_mongos。
$ vi dockerfile_mongos
from ubuntu/mongo:latest entrypoint ["usr/bin/mongos"]
三、通过dockerfile生成image镜像。
$ sudo docker build -t ubuntu/mongo:latest -</dockerfile
$ sudo docker build -t ubuntu/mongo:latest -</dockerfile_mongos
查看image的生成情况。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu/mongo latest 522eeeae18e5 54 minutes ago ubuntu/mongos latest 522eeeae18e6 54 minutes ago
发现image已经生成,可以通过image来创建容器了。
四、通过image镜像构建mongo集群。
1、创建2个分片服务(shardsvr),每个shardsvr包含3个副本,其中1个主节点,1个从节点,1个仲裁节点。
-d 表示后台运行
-p 绑定host主机与docker的端口,第一个20001代表host主机端口,第二个代表对应的docker端口,绑定后可以通过调用host主机ip:port来访问docker的mongodb。
注意:一定不能退在最后添加--fork,使mongo服务后台运行,这样docker会任务无事可做而自杀!
$ sudo docker run -d -p 20001:20001 --name rs1_container1 ubuntu/mongo:lastest --shardsvr --port 20001 --replSet rs1
$ sudo docker run -d -p 20002:20001 --name rs1_container2 ubuntu/mongo:lastest --shardsvr --port 20001 --replSet rs1
$ sudo docker run -d -p 20003:20001 --name rs1_container3 ubuntu/mongo:lastest --shardsvr --port 20001 --replSet rs1
$ sudo docker run -d -p 20011:20001 --name rs2_container1 ubuntu/mongo:lastest --shardsvr --port 20001 --replSet rs2
$ sudo docker run -d -p 20012:20001 --name rs2_container2 ubuntu/mongo:lastest --shardsvr --port 20001 --replSet rs2
$ sudo docker run -d -p 20013:20001 --name rs2_container3 ubuntu/mongo:lastest --shardsvr --port 20001 --replSet rs2
2、创建2个配置服务(configsvr)。
$ sudo docker run -d -p 21001:20001 --name config_container1 ubuntu/mongo:lastest --configsvr --dbpath /data/db --replSet crs --port 20001
$ sudo docker run -d -p 21002:20001 --name config_container2 ubuntu/mongo:lastest --configsvr --dbpath /data/db --replSet crs --port 20001
注意: --dbpath /data/db一定要指定,因为--configsvr默认路径是/data/configdb,如果找不到会报错,然后docker直接自杀!
--replSet crs 从mongodb版本3.2以后支持configsvr的副本集。
3、启动2个路由服务(mongos)。
$ sudo docker run -d -p 22001:20001 --name mongos_container1 ubuntu/mongos:lastest --configdb crs/192.168.30.200:21001,192.168.30.200:21002 --port 20001
$ sudo docker run -d -p 22002:20001 --name mongos_container2 ubuntu/mongos:lastest --configdb crs/192.168.30.200:21001,192.168.30.200:21002 --port 20001
注意: crs/192.168.128.30:21001,192.168.128.30:21002 : mongodb版本3.2以后通过这种形式指定configdb,否则报错,ip要写宿主机的实际ip。
4、查看当前docker服务启动情况。
$ sudo docker ps
发现分片、配置服务、和路由服务都启动起来了。
五、mongo基本操作。
服务启动起来了,但是服务都是互相独立的,所以,接下来我们将这些服务器串联起来。
1、初始化分片rs1副本集。
# 任意选择rs1分片的一个副本 root@ubuntu:/# mongo --port 20001 # 切换数据库 use admin # 写配置文件 config = {_id:"rs1",members:[ {_id:0,host:"192.168.30.200:20001"}, {_id:1,host:"192.168.30.200:20002"}, {_id:2,host:"192.168.30.200:20003",arbiterOnly:true} ] } # 初始化副本集 rs.initiate(config)# 查看副本集状态 rs.status()
结果:
rs1:RECOVERING> rs.status() { "set" : "rs1", "date" : ISODate("2016-12-20T09:01:16.108Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "192.168.30.200:20001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 7799, "optime" : { "ts" : Timestamp(1482224415, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-12-20T09:00:15Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1482224414, 1), "electionDate" : ISODate("2016-12-20T09:00:14Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "192.168.30.200:20002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 71, "optime" : { "ts" : Timestamp(1482224415, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2016-12-20T09:00:15Z"), "lastHeartbeat" : ISODate("2016-12-20T09:01:15.016Z"), "lastHeartbeatRecv" : ISODate("2016-12-20T09:01:15.376Z"), "pingMs" : NumberLong(1), "syncingTo" : "192.168.30.200:20001", "configVersion" : 1 }, { "_id" : 2, "name" : "192.168.30.200:20003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 71, "lastHeartbeat" : ISODate("2016-12-20T09:01:15.016Z"), "lastHeartbeatRecv" : ISODate("2016-12-20T09:01:11.334Z"), "pingMs" : NumberLong(0), "configVersion" : 1 } ], "ok" : 1 }
2、初始化分片rs2副本集。
# 任意选择rs1分片的一个副本 root@ubuntu:/# mongo --port 20011 # 切换数据库 use admin # 写配置文件 config = {_id:"rs2",members:[ {_id:0,host:"192.168.30.200:20011"}, {_id:1,host:"192.168.30.200:20012"}, {_id:2,host:"192.168.30.200:20013",arbiterOnly:true} ] } # 初始化副本集 rs.initiate(config) # 查看副本集状态 rs.status()
3、初始化配置服务副本集。
# 任意选择crs分片的一个副本 root@ubuntu:/# mongo --port 21001 # 切换数据库 use admin # 写配置文件 config = {_id:"crs", configsvr:true, members:[ {_id:0,host:"192.168.30.200:21001"}, {_id:1,host:"192.168.30.200:21002"} ] } # 初始化副本集 rs.initiate(config) # 查看副本集状态 rs.status()
4、通过mongos添加分片关系到configsvr。
root@ubuntu:/# mongo --port 22001 use admin db.runCommand({addshard:"rs1/192.168.30.200:20001,192.168.30.200:20002,192.168.30.200:20003"}) db.runCommand({addshard:"rs2/192.168.30.200:20011,192.168.30.200:20012,192.168.30.200:20013"})
查询结果如下:仲裁节点没有显示。
mongos> db.runCommand({listshards:1}) { "shards" : [ { "_id" : "rs1", "host" : "rs1/192.168.30.200:20001,192.168.30.200:20002" }, { "_id" : "rs2", "host" : "rs2/192.168.30.200:20011,192.168.30.200:20012" } ], "ok" : 1 }
5、设置数据库、集合分片。
db.runCommand({enablesharding:"mydb"}) db.runCommand({shardcollection:"mydb.person", key:{id:1, company:1}})
设置数据库mydb、mydb中person表(集合)应用分片,片键为person集合的id、company字段。
说明:并不是数据库中所有集合都分片,只有设置了shardcollection才分片,因为不是所有的集合都需要分片。
6、测试分片结果。
use mydb for (i =0; i<10000;i++){ db.person.save({id:i, company:"baidu"})}
测试结果如下:发现已经成功分片,rs1和rs2分片不均匀,这和块的大小和片键有关系,有兴趣的小伙伴也可以详细的查阅如何选择片键的文章。
db.person.stats() { "sharded" : true, "capped" : false, "ns" : "mydb.person", "count" : 10000, "size" : 530000, "storageSize" : 192512, "totalIndexSize" : 311296, "nchunks" : 3, "shards" : { "rs1" : { "ns" : "mydb.person", "count" : 9999, "size" : 529947, "avgObjSize" : 53, "totalIndexSize" : 278528, "ok" : 1 }, "rs2" : { "ns" : "mydb.person", "count" : 1, "size" : 53, "avgObjSize" : 53, "storageSize" : 16384, "ok" : 1 } }, "ok" : 1 }
至此。