Todo sobre Docker Swarm y cómo gestiona y orquesta todos los contenedores de un clúster.
¿Qué es Docker Swarm?
Docker swarm es un modo de manejar un cluster de motores Docker, de ahí el nombre Swarm. El clúster de hosts Docker se ejecuta en modo enjambre compuesto por gestores y trabajadores. Las instancias de motores Docker que participan en el enjambre se denominan nodos.
Un despliegue en enjambre a nivel de producción consta de nodos Docker repartidos en varios servidores.
¿Por qué utilizarlo? - Orquestación de contenedores
Cuando se trabaja en un entorno de producción, cientos de contenedores Docker estarán ejecutando múltiples aplicaciones. La gestión de todos estos contenedores puede ser un gran dolor para todos los DevOps Aquí es donde Docker Swarm te ayuda. Gestiona y orquesta el clúster que ejecuta múltiples contenedores Docker con facilidad.
A continuación se indican algunas de sus características:
- Alta disponibilidad - pretende no ofrecer tiempos de inactividad ni interrupciones.
- Equilibrio de carga - asignar automáticamente los recursos y peticiones en otros nodos del clúster si falla alguno.
- Descentralizado - varios nodos gestores funcionan en un entorno de producción, por lo que el clúster nunca depende de un único nodo gestor.
- Escalabilidad - con un único comando docker swarm, puede ampliar o reducir fácilmente los contenedores del clúster.
Orquestar contenedores Docker
Ahora que conoces los fundamentos de Docker Swarm veamos un ejemplo de su implementación.
En este ejemplo, tengo tres máquinas funcionando en un cluster con los siguientes detalles:
manager1: 192.168.56.104
worker1: 192.168.56.105
worker2: 192.168.56.102
Para inicializar el modo enjambre en docker, ejecute el siguiente comando en el nodo gestor. La bandera --advertise-addr
se utiliza para anunciarse a los nodos que pueden unirse al clúster.
geekflare@manager1:~$ docker swarm init --advertise-addr 192.168.56.104
Swarm initialized: current node (lssbyfzuiuh3sye1on63eyixf) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
El comando anterior generará un token que será utilizado por otros nodos para unirse a este clúster. Copia el comando con el token generado y ejecútalo en los nodos trabajadores.
Ejecutando el token en el nodo worker1.
geekflare@worker1:~$ docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377
This node joined a swarm as a worker.
Ejecutando el token en el nodo worker2.
geekflare@worker2:~$ docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377
This node joined a swarm as a worker.
Ahora, en el nodo gestor, puede comprobar qué nodos se están ejecutando en el clúster.
geekflare@manager1:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
lssbyfzuiuh3sye1on63eyixf * manager1 Ready Active Leader 18.09.6
utdr3dnngqf1oy1spupy1qlhu worker1 Ready Active 18.09.6
xs6jqp95lw4cml1i1npygt3cg worker2 Ready Active 18.09.6
Construyamos el geekflare_mongodb
que utilizamos en Tutorial de Dockerfile.
docker build -t geekflare_mongodb .
Ejecuta un contenedor de la imagen docker de MongoDB creando un servicio swarm. 27017 es el número de puerto en el que MongoDB está expuesto.
geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 geekflare_mongodb
image geekflare_mongodb:latest could not be accessed on a registry to record its digest. Each node will access geekflare_mongodb:latest independently, possibly leading to different nodes running different versions of the image.
kok58xa4zi05psh3uy6s5x9e6
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
Comprueba si el servicio docker swarm se ha iniciado. MODO replicado significa que el contenedor se ha replicado en todos los nodos del clúster y REPLICAS 1/1 significa que sólo se está ejecutando un servicio de enjambre.
geekflare@manager1:~$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kok58xa4zi05 Mongo-Container replicated 1/1 geekflare_mongodb:latest *:27017->27017/tcp
Comprobemos en qué nodo del cluster se está ejecutando este servicio. Se está ejecutando en el nodo manager1.
geekflare@manager1:~$ docker service ps Mongo-Container
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jgqjo92rbq23 Mongo-Container.1 geekflare_mongodb:latest manager1 Running Running about a minute ago
Ejecute el comando docker ps para obtener más detalles sobre el contenedor que está ejecutando este servicio de enjambre.
geekflare@manager1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05d77e7b4850 geekflare_mongodb:latest "/bin/sh -c usr/bin/…" 2 minutes ago Up 2 minutes 27017/tcp Mongo-Container.1.jgqjo92rbq23sv01hrufdigtx
Puede ejecutar el servicio de enjambre en "global" en lugar del modo "replicado" por defecto. El modo global ejecuta una tarea del servicio de enjambre en todos los nodos del clúster.
Antes de ejecutar el servicio en modo global, permítanme eliminar el contenedor existente en ejecución.
geekflare@manager1:~$ docker service rm Mongo-Container
Mongo-Container
Inicie el servicio swarm dentro de un contenedor docker en modo global utilizando la bandera -mode.
geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 --mode global geekflare_mongodb
image geekflare_mongodb:latest could not be accessed on a registry to record its digest. Each node will access geekflare_mongodb:latest independently, possibly leading to different nodes running different versions of the image.
mfw8dp0zylffppkllkcjl8391
overall progress: 3 out of 3 tasks
utdr3dnngqf1: running
lssbyfzuiuh3: running
xs6jqp95lw4c: running
verify: Service converged
Compruebe si el servicio de enjambre se inició en modo global. Dado que en el clúster se ejecutan tres nodos (1 manager, 2 workers), el número de réplicas es 3.
geekflare@manager1:~$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
mfw8dp0zylff Mongo-Container global 3/3 geekflare_mongodb:latest *:27017->27017/tcp
Ahora se están ejecutando 3 servicios en 3 nodos, compruébelo ejecutando el siguiente comando.
geekflare@manager1:~$ docker service ps Mongo-Container
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zj2blvptkvj6 Mongo-Container.xs6jqp95lw4cml1i1npygt3cg geekflare_mongodb:latest worker2 Running Running about a minute ago
3eaweijbbutf Mongo-Container.utdr3dnngqf1oy1spupy1qlhu geekflare_mongodb:latest worker1 Running Running about a minute ago
yejg1o2oyab7 Mongo-Container.lssbyfzuiuh3sye1on63eyixf geekflare_mongodb:latest manager1 Running Running about a minute ago
A continuación, voy a mostrar cómo se puede definir el número de réplicas. Antes de eso, voy a eliminar el contenedor actual, que se está ejecutando.
geekflare@manager1:~$ docker service rm Mongo-Container
Mongo-Container
Utilice el indicador -replicas en el comando e indique el número de réplicas que desea del servicio de enjambre. Por ejemplo, quiero tener dos réplicas del servicio de enjambre:
geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 --replicas=2 geekflare_mongodb
image geekflare_mongodb:latest could not be accessed on a registry to record its digest. Each node will access geekflare_mongodb:latest independently, possibly leading to different nodes running different versions of the image.
4yfl41n7sfak65p6zqwwjq82c
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service converged
Compruebe los servicios del enjambre que se están ejecutando actualmente. Puede ver que una réplica se está ejecutando en el nodo manager1 y la otra en el nodo worker1.
geekflare@manager1:~$ docker service ps Mongo-Container
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xukodj69h79q Mongo-Container.1 geekflare_mongodb:latest worker1 Running Running 9 seconds ago
e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running 9 seconds ago
Vaya al nodo worker1 y compruebe si el contenedor docker está ejecutando el servicio swarm.
geekflare@worker1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5042b7f161cb geekflare_mongodb:latest "/bin/sh -c usr/bin/…" About a minute ago Up About a minute 27017/tcp Mongo-Container.1.xukodj69h79q3xf0pouwm7bwv
Para detener este contenedor, ejecute el siguiente comando.
geekflare@worker1:~$ docker stop 5042b7f161cb
5042b7f161cb
Ahora desde el nodo manager1 si compruebas que todos los nodos están ejecutando el servicio, verás que se está ejecutando en el nodo manager1 y en el nodo worker2. El ESTADO ACTUAL del nodo worker1 es Apagado (ya que detuvimos el contenedor que ejecuta el servicio). Pero como dos réplicas deben ejecutar este servicio, otro servicio se inició en el trabajador 2.
Así es como se consigue la alta disponibilidad utilizando docker swarm.
geekflare@manager1:~$ docker service ps Mongo-Container
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 Running Running 30 seconds ago
xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Shutdown Failed 38 seconds ago "task: non-zero exit (137)"
e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running 3 minutes ago
Es muy fácil ampliar o reducir contenedores docker. El siguiente comando escalará el contenedor mongo a 5.
geekflare@manager1:~$ docker service scale Mongo-Container=5
Mongo-Container scaled to 5
overall progress: 5 out of 5 tasks
1/5: running
2/5: running
3/5: running
4/5: running
5/5: running
verify: Service converged
Compruebe cuántas réplicas del contenedor mongo se está ejecutando ahora, debe ser 5.
geekflare@manager1:~$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
4yfl41n7sfak Mongo-Container replicated 5/5 geekflare_mongodb:latest *:27017->27017/tcp
Compruebe dónde se ejecutan estas 5 réplicas en el clúster. 1 réplica se ejecuta en el nodo manager1 y 2 réplicas en cada uno de los nodos trabajadores.
geekflare@manager1:~$ docker service ps Mongo-Container
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 Running Running 2 minutes ago
xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Shutdown Failed 2 minutes ago "task: non-zero exit (137)"
e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running 5 minutes ago
qmp0gqr6ilxi Mongo-Container.3 geekflare_mongodb:latest worker2 Running Running 47 seconds ago
9ddrf4tsvnu2 Mongo-Container.4 geekflare_mongodb:latest worker1 Running Running 46 seconds ago
e9dhoud30nlk Mongo-Container.5 geekflare_mongodb:latest worker1 Running Running 44 seconds ago
En tu cluster, si no quieres que tus servicios se ejecuten en el nodo(s) gestor(es), y quieres mantenerlo sólo para gestionar los nodos, puedes vaciar el nodo gestor.
geekflare@manager1:~$ docker node update --availability drain manager1
manager1
Compruebe la disponibilidad del nodo gestor.
geekflare@manager1:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
lssbyfzuiuh3sye1on63eyixf * manager1 Ready Drain Leader 18.09.6
utdr3dnngqf1oy1spupy1qlhu worker1 Ready Active 18.09.6
xs6jqp95lw4cml1i1npygt3cg worker2 Ready Active 18.09.6
Verás que los servicios ya no se ejecutan en el nodo gestor, sino que están repartidos por los nodos trabajadores del clúster.
geekflare@manager1:~$ docker service ps Mongo-Container
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 Running Running 5 minutes ago
xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Shutdown Failed 5 minutes ago "task: non-zero exit (137)"
qo405dheuutj Mongo-Container.2 geekflare_mongodb:latest worker1 Running Running 41 seconds ago
e66zllm0foc8 \_ Mongo-Container.2 geekflare_mongodb:latest manager1 Shutdown Shutdown 44 seconds ago
qmp0gqr6ilxi Mongo-Container.3 geekflare_mongodb:latest worker2 Running Running 3 minutes ago
9ddrf4tsvnu2 Mongo-Container.4 geekflare_mongodb:latest worker1 Running Running 3 minutes ago
e9dhoud30nlk Mongo-Container.5 geekflare_mongodb:latest worker1 Running Running 3 minutes ago
Eso fue todo acerca de Docker Swarm y cómo orquestar contenedores en modo docker swarm. Pruébalo en tu entorno de no producción para hacerte una idea de cómo funciona.