tutoriales.com

Orquestación de Contenedores Docker con Docker Swarm: Escalabilidad y Alta Disponibilidad

Este tutorial te guiará a través de la orquestación de contenedores Docker utilizando Docker Swarm. Aprenderás a configurar un clúster, desplegar servicios, escalar aplicaciones y asegurar la alta disponibilidad de tus cargas de trabajo.

Intermedio25 min de lectura8 views
Reportar error

🚀 Introducción a Docker Swarm

En el mundo de los contenedores, Docker ha revolucionado la forma en que empaquetamos y desplegamos aplicaciones. Sin embargo, cuando se trata de gestionar múltiples contenedores distribuidos en varios nodos de un clúster, la complejidad aumenta. Aquí es donde entra en juego la orquestación de contenedores, y Docker Swarm es la solución nativa de Docker para este desafío.

Docker Swarm transforma un grupo de hosts Docker en un único "virtual" host Docker, permitiendo desplegar y gestionar aplicaciones en un clúster de manera sencilla y eficiente. Es una herramienta poderosa para lograr escalabilidad, alta disponibilidad y una gestión centralizada de tus servicios contenerizados.

📌 Nota: Aunque Kubernetes es el orquestador más popular en la actualidad, Docker Swarm sigue siendo una excelente opción por su facilidad de uso, integración nativa con Docker y menor curva de aprendizaje, especialmente para proyectos más pequeños o para quienes ya están familiarizados con el ecosistema Docker.

¿Por qué necesitas Docker Swarm?

Imagina que tienes una aplicación web en un único contenedor. ¿Qué pasa si la demanda aumenta? ¿O si el servidor donde reside ese contenedor falla? Sin un orquestador, tu aplicación podría sufrir caídas o rendimientos deficientes. Docker Swarm resuelve esto:

  • Escalabilidad: Permite ejecutar múltiples instancias de tu aplicación distribuidas en diferentes máquinas, aumentando la capacidad de respuesta ante picos de demanda.
  • Alta Disponibilidad: Si un nodo o contenedor falla, Swarm puede automáticamente redistribuir la carga y reiniciar los servicios en otros nodos saludables, minimizando el tiempo de inactividad.
  • Balanceo de Carga: Distribuye el tráfico de red entre las instancias de tu servicio de manera uniforme.
  • Autodescubrimiento de Servicios: Los servicios pueden encontrarse y comunicarse entre sí fácilmente dentro del clúster.
  • Actualizaciones Continuas (Rolling Updates): Permite actualizar tu aplicación sin tiempo de inactividad, reemplazando las versiones antiguas por las nuevas de forma gradual.
  • Gestión Centralizada: Define tu infraestructura como código (Infrastructure as Code) utilizando archivos docker-compose.yml extendidos para Swarm (conocidos como stack files).

🛠️ Conceptos Clave de Docker Swarm

Antes de sumergirnos en la práctica, es fundamental comprender la terminología de Docker Swarm.

Nodos (Nodes)

Un nodo es una instancia de Docker Engine participando en el clúster Swarm. Existen dos tipos de nodos:

  • Manager Nodes (Nodos Gestores): Son los cerebros del clúster. Mantienen el estado del Swarm, programan las tareas, gestionan los servicios y manejan la comunicación entre nodos. Para alta disponibilidad, se recomienda tener al menos tres nodos gestores en un entorno de producción (número impar para evitar problemas de split-brain).
  • Worker Nodes (Nodos Trabajadores): Ejecutan las tareas y servicios asignados por los nodos gestores. No tienen la capacidad de tomar decisiones sobre el clúster, solo ejecutan las instrucciones. Un clúster puede tener cero o más nodos trabajadores.

Servicios (Services)

Un servicio es la definición de la tarea que quieres ejecutar en el clúster Swarm. Un servicio define qué imagen de Docker usar, cuántas réplicas se deben ejecutar, qué puertos exponer, qué volúmenes montar, etc. Es una descripción de tu aplicación en el clúster. Por ejemplo, un servicio puede ser una base de datos MySQL, una aplicación web Nginx o un microservicio backend.

Tareas (Tasks)

