MongoDB con Docker Swarm

A webpage to check questions and latest deployments for linux in the cloud.

MongoDB con Docker Swarm

Un Swarm es un grupo de máquinas que ejecuta Docker y se se unen a un clúster. Después de que eso ocurra, continuará ejecutando los comandos Docker a los que está acostumbrado, pero ahora los ejecuta un administrador de Swarm en un clúster. Las máquinas en un Swarm pueden ser físicas o virtuales. Después de unirse a un enjambre, se les conoce como nodos.

Los administradores de Swarm pueden usar varias estrategias para manejar contenedores, como el “nodo más vacío”, que llena las máquinas menos utilizadas con contenedores. O “global”, que garantiza que cada máquina obtenga exactamente una instancia del contenedor especificado. Le indica al administrador de swarm que use estas estrategias en el archivo Compose.

Los administradores de swarm son las únicas máquinas en un swarm que pueden ejecutar sus comandos, o autorizar a otras máquinas a unirse al swarm como trabajadores “workers”. Los workers están allí para proporcionar capacidad y no tienen la autoridad para decirle a cualquier otra máquina lo que puede o no puede hacer.

MongoDB es una base de datos distribuida en su núcleo, por lo que la alta disponibilidad, la escala horizontal y la distribución geográfica están integradas y son fáciles de usar

MongoDB almacena datos en documentos flexibles, similares a JSON, lo que significa que los campos pueden variar de un documento a otro y la estructura de datos se puede cambiar con el tiempo.

El modelo de documento se correlaciona con los objetos en el código de la aplicación, facilitando el trabajo de los datos

Las consultas ad hoc, la indexación y la agregación en tiempo real proporcionan formas poderosas de acceder y analizar los datos

MongoDB es una base de datos distribuida en su núcleo, por lo que la alta disponibilidad, la escala horizontal y la distribución geográfica están integradas y son fáciles de usar

MongoDB es gratuito y de código abierto, publicado bajo la Licencia Pública General Affero de GNU

Escenario

 

Se realizará la instalación de un replica set de mongo, que a su vez será ejecutado con Docker Swarm, al deployar con docker  swarm, se estará utilizando una funcionalidad nativa de docker.

El método de despliegue será mediante scripting, pero es totalmente viable realizarlo a mano, para lo cual se explicaran cada uno de los comandos del script.

La implementación será realizada con 3 VMs, esto con motivos de tener alta disponibilidad en nuestro cluster de Mongo.

 

Requisitos:

  • 3 VM’s (GCP, AWS, AZURE, Virtualbox, KVM, etc) pero deben de tener conectividad entre ellas.
  • Docker CE o Docker EE 1.13 o superior
  • Particion de +100MB con formato XFS en LVM.
 
En mi caso estaré ocupando 3 VMs con RHEL 7.5 ocupando Docker 18.06.1-ce y virtualizadas sobre KVM
 

Manager: 192.168.122.10

Worker1: 192.168.122.20

Worker2: 192.168.122.30

 
 
Verifica que docker esta instalado en los 3 servidores:
 
#rpm -qa | grep -i docker
 
Las 3 VM’s son alcanzables entre si mismas, por lo cual se tuvo que establecer los puertos que usara docker de la siguiente manera:
 
[manager~]#firewall-cmd --permanent --add-port=2377/tcp 
[manager~]#firewall-cmd --permanent --add-port=7946/tcp 
[manager~]#firewall-cmd --permanent --add-port=7946/udp 
[manager~]#firewall-cmd --reload

Una vez se tenga la comunicacion, se debe verificar que se tenga la particion en donde se alojaran los logs y la base de datos, esta particion debe de ser independiente de la Raiz y debera estar en formato XFS. En mi caso he utilizado 1 particion de 100MB unicamente para propositos del laboratorio.

sdb                                                                     
└─sdb1        LVM2_member       PMaSFv-edzs-Lrz0-RBTr-aTAz-KoD7-EaGuk8  
 └─data-data xfs               97c77a7f-3661-4e31-b339-116dc553d8a1   /mongodata

Sera necesario crear el usuario que tenga acceso a ejecutar comando de docker:

[manager~]#useradd deployer
[manager~]#passwd deployer

Y se le dara acceso a ejecucion de comandos de Docker:

[manager~]#usermod -aG docker deployer 

 

Agrega al /etc/hosts los workers para la traduccion de las IP’s:

[manager~]$cat /etc/hosts
192.168.122.10 mongo1
192.168.122.20 mongo2
192.168.122.30 mongo3

 

Deploy

 
Una vez se tengan las VM’s con docker 1.13 o superior, la particion $DATA que en mi caso esta en /mongodata la cual deberia de estar en formato XFS y que a su vez deberia de estar dentro del archivo /etc/fstab, se procedera a crear los siguientes archivos en los 3 NODOS:

[manager~]$mkdir -p /mongodata/log/mongodb
[manager~]$mkdir -p /mongodata/mongodb/db
 
[manager~]$echo "* soft nofile 64000
 * hard nofile 64000
 * soft nproc 32000
 * hard nproc 32000" >> /mongodata/mongodb/limits.conf
 
[manager~]$echo "* soft nproc 32000
* hard nproc 32000" >> /mongodata/mongodb/90-nproc.conf
 
