Configuración del Cluster Docker Swarm

Docker Swarm es la plataforma de orquestación nativa de Docker que permite administrar un cluster de hosts Docker como un único sistema virtual. Esta guía cubre los aspectos esenciales de configurar, desplegar y gestionar un cluster Docker Swarm en tu infraestructura VPS o baremetal. Ya sea que estés desplegando un pequeño cluster de 3 nodos o escalando a decenas de servidores, comprender los fundamentos de Swarm es crítico para una orquestación de contenedores confiable.

Tabla de Contenidos

Requisitos y Planificación

Antes de inicializar un cluster Docker Swarm, asegúrate de que todos los nodos cumplan con los siguientes requisitos:

  • Docker Engine 1.12 o posterior instalado en cada nodo
  • Puerto 2377/tcp abierto entre todos los nodos (gestión de cluster)
  • Puertos 7946/tcp y 7946/udp abiertos entre todos los nodos (comunicación de nodos)
  • Puerto 4789/udp abierto para tráfico de red overlay
  • Todos los nodos capaces de comunicarse en una red privada
  • Tiempo del sistema consistente en todos los nodos (NTP recomendado)
  • Al menos 2GB de RAM por nodo para operación estable

Mejores prácticas para el tamaño del cluster:

# Verificar versión de Docker y asegurar compatibilidad
docker --version

# Verificar kernel actual y configuración de cgroups
uname -r
cat /proc/cgroups | head

# Verificar conectividad de red entre nodos planificados
ping -c 4 <otra-ip-nodo>

# Probar resolución de DNS para nombres de host de nodos
nslookup <nombre-host-nodo>

Planifica tu arquitectura Swarm con las siguientes consideraciones:

  • Nodos Manager: Mínimo 1 (pero 3 recomendado para alta disponibilidad)
  • Nodos Worker: Escala basada en requisitos de carga de trabajo
  • Distribución: Distribuye entre hosts físicos cuando sea posible
  • Estrategia de Backup: Snapshots regulares del estado del manager

Inicializando Swarm

Inicializa Swarm en tu primer nodo manager. Este nodo se convierte en el líder y genera material de certificados para comunicación segura.

# Inicializar Docker Swarm en el primer nodo manager
docker swarm init

# Especificar dirección de anuncio si existen múltiples interfaces de red
docker swarm init --advertise-addr 192.168.1.10

# Inicializar con cifrado de ruta de datos personalizado (recomendado)
docker swarm init --advertise-addr 192.168.1.10 --force-new-cluster

# Ver estado actual de Swarm
docker info | grep -A 5 Swarm

# Obtener información del cluster
docker node ls

Cuando inicializas Swarm, Docker crea:

  • Un ID de cluster único y certificados
  • Dos tokens únicos: token de manager y token de worker
  • El manager se convierte en la autoridad raíz de certificados
  • Base de datos Raft para almacenar el estado del cluster

Verifica que la inicialización fue exitosa:

# Verificar estado de Swarm
docker swarm inspect

# Listar todos los nodos (solo uno inicialmente)
docker node ls

# Ver estado del manager
docker node inspect --pretty self

# Verificar que los servicios de Swarm están corriendo
systemctl status docker

Agregando Nodos al Cluster

Para escalar tu cluster, agrega nodos manager o worker adicionales. Siempre usa el token apropiado para el tipo de nodo.

Obtén los tokens de unión:

# Obtener token de unión de worker
docker swarm join-token worker

# Obtener token de unión de manager
docker swarm join-token manager

# Rotar tokens por seguridad
docker swarm join-token --rotate worker

# Rotar token de manager
docker swarm join-token --rotate manager

Agrega un nodo worker al cluster:

# En el nuevo nodo worker, ejecuta el comando de unión
docker swarm join \
  --token SWMTKN-1-5k9w2r7y1z3q4p9m8n7o6l5k4j3h2g1f \
  192.168.1.10:2377

# Verificar unión exitosa
docker swarm inspect

Agrega nodos manager para alta disponibilidad:

# En el nuevo nodo manager, únete usando token de manager
docker swarm join \
  --token SWMTKN-1-0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z \
  192.168.1.10:2377

# En cualquier manager existente, verifica que el nuevo manager se unió
docker node ls

Configura etiquetas de nodo para colocación de carga de trabajo:

# Agregar etiquetas a nodos (útil para restringir servicios)
docker node update --label-add environment=production node1

# Agregar múltiples etiquetas
docker node update --label-add tier=web --label-add region=us-east node2

# Ver detalles del nodo incluyendo etiquetas
docker node inspect node1

# Remover una etiqueta
docker node update --label-rm environment node1

Establece disponibilidad del nodo:

# Drenar un nodo (prevenir nuevas tareas, reprogramar existentes)
docker node update --availability drain node-name

# Activar un nodo nuevamente
docker node update --availability active node-name

# Pausar un nodo (sin nuevas tareas, pero existentes continúan)
docker node update --availability pause node-name

# Verificar estado del nodo
docker node ls

Desplegando Servicios en Swarm