Una tarea es la unidad de trabajo más pequeña en Swarm. Cuando se despliega un servicio, el nodo gestor crea tareas para ese servicio. Cada tarea corresponde a una instancia de contenedor y se asigna a un nodo trabajador para su ejecución. Si una tarea falla, Swarm puede crear una nueva tarea para reemplazarla y asignarla a otro nodo.

Stack (Pila)

Un stack es un grupo de servicios relacionados que forman una aplicación completa, definidos en un único archivo docker-compose.yml. Desplegar un stack permite lanzar toda tu aplicación multi-servicio con un solo comando.

Manager Node Worker Node 1 Contenedor: Web API Contenedor: Redis Contenedor: Proxy Worker Node 2 Contenedor: DB Worker Contenedor: App Task
💡 Consejo: Es crucial que todos tus nodos tengan conectividad de red entre sí para que Swarm funcione correctamente.

⚙️ Configuración del Entorno: Preparando tus Nodos

Para este tutorial, necesitaremos al menos dos máquinas virtuales o servidores que puedan comunicarse entre sí. Un nodo actuará como gestor y el otro como trabajador. Puedes usar máquinas virtuales en tu máquina local (con VirtualBox, VMware) o instancias en la nube (AWS EC2, Google Cloud, Azure, DigitalOcean).

Requisitos Previos en cada máquina:

  1. Docker Engine instalado: Asegúrate de tener Docker instalado en cada máquina.
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
Verifica la instalación:
docker --version
  1. Firewall configurado: Abre los puertos necesarios en cada nodo. Estos puertos son esenciales para la comunicación de Swarm:

    • 2377/TCP: Puerto de comunicación para los nodos gestores (gestión del clúster).
    • 7946/TCP y 7946/UDP: Puertos para la comunicación entre nodos (intercambio de información de estado).
    • 4789/UDP: Puerto para el overlay network (red de superposición para los contenedores).

    Ejemplo para UFW (Ubuntu/Debian):

sudo ufw allow 2377/tcp
sudo ufw allow 7946/tcp
sudo ufw allow 7946/udp
sudo ufw allow 4789/udp
sudo ufw enable

Paso 1: Inicializar el Clúster Swarm (en el Manager)

El primer paso es inicializar el Swarm en el nodo que designarás como gestor. Abre una terminal en tu nodo gestor y ejecuta:

 docker swarm init --advertise-addr <IP_DEL_MANAGER>

Sustituye <IP_DEL_MANAGER> por la dirección IP privada de tu nodo gestor. Por ejemplo, 192.168.1.100.

Al ejecutar este comando, Docker inicializará el Swarm y te proporcionará un comando docker swarm join con un token. Este comando es crucial para unir otros nodos al clúster. Guárdalo bien.

Ejemplo de salida:

Swarm initialized: current node (xxxxxxxxxxxx) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-xxxxxxxxxxxx-xxxxxxxxxxxx <IP_DEL_MANAGER>:2377

To add a manager to this swarm, run 'docker swarm join --token SWMTKN-1-xxxxxxxxxxxx-xxxxxxxxxxxx <IP_DEL_MANAGER>:2377' (with the --listen-addr flag if you want it to listen on a different address)

Paso 2: Unir Nodos Trabajadores al Clúster (en los Workers)

Ahora, en cada uno de tus nodos trabajadores, ejecuta el comando docker swarm join que obtuviste en el paso anterior. Asegúrate de usar el token y la IP correcta del gestor.

docker swarm join --token SWMTKN-1-xxxxxxxxxxxx-xxxxxxxxxxxx <IP_DEL_MANAGER>:2377

Verás un mensaje como este:

This node joined a swarm as a worker.

Paso 3: Verificar el Clúster Swarm (en el Manager)

Desde el nodo gestor, puedes verificar el estado de tu clúster y los nodos unidos:

 docker node ls

Deberías ver una salida similar a esta, mostrando tanto el nodo gestor como los trabajadores:

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
xxxxxxxxxxxx                  manager-node        Ready               Active              Leader              20.10.12
yyyyyyyyyyyy                  worker-node-1       Ready               Active              
20.10.12

¡Felicidades! Ya tienes un clúster Docker Swarm funcional.