[manager~]$chown -R deployer:deployer /mongodata/

 

See procedera a ejecutar el inicio del docker swarm en el MASTER Node, en caso de tener multiples IPs se seleccionara la IP por donde se desea establecer la comunicacion entre los nodos:

[manager~]$docker swarm init --advertise-addr 192.168.122.10

 

Automaticamente generara una salida en la cual mostrara el comando a ejecutar en los workers nodes, para que estos se puedan unir al Swarm de docker.

 

docker swarm join --token SWMTKN-1-2l0777kyrpuhtkmqq7i85ybsslwj7z0tiaqmez7yf7lvy-445olupftln2us40xpasrlqr5 192.168.122.10:2377

 

Una vez que los workers se han unido, obtendras un mensaje como el siguiente:

  This node joined a swarm as a worker.

Hasta este momento se tienen los 3 nodos en comunicacion, ahora se procedera con la instalacion de MongoDB como Swarm container

Se crearan los siguientes archivos de configuracion, que a su vez deben estar almacenados en la ruta /mongodata/mongodb/ y deben de estar en los 3 nodos

mongod.conf

storage:
   dbPath: "/mongodata/mongodb/db"
   journal:
     enabled: true
   engine: "wiredTiger"
   wiredTiger:
     engineConfig:
        cacheSizeGB: 8
     collectionConfig:
        blockCompressor: snappy
systemLog:
     destination: file
     logAppend: true
     logRotate: reopen
     path: /var/log/mongodb/mongod.log
     timeStampFormat: iso8601-utc
processManagement:
     fork: false
net:
     bindIp: 0.0.0.0
     port: 27017
replication:
  replSetName: MongoSwarm

Yaml File

A continuacion procederemos a crear el archvo yaml, con el cual se configuraran los containers que estaran ejecutando mongodb, el archivo mongoswarm.yml solo debe de existir en el master node. 
version "3.6"
services:     mongo1:         image: mongo:3.6         deploy:             placement:                 constraints: [node.hostname == manager]             restart_policy:                 condition: on-failure         volumes:             - /mongodata/mongodb/db:/mongodata/mongodb/db             - /mongodata/log/mongodb:/var/log/mongodb             - /mongodata/mongodb/mongod.conf:/etc/mongod.conf             - /mongodata/mongodb/limits.conf:/etc/security/limits.conf             - /mongodata/mongodb/90-nproc.conf:/etc/security/limits.d/90-nproc.conf         hostname: mongo1         networks:             - mongoshard           command: ["/usr/bin/mongod", "-f", "/etc/mongod.conf"]         ports:             - mode: host               target: 27017               published: 27017     mongo2:         image: mongo:3.6         deploy:             placement:                 constraints: [node.hostname == worker1]             restart_policy:                 condition: on-failure         volumes:             - /mongodata/mongodb/db:/mongodata/mongodb/db             - /mongodata/log/mongodb:/var/log/mongodb             - /mongodata/mongodb/mongod.conf:/etc/mongod.conf             - /mongodata/mongodb/limits.conf:/etc/security/limits.conf             - /mongodata/mongodb/90-nproc.conf:/etc/security/limits.d/90-nproc.conf         hostname: mongo2         networks:             - mongoshard         command: ["/usr/bin/mongod","-f","/etc/mongod.conf"]         ports:             - mode: host               target: 27017               published: 27017     mongo3:         image: mongo:3.6         deploy:             placement:                 constraints: [node.hostname == worker2]             restart_policy:                 condition: on-failure         volumes:             - /mongodata/mongodb/db:/mongodata/mongodb/db             - /mongodata/log/mongodb:/var/log/mongodb             - /mongodata/mongodb/mongod.conf:/etc/mongod.conf             - /mongodata/mongodb/limits.conf:/etc/security/limits.conf             - /mongodata/mongodb/90-nproc.conf:/etc/security/limits.d/90-nproc.conf         hostname: mongo3         networks:             - mongoshard         command: ["/usr/bin/mongod","-f","/etc/mongod.conf"]         ports:             - mode: host               target: 27017               published: 27017 networks:     mongoshard:         external: true

Sera necesario crear la red mongoshard para que se pueda establecer la comunicacion interna entre los contenedores que pertenecen al Swarm:

[manager~]$docker network create --driver overlay --attachable mongoshard 

Finalmente se ejecutara el docker stack deploy unicamente en el master para crear los contenedores, descargar la imagen de mongo en su version 3.6 y la conexion entre los contenedores:

[manager~]$docker stack deploy  -c /mongodata/mongodb/mongoswarm.yml mongoswarm

 

Para verificar que se han ejecutado los contenedores se puede ejecutar el siguiente comando:

[manager~]$docker stack ps mongoswarm

 

Finalmente para crear el replica set se ejecutara el siguiente comando:

[manager~]$docker exec -it $(docker ps -qf label=com.docker.stack.namespace=mongoswarm) mongo --eval 'rs.initiate({ _id: "MongoSwarm", members: [{ _id: 0, host: "mongo1:27017" }, { _id: 1, host: "mongo2:27017" }, { _id: 2, host: "mongo3:27017"}], settings: { getLastErrorDefaults: { w: "majority", wtimeout: 5000 }}})'
 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Translate »