Los servicios son la forma principal de ejecutar contenedores en Swarm. Un servicio define la imagen del contenedor deseada, réplicas, mapeos de puertos y restricciones de recursos.

Crea un servicio simple:

# Desplegar un servicio con 3 réplicas
docker service create \
  --name web \
  --replicas 3 \
  --publish 80:80 \
  nginx:latest

# Verificar creación de servicio
docker service ls

# Verificar detalles del servicio
docker service inspect web

# Ver tareas del servicio (contenedores en ejecución)
docker service ps web

Configura restricciones y colocación de servicio:

# Desplegar servicio solo en nodos de producción
docker service create \
  --name db \
  --constraint node.labels.environment==production \
  --replicas 1 \
  postgres:15

# Usar estrategia de colocación spread
docker service create \
  --name api \
  --placement-pref spread=node.hostname \
  --replicas 3 \
  myapp:latest

# Desplegar en nodo específico
docker service create \
  --name cache \
  --constraint node.hostname==cache-node-01 \
  redis:7-alpine

Configura límites de recursos y reservas:

# Limitar memoria y CPU
docker service create \
  --name web \
  --limit-memory 512m \
  --limit-cpu 0.5 \
  --reserve-memory 256m \
  --reserve-cpu 0.25 \
  --replicas 2 \
  nginx:latest

# Ver uso de recursos
docker stats

Configura variables de entorno y secretos:

# Pasar variables de entorno
docker service create \
  --name app \
  --env DATABASE_URL=postgres://db:5432/myapp \
  --env LOG_LEVEL=info \
  --replicas 2 \
  myapp:latest

# Actualizar entorno del servicio
docker service update \
  --env-add NEW_VAR=value \
  app

Entendiendo Redes Overlay

Las redes overlay permiten comunicación segura de contenedor a contenedor a través de múltiples hosts en el Swarm.

Crea y gestiona redes overlay:

# Crear una red overlay
docker network create --driver overlay mynetwork

# Crear con cifrado habilitado (recomendado)
docker network create \
  --driver overlay \
  --opt encrypted \
  --subnet 10.0.0.0/24 \
  secure-net

# Listar redes
docker network ls

# Inspeccionar red
docker network inspect mynetwork

# Remover red
docker network rm mynetwork

Conecta servicios a redes overlay:

# Crear una red
docker network create --driver overlay backend

# Desplegar servicio en red
docker service create \
  --name web \
  --network backend \
  --publish 80:80 \
  nginx:latest

# Desplegar otro servicio en la misma red
docker service create \
  --name app \
  --network backend \
  myapp:latest

# Los servicios ahora pueden comunicarse por nombre de servicio
# Desde contenedor app: curl http://web/

Crea redes overlay adjuntables para acceso externo:

# Crear red adjuntable (permite contenedores autónomos)
docker network create \
  --driver overlay \
  --attachable \
  shared-net

# Conectar un contenedor autónomo (si es necesario)
docker run -d \
  --network shared-net \
  --name standalone \
  nginx:latest

# Conectar servicio a red
docker service create \
  --name api \
  --network shared-net \
  myapi:latest

Descubrimiento de servicios en redes overlay:

# Todos los servicios en la misma red pueden resolver por nombre
# DNS interno: <nombre-servicio>.<nombre-red>
# Ejemplo desde dentro de un contenedor en la red:

# nslookup web
# Se resuelve a IP virtual (VIP) del servicio web

# VIP del servicio balancea carga entre todas las réplicas
# curl http://web:80/ hará round-robin entre réplicas

Gestión de Stacks y Archivos Compose

Los stacks son una forma conveniente de desplegar y gestionar aplicaciones multi-servicio usando archivos en formato Docker Compose.

Crea un stack desde un archivo compose:

# Crear un archivo docker-compose.yml
cat > docker-compose.yml <<EOF
version: '3.9'

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s

  app:
    image: myapp:latest
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  db:
    image: postgres:15
    deploy:
      replicas: 1
      constraints:
        - node.labels.tier == database
    environment:
      POSTGRES_PASSWORD: secret

networks:
  default:
    driver: overlay
    driver_opts:
      encrypted: "true"

EOF

# Desplegar el stack
docker stack deploy -c docker-compose.yml myapp

# Listar stacks
docker stack ls

# Verificar servicios del stack
docker stack services myapp

# Ver detalles del stack
docker stack ps myapp

Actualiza y gestiona stacks:

# Actualizar servicio en stack en ejecución
docker service update \
  --image myapp:v2.0 \
  myapp_app

# O actualizar mediante cambios en archivo compose
docker stack deploy -c docker-compose.yml myapp

# Remover stack completo y servicios
docker stack rm myapp

# Ver tareas del stack
docker stack ps myapp --no-trunc

Actualizaciones Gradientes y Escalado de Servicios

Implementa despliegues sin downtime con actualizaciones gradientes y gestiona escalado de servicios eficientemente.

Configura estrategia de actualización:

# Crear servicio con configuración de actualización
docker service create \
  --name api \
  --update-delay 10s \
  --update-parallelism 1 \
  --update-failure-action pause \
  --replicas 4 \
  myapi:v1.0

