Docker Swarm para orquestación de contenedores

Publicado: 2019-08-08

Todo sobre Docker Swarm y cómo administra y orquesta todos los contenedores en un clúster.

¿Qué es Docker Swarm?

Docker Swarm es un modo de manejar un grupo de Docker Engines, de ahí el nombre Swarm. El clúster de hosts de Docker se ejecuta en modo de enjambre y consta de administradores y trabajadores. Las instancias del motor acoplable que participan en el enjambre se denominan nodos.

Una implementación de enjambre de nivel de producción consta de nodos acoplables repartidos en varios servidores.

¿Por qué usarlo? – Orquestación de contenedores

Cuando trabaja en un entorno de producción, cientos de contenedores docker ejecutarán múltiples aplicaciones en él. Administrar todos estos contenedores puede ser un gran dolor para todos los ingenieros de DevOps; aquí es donde Docker Swarm te ayuda. Administra y organiza 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 no ofrecer tiempo de inactividad ni interrupción.
  • Equilibrio de carga: asigne los recursos y las solicitudes en otros nodos del clúster automáticamente si algún nodo falla.
  • Descentralizado: varios nodos de gestión se ejecutan en un entorno de producción; por lo tanto, el clúster nunca depende de un único nodo administrador.
  • Escalabilidad: con un único comando Docker Swarm, puede ampliar o reducir fácilmente los contenedores en el clúster.

Orquestar contenedores Docker

Ahora que conoce los conceptos básicos 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:

 manager1: 192.168.56.104 worker1: 192.168.56.105 worker2: 192.168.56.102

Para inicializar el modo de enjambre en la ventana acoplable, ejecute el siguiente comando en el nodo del administrador. La bandera --advertise-addr se usa 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. Copie el comando con el token generado y ejecútelo en los nodos trabajadores.

Ejecutando el token en el nodo trabajador1.

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

 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 administrador, puede verificar 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 la imagen acoplable geekflare_mongodb que usamos en el Tutorial de Dockerfile.

 docker build -t geekflare_mongodb .

Ejecute un contenedor de la imagen acoplable de MongoDB creando un servicio de enjambre. 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 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

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 REPLICAS 1/1 significa que solo se está ejecutando un servicio de enjambre actualmente.

 geekflare@manager1:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS kok58xa4zi05 Mongo-Container replicated 1/1 geekflare_mongodb:latest *:27017->27017/tcp

Verifiquemos 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 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 ejecuta 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

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

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

Inicie el servicio de enjambre dentro de un contenedor docker en modo global usando el indicador de modo.

 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 tres nodos (1 administrador, 2 trabajadores) se ejecutan en el clúster, es por eso que la cantidad 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

3 servicios se están ejecutando ahora en 3 nodos, verifíquelo 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, déjame mostrarte cómo puedes definir el número de réplicas. Antes de eso, eliminaré el contenedor actual, que se está ejecutando.

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

Use el indicador –replicas en el comando y mencione la cantidad 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 de 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 trabajador1 y verifique si el contenedor acoplable está ejecutando el servicio de enjambre.

 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 verifica qué nodos están ejecutando el servicio, verá que se está ejecutando en el nodo manager1 y en el nodo trabajador2. El ESTADO ACTUAL del nodo trabajador1 es Apagado (ya que detuvimos el contenedor que ejecuta el servicio). Pero dado que se deben ejecutar dos réplicas de este servicio, se inició otro servicio en el trabajador 2.

Así es como se logra una alta disponibilidad mediante 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 escalar hacia arriba o hacia abajo los 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án ejecutando ahora, deben 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 está ejecutando en el nodo manager1 y 2 réplicas en ambos nodos de trabajo cada uno.

 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 su clúster, si no desea que sus servicios se ejecuten en los nodos del administrador y desea conservarlos solo para administrar los nodos, puede drenar el nodo del administrador.

 geekflare@manager1:~$ docker node update --availability drain manager1 manager1

Verifique la disponibilidad del nodo administrador.

 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á que los servicios ya no se ejecutan en el nodo del administrador; se distribuyen entre 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 sobre Docker Swarm y cómo orquestar contenedores en modo docker swarm. Pruébelos en su entorno de no producción para tener una idea de cómo funciona.