Docker Compose y Docker Swarm: orquestación de contenedores Docker
La plataforma de contenedores Docker permite distribuir aplicaciones en la red a modo de tareas de forma rápida y cómoda y ahorrando recursos. Todo lo que se necesita para ello es Swarm, el administrador de clústeres de Docker que con la denominación de “Swarm Mode” se incluye como función nativa de la Docker engine desde la versión 1.12.0 y con ello forma parte del software nuclear de la plataforma. Docker Swarm permite escalar las aplicaciones basadas en contenedores, gestionándolas en tantas instancias y en tantos nodos de red como se requiera. Si, por el contrario, quieres ejecutar en un clúster una aplicación multicontenedor, conocida también como “stack” (lote), es mejor recurrir a la herramienta Docker Compose. A continuación, te aclaramos los conceptos básicos de la orquestación de Docker con Swarm y Compose así como los pasos para implementarlos según los códigos utilizados de ejemplo.
Docker Swarm
Swarm es un software creado por los programadores de Docker que permite agrupar una serie de hosts de Docker en un clúster y gestionar los clústeres de forma centralizada así como orquestar los contenedores. Aunque hasta la versión 1.11 de Docker había que implementar Swarm como una herramienta aparte, las versiones posteriores de la plataforma de contenedores soportan un modo nativo swarm (también conocido como modo enjambre), por lo que cuando los usuarios instalan el Docker engine, también tienen a su disposición este gestor de clústeres.
Docker Swarm se basa en una arquitectura maestro-esclavo. Cada clúster de Docker está formado al menos por un nodo maestro (también llamado administrador o manager) y tantos nodos esclavos (llamados de trabajo o workers) como sea necesario. Mientras que el maestro de Swarm es responsable de la gestión del clúster y la delegación de tareas, el esclavo se encarga de ejecutar las unidades de trabajo (tasks o tareas). Además, las aplicaciones de contenedores se distribuyen en servicios en las cuentas de Docker elegidas.
En la jerga de Docker, “service” o servicio designa una estructura abstracta con la que se pueden definir aquellas tareas que deben ejecutarse en el clúster. Cada servicio está formado por un conjunto de tareas individuales que se procesan en contenedores independientes en uno de los nodos del clúster. Cuando se crea un servicio, el usuario determina la imagen de contenedor en la que se basa y los comandos que se ejecutan en el contenedor, operándose sobre la base de la imagen. Docker Swarm soporta dos modos de definir servicios swarm: servicios globales o replicados.
- Servicios replicados: se trata de tareas que se ejecutan en un número de réplicas definido por el usuario. A su vez, cada réplica es una instancia del contenedor definido en el servicio. Los servicios replicados se pueden escalar, permitiendo a los usuarios crear réplicas adicionales. Si así se requiere, un servidor web como NGINX se puede escalar en 2, 4 o 100 instancias con una sola línea de comandos.
- Servicios globales: si un servicio se ejecuta en modo global, cada nodo disponible en el clúster inicia una tarea para el servicio correspondiente. Si al clúster se le añade un nodo nuevo, el maestro de Swarm le atribuye una tarea para el servicio global de forma inmediata. Este tipo de servicios se recomienda para las aplicaciones de monitoreo o los programas antivirus.
Uno de los campos en los que se puede aplicar Docker Swarm es el reparto de cargas, pues con el modo enjambre Docker dispone de funciones integradas de balanceo de carga. Si se ejecuta, por ejemplo, un servidor web NGINX con cuatro instancias, Docker distribuye las consultas entrantes de forma inteligente entre las instancias del servidor web disponibles.
Docker Compose
Docker Compose permite definir las aplicaciones multicontenedor, conocidas como stacks, y ejecutarlas en un nodo individual o en un clúster. La herramienta recurre para ello a una consola de línea de comandos con el fin de gestionar el ciclo de vida completo de sus aplicaciones.
En el universo Docker los stacks o lotes son grupos de servicios interconectados que comparten las dependencias del software y que se escalan y orquestan de forma conjunta. Un stack de Docker permite definir las diversas funcionalidades de una aplicación en un archivo central, este es, docker-compose.yml, iniciarlo, ejecutarlo conjuntamente en un sistema de tiempo de ejecución y gestionarlo de forma central.
Dependiendo del sistema operativo en el que se ejecute Docker es posible que haya que instalar Compose por separado. Aunque Docker Compose ya se incluye en la gama de funciones de la plataforma de contenedores si se utiliza la aplicación como instalación de escritorio Docker para Mac o Docker para Windows, habrá que proceder a la instalación manual de la herramienta si se utiliza Docker con Linux o con Windows Server 2016. Asimismo, la toolbox de Docker también está disponible para los sistemas de Mac y Windows.
Instalación de Docker Compose con Linux
En primer lugar hay que abrir la terminal y ejecutar el comando que aparece a continuación para poder descargar del repositorio de GitHub los archivos binarios de Compose:
sudo curl -L https://github.com/docker/compose/releases/download/1.18
.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
Concede a todos los usuarios el derecho de poder ejecutar archivos binarios:
sudo chmod +x /usr/local/bin/docker-compose
Para comprobar si la herramienta se ha instalado correctamente se introduce el comando:
docker-compose -version
Si la instalación se ha ejecutado con éxito recibirás el número de versión de la herramienta en la terminal.
Instalación de Compose con Windows Server 2016 (solo Docker EE for Windows)
Inicia PowerShell como administrador y ejecuta el siguiente comando para descargar los archivos binarios de Compose desde el repositorio GitHub:
Invoke-WebRequest
"https://github.com/docker/compose/releases/download/1.18.0/docker-compose-
Windows-x86_64.exe" -UseBasicParsing -OutFile
$Env:ProgramFiles\docker\docker-compose.exe
Inicia los archivos ejecutables para instalar Docker Compose.
El artículo sobre el ecosistema de Docker ofrece más información sobre las herramientas de Docker como Swarm o Compose.
Tutorial: Docker Swarm y Compose en uso
Para poder operar una app multicontenedor en un clúster con Docker es necesario utilizar un enjambre (traducción de swarm), esto es, un clúster de Docker engine en swarm mode, así como la herramienta de Docker Compose.
En este tutorial se describen en primer lugar los pasos a seguir para poder instalar Docker Swarm. Más adelante se procede a aclarar cómo se crean aplicaciones multicontenedor con Docker Compose y se despliegan en el clúster.
El tutorial de Docker de nuestra Guía Digital presenta los conceptos principales de la plataforma de contenedores y describe paso a paso cómo instalar Docker engine en Linux.
Primera parte: Docker en swarm mode
Con el término enjambre se describe a una cantidad arbitraria de Docker engines en modo swarm. Cada Docker engine funciona en un nodo separado que se integra en un clúster.
Para crear un clúster de Docker hay que seguir tres pasos:
- Preparar los hosts de Docker
- Inicializar Swarm
- Integrar los hosts de Docker en el enjambre
Como alternativa, puede cambiarse el modo de un motor Docker que se encuentre en un entorno local de desarrollo al modo enjambre. Se habla entonces de un enjambre de nodo único.
Paso 1: preparar el Docker host
Para preparar los nodos de Docker se recomienda recurrir a la herramienta de aprovisionamiento Docker machine. Esto facilita la implementación de Docker host, también conocido como dockerized host, un host virtual incluido en el motor de Docker. Con Docker machine puedes preparar las cuentas para tu enjambre en cualquier infraestructura y gestionarlas de forma remota. Son varias las plataformas en la nube, como Amazon Web Services (AWS) o Digital Ocean, que ofrecen plugins de controladores para Docker machine con los que es posible reducir el trabajo ligado al aprovisionamiento de los hosts de Docker a una simple línea de código. Para crear un Docker host (aquí: docker-sandbox) en la infraestructura de Digital Ocean, se puede usar el código que aparece a continuación:
$ docker-machine create --driver digitalocean --digitalocean-access-token xxxxx docker-sandbox
En AWS puedes crear un Docker host con el siguiente comando (aquí: aws-sandbox):
$ docker-machine create --driver amazonec2 --amazonec2-access-key AKI******* --amazonec2-secret-key 8T93C******* aws-sandbox
Los caracteres xxxxx y ****** sirven a modo de marcador para un token de acceso o clave que se genera con una cuenta de usuario en el proveedor correspondiente.
Paso 2: inicializar Swarm
Si ya se ha creado el número pertinente de hosts virtuales para el enjambre, es posible gestionarlos a través de Docker machine y agruparlos en un clúster con Docker Swarm. Accede primero a los nodos que se pretenden usar como swarm maestro. Docker machine proporciona el siguiente comando para construir una conexión encriptada SSH con el Docker Host.
docker-machine ssh MACHINE-NAME
Sustituye el marcador MACHINE-NAME por el nombre del host al que se quiere acceder.
Una vez se establece la conexión con los nodos deseados se puede recurrir al siguiente comando para inicializar el enjambre.
docker swarm init [OPTIONS]
El comando docker swarm init, que puede acompañarse con opciones (véase la documentación de Docker ), define como manager de swarm a los nodos seleccionados y crea dos tokens aleatorios: un token manager y un token de trabajo.
Swarm initialized: current node (1ia0jlt0ylmnfofyfj2n71w0z) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-511cy9taxx5w47n80vopivx6ii6cjpi71vfncqhcfcawxfcb14-6cng4m8lhlrdfuq9jgzznre1p \
10.0.2.15:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Además el comando docker swarm init genera una entrada de terminal que contiene toda la información necesaria para añadir más cuentas a tu enjambre.
Normalmente se usa docker swarm init con el indicador --advertise-addr. Este establece qué dirección IP se debe usar para el acceso API y la red superpuesta. En caso de que la dirección IP no se haya definido de forma explícita, Docker comprueba automáticamente bajo qué dirección IP está disponible el sistema elegido y la selecciona. Si un nodo tiene más de una dirección IP, hay que emplear el indicador correspondiente. A menos que se indique lo contrario, Docker usa el puerto 2377.
Paso 3: integrar los Docker hosts en el enjambre
Tras haber inicializado el enjambre con el nodo seleccionado como swarm manager, se procede a añadir todos los nodos que se requieran como manager o worker. Para ello, se escribe el comando docker swarm join combinado con el token correspondiente.
3.1 Añadir nodos worker: para añadir a tu enjambre un nodo worker hay que acceder a través de docker machine al nodo correspondiente y ejecutar el siguiente comando:
docker swarm join [OPTIONS] HOST:PORT
El indicador –token, que contiene el token de acceso al clúster, es un elemento obligatorio del comando docker swarm join.
docker swarm join \
--token SWMTKN-1-511cy9taxx5w47n80vopivx6ii6cjpi71vfncqhcfcawxfcb14-6cng4m8lhlrdfuq9jgzznre1p \
10.0.2.15:2377
En el ejemplo aquí presentado el comando contiene el token worker generado anteriormente así como la dirección IP bajo la que está disponible el manager swarm. Si no se dispone en ese momento del token correspondiente, se puede conseguir mediante docker swarm join-token worker.
3.2 Añadir nodos master: si se quiere añadir al enjambre un nodo manager adicional, hay que establecer primero el token manager. A continuación se ejecuta el comando docker swarm join-token manager en la cuenta de administrador en la que has inicializado el enjambre y se siguen las instrucciones.
Docker genera un token manager que puede ejecutarse junto al comando docker swarm join y la dirección IP definida en un Docker host para poder integrarlo como manager en el enjambre.
$ sudo docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-511cy9taxx5w47n80vopivx6ii6cjpi71vfncqhcfcawxfcb14-ed2ct6pg5rc6vp8bj46t08d0i \
10.0.2.15:2377
3.3 Vista de todos los nodos del enjambre: ejecutando el comando de administración docker node ls en uno de los nodos manager puedes tener una vista de todos los nodos integrados en el enjambre.
ID HOSTNAME STATUS AVAILABILITY MANAGER
jhy7ur9hvzvwd4o1pl8veqms3 worker2 Ready Active
jukrzzii3azdnub9jia04onc5 worker1 Ready Active
1ia0jlt0ylmnfofyfj2n71w0z * osboxes Ready Active Leader
Los nodos manager se marcan en la vista general como Leader.
Para eliminar un nodo de tu enjambre, se accede al host correspondiente y se ejecuta el comando docker swarm leave. Si se trata de un nodo de un manager swarm hay que forzar la ejecución del comando con el indicador --force.
Segunda parte: ejecutar una app multicontenedor en un clúster
En la primera parte de esta guía se ha explicado cómo preparar Docker hosts con Docker machine y compendiarlos en swarm mode como clúster. Ahora presentamos cómo se pueden definir diferentes servicios como aplicaciones multicontenedor compactas y ejecutarlas en un clúster con ayuda de Docker Compose.
La preparación de aplicaciones multicontenedor en un clúster se consigue en cinco pasos:
- Crear un registro Docker local
- Definir una app multicontenedor como stack
- Probar la app multicontenedor con Docker Compose
- Cargar la imagen en el registro
- Ejecutar un stack en el clúster
Paso 1: iniciar el registro local de Docker como servicio
Dado que un enjambre de Docker lo componen un número determinado de Docker engines, solo es posible operar las aplicaciones en un clúster si todas las Docker engines implicadas tienen acceso a la imagen de la aplicación. Para ello se requiere un servicio central que permita gestionar las imágenes y disponerlas en el clúster, servicio que se conoce como registro.
Una imagen es una representación compacta y ejecutable de una aplicación y contiene, además del código de la aplicación, el conjunto de dependencias (entorno de tiempo de ejecución, bibliotecas, variables de entorno y archivos de configuración) que Docker requiere para ejecutar la aplicación en un contenedor, es decir, cada contenedor se puede entender como la instancia en tiempo de ejecución de una imagen.
1.1 Iniciar registro como servicio en el clúster: para iniciar un registro servidor local en el clúster como servicio se requiere el comando docker service create con el siguiente esquema:
docker service create --name registry --publish 5000:5000 registry:2
El comando ordena a Docker arrancar un servicio denominado registry que escucha en el puerto 5000. El primer valor tras el indicador --publish indica el puerto host, el segundo hace referencia al puerto del contenedor. El servicio se basa en la imagen registry:2, que incluye la implementación del registro HTTP API V2 de Docker y se puede descargar gratuitamente desde Docker Hub.
1.2. Probar el estado del servicio de registro: para ello se usa el comando docker service ls, que muestra una lista de todos los servicios que estén ejecutándose en el clúster de Docker.
$ sudo docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
K2hq2ivnwuq4 registry replicated 1/1 registry:2 *:5000->5000/tcp
1.3. Probar la conexión al registro con cURL: comprueba que puedes acceder a tu registro a través de cURL con el comando:
$ curl http://localhost:5000/v2/
Si el registro funciona como se espera, cURL debería mostrar la siguiente salida en la terminal:
{}
cURL es un programa de línea de comandos con el que acceder a direcciones web y poder descargar o subir archivos. En el proyecto web del software de código abierto curl.haxx.se encuentras más información.
Paso 2: crear una app multicontenedor y definirla como stack
En el siguiente paso se crean todos los archivos que se requieren para la implementación de un stack en un clúster de Docker y se archivan en un directorio conjunto del proyecto.
2.1 Crear una carpeta de proyecto: a continuación hay que crear una carpeta de proyecto y asignarle un nombre, que en este tutorial es stackdemo.
$ mkdir stackdemo
Navega por el directorio del proyecto con:
$ cd stackdemo
El directorio del proyecto sirve para guardar todos los archivos necesarios para gestionar una app multicontenedor. Esta incluye un archivo con el código fuente de la app, un archivo de texto en el que se define el software requerido para que funcione la aplicacion, así como un Dockerfile y un Composefile.
2.2 Crear una app: hay que crear una aplicación Python con el contenido que aparece a continuación y guardarla en el directorio del proyecto con el nombre app.py.
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
El ejemplo app.py muestra una aplicación web sencilla cuya página de inicio muestra el saludo "Hello World!" e incluye el número de veces que se tuvo acceso a la app. Se basa en el framework de código abierto Flask y la base de datos en memoria de código abierto Redis. 2.3 Definir los requisitos: hay que crear un archivo de texto requirements.txt con el siguiente contenido y depositarlo en el directorio del proyecto.
flask
redis
En requirements.txt se define específicamente el software en el que se basa la aplicación.
2.4 Crear un Dockerfile: también se requiere la creación de otro archivo de texto llamado Dockerfile, al que hay que añadir el contenido que aparece a continuación. Una vez creado se guarda en el directorio del proyecto.
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
El Dockerfile contiene todas las instrucciones necesarias para crear la imagen de una aplicación. Por ejemplo, este archivo Docker remite a requirements.txt e indica el software que tiene que instalarse para el funcionamiento de la aplicación. En el ejemplo, el Dockerfile permite crear una imagen de la aplicación web app.py incluyendo todos los requisitos (Flask y Redis).
2. 5 Crear un archivo Compose: hay que crear un archivo de configuración con el siguiente contenido y guardarlo como docker-compose.yml.
version: '3'
services:
web:
image: 127.0.0.1:5000/stackdemo
build: .
ports:
- "8000:8000"
redis:
image: redis:alpine
El fichero docker-compose.yml permite interconectar diversos servicios, ejecutarlos como unidad y gestionarlos de forma centralizada.
El archivo Compose se escribe en YAML, un lenguaje de marcado sencillo, usado principalmente en los archivos de configuración, que sirve para ilustrar datos estructurados. En Docker, docker-compose.yml se utiliza para configurar centralmente los servicios de una aplicación multicontenedor.
En el ejemplo actual se definen dos servicios: un servicio web y un servicio redis.
- Servicio web: la base de un servicio web es una imagen que se crea en la carpeta stackdemo según el archivo Docker que ha creado el usuario.
- Servicio Redis: para el servicio Redis no se usa ninguna imagen. En lugar de ello se accede a una imagen de acceso público (redis:alpine)disponible en Docker hub.
Paso 3: probar la app multicontenedor con Compose
Primero hay que probar la app multicontenedor de forma local ejecutándola en los nodos manager.
3.1 Iniciar app: se puede iniciar un stack con el comando docker-compose up junto con el indicador --d. El indicador activa el “detached mode”, en cuyo caso todos los contenedores se ejecutan en segundo plano. De esta forma la terminal está preparada para la entrada de comandos adicionales.
$ sudo docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use the bundle feature of the Docker experimental build.
More info:
https://docs.docker.com/compose/bundles
Creating network "stackdemo_default" with the default driver
Creating stackdemo_web_1
Creating stackdemo_redis_1
3.2 Probar estatus de Stack: es posible con el comando docker-compose. En la terminal se muestra:
$ sudo docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------
stackdemo_redis_ docker- Up 6379/tcp
1 entrypoint.sh
redis ...
stackdemo_web_1 python app.py Up 0.0.0.0:8000->80
00/tcp
El comando docker-compose ps ofrece una vista general de todos los contenedores que se iniciaron en el marco de la aplicación multicontenedor. En el ejemplo actual la lista agrupa a dos contenedores, uno para servicios redis y otro para servicios web.
3.3. Probar un stack con cURL: prueba tu stack ejecutando el programa de líneas de comandos cURL con la dirección de host local (localhost oder 127.0.0.1)
$ curl http://localhost:8000
Hello World! I have been seen 1 times.
$ curl http://localhost:8000
Hello World! I have been seen 2 times.
$ curl http://localhost:8000
Hello World! I have been seen 3 times.
También es posible acceder a la aplicación web a través del navegador.
3.4 Desconectar la app: si se quiere desconectar el stack, hay que ejecutar el comando docker-compose down con el indicador –volumes.
$ sudo docker-compose down --volumes
Stopping stackdemo_redis_1 ... done
Stopping stackdemo_web_1 ... done
Removing stackdemo_redis_1 ... done
Removing stackdemo_web_1 ... done
Removing network stackdemo_default
Paso 4: cargar la imagen en el registro
Antes de que una aplicación multicontenedor se pueda ejecutar en el clúster, en el registro del servicio deben facilitarse todas las imágenes necesarias para ello. El ejemplo solo incluye la imagen creada por el propio servicio web (la imagen redis está disponible a través de un registro público de Docker Hub).
Con el término “push” se hace referencia en la jerga de Docker a la subida de una imagen creada localmente en un registro central. Para ello Docker Compose crea el comando docker-compose push que debe ejecutarse en el directorio del proyecto.
Todas las imágenes presentadas en docker-compose.yml, que han sido creadas de forma local, se cargan en el registro.
$ sudo docker-compose push
Pushing web (127.0.0.1:5000/stackdemo:latest)...
The push refers to a repository [127.0.0.1:5000/stackdemo]
5b5a49501a76: Pushed
be44185ce609: Pushed
bd7330a79bcf: Pushed
c9fc143a069a: Pushed
011b303988d2: Pushed
latest: digest: sha256:a81840ebf5ac24b42c1c676cbda3b2cb144580ee347c07e1bc80e35e5ca76507 size: 1372
En el ejemplo, docker-compose push carga la imagen del stack stackdemo con la etiqueta latest en el registro local bajo 127.0.0.1:5000.
Paso 5: ejecutar un stack en un clúster
La aplicación multicontenedor se puede ejecutar en el clúster si la imagen del stack está disponible en el servicio de registro local.
5.1 Ejecutar un stack en el clúster: también es posible ejecutar un stack en un clúster con una simple línea de comando. La plataforma de contenedores dispone para ello del comando siguiente:
docker stack deploy [OPTIONS] STACK
En el lugar del marcador STACK se inserta el nombre correspondiente de la imagen del stack que se quiere ejecutar.
A continuación se ejecuta el comando docker stack deploy en un nodo manager del enjambre.
$ sudo docker stack deploy --compose-file docker-compose.yml stackdemo
Ignoring unsupported options: build
Creating network stackdemo_default
Creating service stackdemo_web
Creating service stackdemo_redis
El indicador --compose-file establece la ruta al archivo Compose.
5.2 Acceder al estado del stack: es posible con el siguiente comando.
docker stack services [OPTIONS] STACK
Docker muestra el ID, modos, réplicas, imágenes y puertos de todos los servicios que se están ejecutando en el stack.
$ sudo docker stack services stackdemo
ID NAME MODE REPLICAS IMAGE PORTS
cxyp7srukffy stackdemo_web replicated 1/1 127.0.0.1:5000/stackdemo:latest *:8000->8000/tcp
z0i2rtjbrj9s stackdemo_redis replicated 1/1 redis:alpine
5.3 Probar cURL con la aplicación: para probar la aplicación multicontenedor, accede a esta a través de la dirección de host local en el puerto 8000.
$ curl http://localhost:8000
Hello World! I have been seen 1 times.
$ curl http://localhost:8000
Hello World! I have been seen 2 times.
$ curl http://localhost:8000
Hello World! I have been seen 3 times.
Como alternativa a cURL, también es posible acceder a la aplicación a través del navegador. Para ello es necesario usar la dirección del host local o la dirección de uno de los nodos. Gracias a la red de ruta interna puedes acceder a cualquier nodo del enjambre en el puerto 8000 y dirigirlo a tu aplicación.
5.4 Desconectar el stack: es necesario utilizar docker stack rm con el nombre del stack.
$ docker stack rm stackdemo
Removing service stackdemo_web
Removing service stackdemo_redis
Removing network stackdemo_default
5.5 Desconectar el registro servicio: hay que recurrir al comando docker service rm con el nombre de servicio, en este caso, registry.
$ docker service rm registry
Swarm y Compose amplían la funcionalidad central de la plataforma de contenedores con herramientas que ofrecen la opción de operar una aplicación compleja en sistemas diferenciados con un trabajo de gestión reducido. La empresa líder de mercado en el ámbito de la virtualización de contenedores ofrece a los usuarios una solución completa para orquestarlos. Ambas herramientas se basan en una documentación de calidad y se actualizan regularmente. Se puede afirmar, por tanto, que Docker Compose y Docker Swarm pueden considerarse una alternativa adecuada a las herramientas de proveedores como Kubernetes o Panamax.