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 de 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 en él. La gestión de todos estos contenedores puede ser un gran dolor para todos los ingenieros DevOps; aquí es donde Docker Swarm le ayuda. Gestiona y orquesta el clúster que ejecuta múltiples contenedores docker con facilidad.

A continuación se presentan algunas de sus características:

  • Alta disponibilidad – tiene como objetivo ofrecer ningún tiempo de inactividad o interrupción.
  • Equilibrio de la carga – asigna los recursos y las solicitudes en otros nodos del clúster automáticamente si falla algún nodo.
  • Descentralizado – en un entorno de producción se ejecutan varios nodos gestores, por lo que el clúster nunca depende de un único nodo gestor.
  • Escalabilidad – utilizando un único comando docker swarm, puede ampliar o reducir fácilmente los contenedores del clúster.

Orquestación de contenedores Docker

Ahora que conoce los fundamentos de Docker Swarm veamos un ejemplo de su implementación.

En este ejemplo, tengo tres máquinas ejecutándose en un clúster con los siguientes detalles:

gestor1: 192.168.56.104

trabajador1: 192.168.56.105

trabajador2: 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 enjambre.

geekflare@manager1:~$ docker swarm init --advertise-addr 192.168.56.104

Enjambre inicializado: el nodo actual (lssbyfzuiuh3sye1on63eyixf) es ahora un gestor.

Para añadir un trabajador a este enjambre, ejecute el siguiente comando:

docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377

Para añadir un gestor a este enjambre, ejecute 'docker swarm join-token manager' y siga las instrucciones.

El comando anterior generará un token que será utilizado por otros nodos para unirse a este enjambre. Copie el comando con el token generado y ejecútelo 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

Este nodo se unió a un enjambre como trabajador.

Ejecutando el token en el nodo worker2.

geekflare@worker2:~$ docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377

Este nodo se unió a un enjambre como trabajador.

Ahora, en el nodo gestor, puede comprobar qué nodos se están ejecutando en el enjambre.

geekflare@manager1:~$ docker node ls

ID HOSTNAME STATUS DISPONIBILIDAD MANAGER STATUS ENGINE VERSION

lssbyfzuiuh3sye1on63eyixf * manager1 Listo Líder activo 18.09.6

utdr3dnngqf1oy1spupy1qlhu trabajador1 Listo Activo 18.09.6

xs6jqp95lw4cml1i1npygt3cg trabajador2 Listo Activo 18.09.6

Vamos a construir la imagen docker geekflare_mongodb que utilizamos en el Tutorial Dockerfile.

docker build -t geekflare_mongodb .

Ejecute un contenedor de la imagen docker MongoDB creando un servicio swarm. 27017 es el número de puerto en el que se expone MongoDB.

geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 geekflare_mongodb

no se ha podido acceder a la imagen geekflare_mongodb:latest en un registro para anotar su compendio. Cada nodo accederá a geekflare_mongodb:latest de forma independiente, lo que puede dar lugar a que distintos nodos ejecuten versiones diferentes de la imagen.

kok58xa4zi05psh3uy6s5x9e6

progreso general: 1 de 1 tareas

1/1: en marcha

verificar: servicio convergido

Compruebe 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 RÉPLICAS 1/1 significa que sólo se está ejecutando un servicio de enjambre.

geekflare@manager1:~$ docker service ls

ID NOMBRE MODO REPLICAS IMAGEN PUERTOS

kok58xa4zi05 Mongo-Container replicado 1/1 geekflare_mongodb:latest *:27017->27017/tcp

Comprobemos en qué nodo del clúster se está ejecutando este único servicio. Se está ejecutando en el nodo manager1.

geekflare@manager1:~$ docker service ps Mongo-Container

ID NOMBRE IMAGEN NODO ESTADO DESEADO ESTADO ACTUAL ERROR PUERTOS

jgqjo92rbq23 Mongo-Container.1 geekflare_mongodb:latest manager1 En ejecución En ejecución hace aproximadamente un minuto

Ejecute el comando docker ps para obtener más detalles sobre el contenedor que está ejecutando este servicio de enjambre.

