En esta ocasión vamos a crear un cluster de MongoDB con 3 notos, activaremos la autenticación y persistencia de los datos en el siste de archivos local y por último insertaremos un registro en el nodo principal y lo leeremos en uno de los nosos secundarios.
Lo primero que tenemos que tener son 3 máquinas, puede ver nuestro artículo Administrando hosts con docker-machine para ver como crear esas máquinas en local.
Inicamos veririfcando que tenemos las máquinas ejecutándose:
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
machine1 - virtualbox Running tcp://192.168.99.101:2376 v1.11.1
machine2 - virtualbox Running tcp://192.168.99.102:2376 v1.11.1
machine3 * virtualbox Running tcp://192.168.99.103:2376 v1.11.1
Crearemos un archivo clave que será usado en todos los nodos.
Tendremos que acceder a una de las máquinas y crear el archivo:
$ docker-machine ssh machine1
$ mkdir /home/core -p
$ cd /home/core
$ openssl rand -base64 741 > mongodb-keyfile
$ chmod 600 mongodb-keyfile
$ sudo chown 999 mongodb-keyfile
Ahora copiaremos en los otros 2 servidores en la misma ubicación:
$ docker-machine scp -r machine1:/home/core machine2:/home/
$ docker-machine scp -r machine1:/home/core machine3:/home/
Ahora debemos cambiar de propietario a los 3 archivos al id de usuario 999 porque dentro del contenedor del MongoDB es el único que tiene acceso al keyfile:
$ docker-machine ssh machine1 sudo chown 999 /home/core/mongodb-keyfile
$ docker-machine ssh machine2 sudo chown 999 /home/core/mongodb-keyfile
$ docker-machine ssh machine3 sudo chown 999 /home/core/mongodb-keyfile
En la primera máquina vamos a ejecutar el contenedor de MongoDB sin autenticación:
$ eval $(docker-machine env machine1)
$ docker run --name mongo -v /home/core/mongo-files/data:/data/db -v /home/core/mongo-files:/opt/keyfile --hostname=2machine1.example.com" -p 27017:27017 -d mongo:2.6.5 --smallfiles
Para crear el usuario admin, nos conectaremos al contenedor y en shell:
$ docker exec -it mongo /bin/bash
Crearemos un usuario admin.
$ mongo
Which will start the 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
>
Cambiamos al usuario admin:
> use admin
Crear el nuevo usuario para la base de datos admin:
> db.createUser( {
user: "siteUserAdmin",
pwd: "password",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
});
Debería ver un mensaje de confirmación:
Successfully added user: {
"user" : "siteUserAdmin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
Creamos el usuario root:
> db.createUser( {
user: "siteRootAdmin",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
});
El mensaje de creación sería algo así:
Successfully added user: {
"user" : "siteRootAdmin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
Utilizaremos estos usuarios más adeante para usar el log. Ahora salimos del shell de mongo y de docker:
> exit
bye
$ exit
Detemos el contenedor de mongo
$ docker stop mongo
Ahora ejecutamos otra vez la instancia de mongo pero ahora indicandole el keyfile (seguimos en la máquina 1):
$ docker rm mongo
$ docker run --name mongo -v /home/core/mongo-files/data:/data/db -v /home/core:/opt/keyfile --hostname="machine1.example.com" --add-host machine1.example.com:$(docker-machine ip machine1) --add-host machine2.example.com:$(docker-machine ip machine2) --add-host machine3.example.com:$(docker-machine ip machine3) -p 27017:27017 -d mongo:2.6.5 --smallfiles --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"
Nota que agregamos 3 –add-host por cada una de las máquinas.
Nos conectaremos al contenedor de mongo, nos autenticaremos e iniciaremos la réplica:
$ docker exec -it mongo /bin/bash
root@machine1:/# mongo
MongoDB shell version: 2.6.5
>
Cambiamos al usuario admin:
> use admin
Ahora debemos autenticarnos con la contraseña password con la que le creamos:
> db.auth("siteRootAdmin", "password");
1
Inicializamos la réplica:
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "machine1.example.com:27017",
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
>
Revisamos la configuración:
> rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 1,r
"members" : [
{
"_id" : 0,
"host" : "machine1.example.com:27017"
}
]
}
Ahora ejecutaremos 2 contenedores más, uno en cada una de las otras dos máquinas:
$ eval $(docker-machine env machine2)
$ docker run --name mongo -v /home/core/mongo-files/data:/data/db -v /home/core:/opt/keyfile --hostname="machine2.example.com" --add-host machine1.example.com:$(docker-machine ip machine1) --add-host machine2.example.com:$(docker-machine ip machine2) --add-host machine3.example.com:$(docker-machine ip machine3) -p 27017:27017 -d mongo:2.6.5 --smallfiles --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"
$ eval $(docker-machine env machine3)
$ docker run --name mongo -v /home/core/mongo-files/data:/data/db -v /home/core:/opt/keyfile --hostname="machine3.example.com" --add-host machine1.example.com:$(docker-machine ip machine1) --add-host machine2.example.com:$(docker-machine ip machine2) --add-host machine3.example.com:$(docker-machine ip machine3) -p 27017:27017 -d mongo:2.6.5 --smallfiles --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"
Debemos añadir los otros 2 nodos dentro de la réplica. Regresamos a la machine y en el mongo shell el prompt habrá cambiado a rs0:PRIMARY>. Esto quiere decir que es el nodo primario para la réplica rs0.
$ eval $(docker-machine env machine1)
$ docker exec -ti mongo /bin/bash
root@machine1:/# mongo
MongoDB shell version: 2.6.5
connecting to: test
rs0:PRIMARY>
rs0:PRIMARY> use admin
rs0:PRIMARY> db.auth("siteRootAdmin", "password");
1
rs0:PRIMARY> rs.add("machine2.example.com")
{ "ok" : 1 }
rs0:PRIMARY> rs.add("machine3.example.com")
{ "ok" : 1 }
Puede ver el estado de los servicios usando rs.status()
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2016-05-27T18:50:14Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "machine1.example.com:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 10392,
"optime" : Timestamp(1464374856, 1),
"optimeDate" : ISODate("2016-05-27T18:47:36Z"),
"electionTime" : Timestamp(1464364704, 2),
"electionDate" : ISODate("2016-05-27T15:58:24Z"),
"self" : true
},
{
"_id" : 1,
"name" : "machine2.example.com:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 161,
"optime" : Timestamp(1464374856, 1),
"optimeDate" : ISODate("2016-05-27T18:47:36Z"),
"lastHeartbeat" : ISODate("2016-05-27T18:50:13Z"),
"lastHeartbeatRecv" : ISODate("2016-05-27T18:50:14Z"),
"pingMs" : 0,
"syncingTo" : "machine1.example.com:27017"
},
{
"_id" : 2,
"name" : "machine3.example.com:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 158,
"optime" : Timestamp(1464374856, 1),
"optimeDate" : ISODate("2016-05-27T18:47:36Z"),
"lastHeartbeat" : ISODate("2016-05-27T18:50:14Z"),
"lastHeartbeatRecv" : ISODate("2016-05-27T18:50:13Z"),
"pingMs" : 0,
"syncingTo" : "machine1.example.com:27017"
}
],
"ok" : 1
}
Vamos a insertar un registro para luego leerlo en los otros nodos. Primero lo insertamos:
$ eval $(docker-machine env machine1)
$ docker exec -ti mongo /bin/bash
$ mongo
.
.
.
rs0:PRIMARY> db.auth("siteRootAdmin", "password");
1
rs0:PRIMARY> db.products.insert( { item: "card", qty: 15 } )
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.products.find()
{ "_id" : ObjectId("57489fd2ae8da148587ce2ba"), "item" : "card", "qty" : 15 }
rs0:PRIMARY> exit
Ahora lo leemos el valor en la machine2:
$ eval $(docker-machine env machine2)
$ docker exec -ti mongo /bin/bash
$ mongo
.
.
.
rs0:SECONDARY> db.auth("siteRootAdmin", "password");
1
rs0:SECONDARY> db.auth("siteRootAdmin", "password");
1
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> { "_id" : ObjectId("57489fd2ae8da148587ce2ba"), "item" : "card", "qty" : 15 }
rs0:SECONDARY> exit
Eso es todo, hemos creado un cluster en 3 máquinas con un contenedor MongoDB y lo hemos probado creando un registro en la máquina principal y leyendo en la secundaria.
Comentarios recientes