🚀 Despliegue de Servicios en Docker Swarm

Ahora que el clúster está configurado, vamos a desplegar una aplicación simple. Usaremos un ejemplo de una aplicación web Nginx.

Paso 1: Desplegar un Servicio Simple

Desde el nodo gestor, podemos crear un servicio. Un servicio define la imagen que se usará, la cantidad de réplicas, los puertos, etc.

docker service create --name webserver --publish published=80,target=80 --replicas 3 nginx:latest

Explicación del comando:

  • docker service create: Crea un nuevo servicio.
  • --name webserver: Asigna el nombre webserver al servicio.
  • --publish published=80,target=80: Mapea el puerto 80 del host (published) al puerto 80 del contenedor (target). Swarm se encargará de balancear la carga entre las réplicas.
  • --replicas 3: Indica que queremos 3 instancias (réplicas) de este servicio.
  • nginx:latest: La imagen Docker a utilizar.

Paso 2: Verificar el Servicio

Para ver el estado de tu servicio, ejecuta:

 docker service ls

Deberías ver algo como esto:

ID             NAME        MODE         REPLICAS    IMAGE           PORTS
xxxxxxxxxxxx   webserver   replicated   3/3         nginx:latest    *:80->80/tcp

También puedes inspeccionar el servicio en detalle y ver qué tareas se están ejecutando y en qué nodos:

docker service ps webserver

Esto mostrará cada réplica del servicio y en qué nodo está ejecutándose. Podrías ver que las 3 réplicas están distribuidas entre el nodo gestor y el nodo trabajador, o todas en un solo nodo si tienes pocos nodos y Swarm decide que es lo más óptimo por el momento.

Paso 3: Acceder a la Aplicación

Ahora puedes acceder a la aplicación Nginx desde cualquier navegador utilizando la dirección IP de cualquiera de tus nodos (gestor o trabajador), en el puerto 80. Swarm maneja el balanceo de carga automáticamente. Abre tu navegador y navega a http://<IP_DE_CUALQUIER_NODO>.

Deberías ver la página de bienvenida de Nginx.

Escalando un Servicio

Una de las mayores ventajas de Swarm es la facilidad para escalar. Para aumentar el número de réplicas de tu servicio webserver a 5:

 docker service scale webserver=5

Verifica de nuevo con docker service ls y docker service ps webserver para ver las nuevas réplicas.

Para reducir el número de réplicas a 1:

docker service scale webserver=1

Eliminar un Servicio

Cuando ya no necesites el servicio, puedes eliminarlo fácilmente:

 docker service rm webserver

📦 Despliegue de Stacks con Docker Compose (Docker Stack)

Para aplicaciones más complejas que constan de múltiples servicios (por ejemplo, una aplicación web con su base de datos y un backend API), Docker Swarm utiliza archivos docker-compose.yml extendidos, que se despliegan como un stack.

Ejemplo: Aplicación Multi-Servicio (WordPress + MySQL)

Crearemos un archivo docker-compose.yml para desplegar una instalación de WordPress con MySQL.

Crea un directorio para tu proyecto y dentro de él, un archivo docker-compose.yml:

# wordpress/docker-compose.yml
version: '3.8'

services:
wordpress:
image: wordpress:latest
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpress
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
volumes:
- wordpress_data:/var/www/html

mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: password
deploy:
# Para bases de datos, generalmente se usa solo 1 réplica para evitar problemas de consistencia
# A menos que se use un clúster MySQL (ej. Galera Cluster), lo cual es más avanzado.
replicas: 1
placement:
# Asegura que MySQL se ejecute en un nodo específico si es necesario
# o en un nodo que no sea gestor para separar preocupaciones
constraints:
- node.role == worker
volumes:
- db_data:/var/lib/mysql

volumes:
wordpress_data:
db_data:
🔥 Importante: Para entornos de producción, no uses contraseñas como `password` o `rootpassword`. Utiliza secretos de Docker (Docker Secrets) para gestionar información sensible de forma segura.