# Ver configuración de actualización
docker service inspect api | grep -A 5 UpdateConfig

Realiza una actualización gradiente:

# Actualizar imagen del servicio
docker service update \
  --image myapi:v2.0 \
  api

# Monitorear la actualización gradiente
docker service ps api --no-trunc

# Actualizar con sincronización personalizada
docker service update \
  --image myapi:v3.0 \
  --update-delay 5s \
  --update-parallelism 2 \
  api

# Reversión si es necesario (ir a imagen anterior)
docker service update \
  --image myapi:v2.0 \
  api

Escala servicios hacia arriba y abajo:

# Escalar servicio a réplicas deseadas
docker service scale api=6

# Escalar múltiples servicios
docker service scale web=5 app=3 cache=2

# Monitorear escalado
docker service ps api
watch -n 1 'docker service ps api'

# Verificar distribución de tareas
docker node ls
docker service ps api --filter desired-state=running

Configura recuperación automática basada en salud:

# Crear servicio con política de reinicio
docker service create \
  --name web \
  --restart-condition on-failure \
  --restart-delay 5s \
  --restart-max-attempts 3 \
  --replicas 3 \
  nginx:latest

# Monitorear fallos de tareas
docker service ps web --filter desired-state=failed

Drenando y Removiendo Nodos

Remueve nodos del cluster de forma segura con migración adecuada de tareas.

Drena un nodo antes de su remoción:

# Poner nodo en estado de drenaje (migrar todas las tareas)
docker node update --availability drain node-to-remove

# Monitorear migración de tareas
watch -n 1 'docker service ps -f "node=node-to-remove"'

# Esperar que todas las tareas se migren
# Verificar cuando el nodo no muestre tareas en ejecución
docker service ps api --filter node=node-to-remove

# Una vez drenado, remover del cluster (en el nodo objetivo)
docker swarm leave

Remueve un nodo forzadamente desde otro manager:

# Si el nodo no responde, remover desde cualquier manager
docker node rm node-offline-id

# Ver ID del nodo
docker node ls

# Remover con bandera de fuerza
docker node rm --force unresponsive-node-id

Reúne un nodo después de su remoción:

# Obtener nuevo token de unión
docker swarm join-token worker

# En el nodo, ejecutar comando de unión
docker swarm join \
  --token SWMTKN-1-newtoken \
  192.168.1.10:2377

# Verificar reunión
docker node ls

Monitoreo y Solución de Problemas

Monitorea la salud del cluster y diagnostica problemas comunes.

Verifica el estado del cluster:

# Ver información del cluster
docker info

# Listar todos los nodos con estado
docker node ls

# Información detallada del nodo
docker node inspect node1 --pretty

# Verificar base de datos Swarm
docker system info | grep -A 10 Swarm

# Ver estadísticas del manager
docker node stats

Diagnostica problemas de nodo:

# Verificar estado del nodo
docker node inspect node2

# Ver eventos del nodo
docker events --filter type=node

# Verificar conectividad del nodo
docker node update --label-add health-check=pending node2

# Remover etiqueta de verificación de salud
docker node update --label-rm health-check node2

Monitorea servicios y tareas:

# Monitoreo de servicios en tiempo real
docker stats

# Ver todas las tareas en el cluster
docker service ps --all

# Monitorear servicio específico
docker service ps api --no-trunc

# Verificar logs de tareas
docker service logs api

# Seguir logs de tareas
docker service logs -f api

Soluciona problemas comunes:

# El servicio no inicia - verificar disponibilidad de imagen
docker service create --name test busybox:latest
docker service ps test

# Tareas atrapadas pendientes - verificar restricciones
docker service inspect api | grep -A 5 Placement

# Problemas de red - probar conectividad
docker exec <container-id> ping <nombre-servicio>

# Verificar red overlay
docker network inspect <nombre-red>

# Verificar estado del certificado de nodo
docker node inspect --pretty self

Respalda y restaura Swarm:

# Respaldar nodo manager (detener contenedor de forma segura)
sudo systemctl stop docker
sudo tar -czf /backup/swarm-backup.tar.gz /var/lib/docker/swarm

# Restaurar desde respaldo
sudo systemctl stop docker
sudo tar -xzf /backup/swarm-backup.tar.gz -C /
sudo systemctl start docker

# Verificar estado del cluster
docker node ls
docker service ls

Conclusión

Docker Swarm proporciona una plataforma directa pero poderosa para orquestar aplicaciones containerizadas a escala. Al comprender procedimientos de inicialización, gestión de nodos, redes overlay y estrategias de despliegue de servicios, puedes construir infraestructura confiable y escalable. Comienza con un cluster pequeño, practica actualizaciones gradientes y operaciones de escalado, e incrementa gradualmente la complejidad de tu despliegue. Monitorea tu cluster consistentemente y mantén respaldos regulares de nodos manager para asegurar continuidad del negocio. Con estos fundamentos en lugar, Docker Swarm se convierte en una excelente opción para organizaciones que buscan una solución de orquestación Docker nativa sin la complejidad de Kubernetes.