geekflare@manager1:~$ docker ps

CONTENEDOR ID IMAGEN COMANDO CREADO ESTADO PUERTOS NOMBRES

05d77e7b4850 geekflare_mongodb:latest "/bin/sh -c usr/bin/..." hace 2 minutos Arriba 2 minutos 27017/tcp Mongo-Container.1.jgqjo92rbq23sv01hrufdigtx

También puede ejecutar el servicio de enjambre en modo » global » en lugar del modo «replicado» predeterminado. 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ítame eliminar el contenedor en ejecución existente.

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

no se ha podido acceder a la imagen geekflare_mongodb:latest en un registro para registrar su compendio. Cada nodo accederá a geekflare_mongodb:latest de forma independiente, lo que puede dar lugar a que distintos nodos ejecuten versiones diferentes de la imagen.

mfw8dp0zylffppkllkcjl8391

progreso general: 3 de 3 tareas

utdr3dnngqf1: en ejecución

lssbyfzuiuh3: en ejecución

xs6jqp95lw4c: en ejecución

verificar: servicio convergente

Compruebe si el servicio de enjambre se ha iniciado en modo global. Dado que en el clúster se están ejecutando tres nodos (1 manager, 2 workers), el número de réplicas es 3.

geekflare@manager1:~$ docker service ls

ID NOMBRE MODO REPLICAS IMAGEN PUERTOS

mfw8dp0zylff Mongo-Container global 3/3 geekflare_mongodb:latest *:27017->27017/tcp

3 servicios se están ejecutando ahora a través de 3 nodos, compruébelo ejecutando el siguiente comando.

geekflare@manager1:~$ docker service ps Mongo-Container

ID NOMBRE IMAGEN NODO ESTADO DESEADO ESTADO ACTUAL ERROR PUERTOS

zj2blvptkvj6 Mongo-Container.xs6jqp95lw4cml1i1npygt3cg geekflare_mongodb:latest worker2 En ejecución En ejecución hace aproximadamente un minuto

3eaweijbbutf Mongo-Container.utdr3dnngqf1oy1spupy1qlhu geekflare_mongodb:latest worker1 En ejecución En ejecución hace aproximadamente un minuto

yejg1o2oyab7 Mongo-Container.lssbyfzuiuh3sye1on63eyixf geekflare_mongodb:latest manager1 En ejecución En ejecución hace aproximadamente un minuto

A continuación, permítame mostrarle cómo puede definir el número de réplicas. Antes de eso, eliminaré el contenedor actual, que está en ejecución.

geekflare@manager1:~$ docker service rm Mongo-Container

Mongo-Container

Utilice la bandera –replicas en el comando y mencione el número de réplicas que desea del servicio swarm. 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

no se ha podido acceder a la imagen geekflare_mongodb:latest en un registro para anotar su compendio. Cada nodo accederá a geekflare_mongodb:latest de forma independiente, lo que puede dar lugar a que distintos nodos ejecuten versiones diferentes de la imagen.

4yfl41n7sfak65p6zqwwjq82c

progreso general: 2 de 2 tareas

1/2: en marcha

2/2: en marcha

verificar: servicio convergente

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 NOMBRE IMAGEN NODO ESTADO DESEADO ESTADO ACTUAL ERROR PUERTOS

xukodj69h79q Mongo-Container.1 geekflare_mongodb:latest worker1 En ejecución En ejecución hace 9 segundos

e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 En ejecución En ejecución hace 9 segundos

Vaya al nodo worker1 y compruebe si el contenedor docker está ejecutando el servicio swarm.

geekflare@worker1:~$ docker ps

CONTENEDOR ID IMAGEN COMANDO CREADO ESTADO PUERTOS NOMBRES

5042b7f161cb geekflare_mongodb:latest "/bin/sh -c usr/bin/..."   Hace aproximadamente un minuto Arriba Hace aproximadamente un minuto 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 comprueba cuales son todos los nodos que están ejecutando el servicio, verá 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 deben ejecutarse dos réplicas de este servicio, se inició otro servicio en el trabajador 2.