Cambios clave en deploy section para Swarm:

  • replicas: Número deseado de instancias del servicio.
  • update_config: Cómo se comportan las actualizaciones continuas (rolling updates).
  • parallelism: Cuántas tareas se actualizan a la vez.
  • delay: Tiempo de espera entre actualizaciones de tareas.
  • restart_policy: Define qué hacer si un contenedor falla o se cierra.
  • placement: Reglas para decidir dónde se desplegará el servicio. Por ejemplo, node.role == worker asegura que el servicio MySQL se ejecute solo en nodos trabajadores, no en el nodo gestor.

Desplegar el Stack

Desde el nodo gestor, navega al directorio donde creaste docker-compose.yml y despliega el stack:

docker stack deploy -c docker-compose.yml wordpress_app
  • docker stack deploy: Despliega un stack.
  • -c docker-compose.yml: Especifica el archivo Compose.
  • wordpress_app: Es el nombre del stack (arbitrario).

Verificar el Stack y sus Servicios

Para ver los stacks activos:

 docker stack ls

Para ver los servicios dentro de un stack específico:

docker stack services wordpress_app

Para ver las tareas de todos los servicios del stack:

 docker stack ps wordpress_app

Acceder a WordPress

Al igual que antes, puedes acceder a tu instalación de WordPress usando la IP de cualquiera de tus nodos en el puerto 80. Completa la instalación de WordPress a través de la interfaz web.

Actualizar un Stack

Si realizas cambios en tu docker-compose.yml (por ejemplo, cambias la imagen de WordPress o aumentas las réplicas), simplemente ejecuta el comando docker stack deploy de nuevo con el mismo nombre de stack. Docker Swarm detectará los cambios y realizará una actualización continua (rolling update) automáticamente, sin tiempo de inactividad.

docker stack deploy -c docker-compose.yml wordpress_app

Eliminar un Stack

Para eliminar todos los servicios y recursos asociados a un stack:

 docker stack rm wordpress_app

🔒 Gestión de Nodos y Seguridad en Swarm

Promover/Degradar Nodos

Puedes cambiar el rol de un nodo si es necesario. Por ejemplo, si tienes un nodo trabajador y quieres que sea gestor:

# En el gestor
docker node promote <ID_DEL_WORKER>

Y para degradar un gestor a trabajador:

 # En el gestor
 docker node demote <ID_DEL_MANAGER_A_DEGRADAR>
⚠️ Advertencia: Un clúster con un solo nodo gestor es un punto único de fallo (SPOF). Se recomienda un número impar de nodos gestores (3 o 5) para la tolerancia a fallos.

Sacar un Nodo del Clúster

Si necesitas eliminar un nodo (por mantenimiento o porque ya no lo necesitas):

  1. En el nodo gestor, drena el nodo: Esto detiene la asignación de nuevas tareas a ese nodo y migra las tareas existentes a otros nodos.
docker node update --availability drain <ID_DEL_NODO>
  1. Desde el nodo a salir, abandona el Swarm:
docker swarm leave

Si el nodo era un gestor, usa:

docker swarm leave --force
  1. En el nodo gestor, elimina el nodo de la lista:
docker node rm <ID_DEL_NODO>

Docker Secrets y Configs

Para manejar información sensible como contraseñas, claves API o certificados, Docker Swarm ofrece Secrets. Para archivos de configuración o datos no sensibles pero específicos de la aplicación, usa Configs.

Crear un Secret:

echo "mysecretpassword" | docker secret create my_db_password -

Luego, puedes usar este secret en tu docker-compose.yml:

 services:
   mysql:
     image: mysql:8.0
     environment:
       MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_db_password
     secrets:
       - my_db_password

 secrets:
   my_db_password:
     external: true
💡 Consejo: Docker Secrets solo se montan en `/run/secrets` dentro del contenedor y no se exponen al host, lo que mejora la seguridad.

📈 Alta Disponibilidad y Tolerancia a Fallos

Docker Swarm está diseñado con la alta disponibilidad en mente. Aquí hay algunas consideraciones:

Nodos Gestores

Para la tolerancia a fallos de los nodos gestores, siempre utiliza un número impar (3, 5, 7...). Esto permite que el clúster continúe funcionando incluso si uno o más gestores fallan, siempre que haya una mayoría disponible (cuórum).

  • 3 Gestores: Tolerancia a 1 fallo.
  • 5 Gestores: Tolerancia a 2 fallos.

Para añadir un nuevo gestor, obtén el comando docker swarm join con el token de gestor (desde un gestor existente):

 docker swarm join-token manager

Luego ejecuta ese comando en el nuevo nodo.

Redes de Superposición (Overlay Networks)

Swarm utiliza redes de superposición para permitir que los contenedores de diferentes nodos se comuniquen entre sí de forma transparente. Cuando creas un servicio o un stack, Swarm automáticamente crea o utiliza una red de superposición.

  • ingress network: La red predeterminada para el balanceo de carga de los servicios que exponen puertos al exterior.
  • Puedes crear tus propias redes de superposición para aislar servicios:
docker network create --driver overlay my_app_network
Luego especifica esta red en tu `docker-compose.yml`.
Ejemplo de Red Personalizada en `docker-compose.yml`
 version: '3.8'
 services:
   service1:
     image: myimage1
     networks:
       - my_app_network
   service2:
     image: myimage2
     networks:
       - my_app_network

 networks:
   my_app_network:
     external: true # Si ya la creaste manualmente
     # o si no, déjala sin external para que Swarm la cree
     # my_app_network:
     #   driver: overlay

Persistencia de Datos

Para datos que necesitan sobrevivir al ciclo de vida de un contenedor o ser compartidos entre réplicas, usa volúmenes.

En el ejemplo de WordPress, usamos wordpress_data y db_data como volúmenes. Swarm se asegura de que estos volúmenes se mantengan y puedan ser reasociados a nuevas instancias de contenedores si un nodo falla y el servicio se reinicia en otro lugar.

💡 Consejo: Para una verdadera persistencia y alta disponibilidad de datos en entornos distribuidos, considera soluciones de almacenamiento compartido como NFS, GlusterFS, o soluciones de almacenamiento en la nube que integren con Docker (por ejemplo, volúmenes de AWS EBS o Google Persistent Disk).

✅ Conclusión y Próximos Pasos

Has llegado al final de este tutorial y ahora tienes un sólido entendimiento de cómo utilizar Docker Swarm para orquestar tus contenedores. Hemos cubierto desde la inicialización de un clúster y la gestión de nodos, hasta el despliegue de servicios y stacks complejos, y hemos tocado aspectos cruciales de seguridad y alta disponibilidad.

Docker Swarm es una herramienta potente y fácil de aprender para aquellos que buscan escalar sus aplicaciones contenerizadas sin la complejidad inicial de Kubernetes. Es una excelente opción para comenzar con la orquestación y gestionar tus despliegues de Docker de manera efectiva.

Resumen de lo aprendido:

CaracterísticaDescripción
------
Inicialización SwarmConvertir un Docker Engine en un nodo gestor de Swarm.
Unión de NodosAñadir máquinas al clúster como gestores o trabajadores.
------
ServiciosDesplegar contenedores con réplicas y balanceo de carga.
StacksDesplegar aplicaciones multi-servicio usando docker-compose.yml extendido.
------
EscaladoAumentar o disminuir las réplicas de los servicios.
Alta DisponibilidadTolerancia a fallos de nodos gestores y servicios.
------
Redes de SuperposiciónComunicación transparente entre contenedores en diferentes nodos.
PersistenciaGestión de datos con volúmenes.
------
SeguridadUso básico de Docker Secrets.
¡Dominio Básico de Swarm Alcanzado!

Próximos Pasos:

  • Explora Docker Secrets y Configs a fondo: Aprende a gestionar credenciales y configuraciones de forma segura.
  • Monitoreo del Clúster: Integra herramientas como Prometheus y Grafana para observar el rendimiento de tus servicios y nodos.
  • CI/CD con Docker Swarm: Automatiza el despliegue de tus aplicaciones en Swarm usando pipelines de integración y entrega continua.
  • Integración con almacenamiento externo: Experimenta con volúmenes de red (NFS, EFS, etc.) para una persistencia de datos más robusta en un clúster.
  • Modo de debug y logs: Aprende a diagnosticar problemas en servicios y tareas de Swarm.

¡Sigue experimentando y construyendo con Docker Swarm!

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!