Así es como se consigue una alta disponibilidad utilizando docker swarm.

geekflare@manager1:~$ docker service ps Mongo-Container

ID NOMBRE IMAGEN NODO ESTADO DESEADO ESTADO ACTUAL ERROR PUERTOS

cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 En ejecución En ejecución hace 30 segundos

xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Apagado Fallido hace 38 segundos "task: non-zero exit (137)"

e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running Hace 3 minutos

Es muy fácil escalar contenedores docker hacia arriba o hacia abajo. El siguiente comando escalará el contenedor mongo a 5.

geekflare@manager1:~$ docker service scale Mongo-Container=5

Contenedor Mongo escalado a 5

progreso general: 5 de 5 tareas

1/5: en ejecución

2/5: en marcha

3/5: corriendo

4/5: corriendo

5/5: corriendo

verificar: servicio convergente

Compruebe cuántas réplicas del contenedor mongo se están ejecutando ahora, debe ser 5.

geekflare@manager1:~$ docker service ls

ID NOMBRE MODO REPLICAS IMAGEN PUERTOS

4yfl41n7sfak Mongo-Container replicado 5/5 geekflare_mongodb:latest *:27017->27017/tcp

Compruebe dónde se están ejecutando estas 5 réplicas en el clúster. 1 réplica se está ejecutando en el nodo manager1 y 2 réplicas en cada uno de los nodos worker.

geekflare@manager1:~$ docker service ps Mongo-Container

ID NOMBRE IMAGEN NODO ESTADO DESEADO ESTADO ACTUAL ERROR PUERTOS

cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 En ejecución En ejecución hace 2 minutos

xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Apagado Fallido hace 2 minutos "task: non-zero exit (137)"

e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running Hace 5 minutos

qmp0gqr6ilxi Mongo-Container.3 geekflare_mongodb:latest worker2 En ejecución En ejecución hace 47 segundos

9ddrf4tsvnu2 Mongo-Container.4 geekflare_mongodb:latest worker1 En ejecución En ejecución hace 46 segundos

e9dhoud30nlk Mongo-Container.5 geekflare_mongodb:latest worker1 En ejecución En ejecución hace 44 segundos

En su clúster, si no desea que sus servicios se ejecuten en el nodo o nodos gestores y desea mantenerlo sólo para gestionar los nodos, puede 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 DISPONIBILIDAD MANAGER STATUS ENGINE VERSION

lssbyfzuiuh3sye1on63eyixf * manager1 Ready Drain Leader 18.09.6

utdr3dnngqf1oy1spupy1qlhu trabajador1 Listo Activo 18.09.6

xs6jqp95lw4cml1i1npygt3cg worker2 Listo Activo 18.09.6

Verá que los servicios ya no se ejecutan en el nodo gestor; están repartidos por los nodos trabajadores del clúster.

geekflare@manager1:~$ docker service ps Mongo-Container

ID NOMBRE IMAGEN NODO ESTADO DESEADO ESTADO ACTUAL ERROR PUERTOS

cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 En ejecución En ejecución hace 5 minutos

xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Apagado Fallido hace 5 minutos "task: non-zero exit (137)"

qo405dheuutj Mongo-Container.2 geekflare_mongodb:latest worker1 Running Running Hace 41 segundos

e66zllm0foc8 \_ Mongo-Container.2 geekflare_mongodb:latest manager1 Apagado Apagado hace 44 segundos

qmp0gqr6ilxi Mongo-Container.3 geekflare_mongodb:latest worker2 En ejecución En ejecución hace 3 minutos

9ddrf4tsvnu2 Mongo-Container.4 geekflare_mongodb:latest worker1 En ejecución En ejecución hace 3 minutos

e9dhoud30nlk Mongo-Container.5 geekflare_mongodb:latest worker1 En ejecución En ejecución hace 3 minutos

Eso fue todo sobre Docker Swarm y cómo orquestar contenedores en modo docker swarm. Pruebe esto en su entorno de no producción para tener una idea de cómo funciona.