--- title: "Cómo crear un clúster Docker Swarm en Ubuntu 24.04" description: "Crea un clúster Docker Swarm de tres nodos en Ubuntu 24.04, despliega un stack replicado en una red overlay cifrada y aprende a escalar y drenar nodos." category: "Docker Avanzado" language: es source: https://cubepath.com/es/docs/docker-avanzado/configuracion-del-cluster-docker-swarm updated: 2026-09-25 --- # Cómo crear un clúster Docker Swarm en Ubuntu 24.04 Docker Swarm es el modo de orquestación integrado en Docker Engine: agrupa varios servidores en un clúster y reparte entre ellos contenedores replicados, con balanceo de carga, actualizaciones progresivas y recuperación automática si un nodo cae. Es mucho más sencillo de operar que Kubernetes y usa el mismo formato de ficheros Compose que ya conoces. En este tutorial crearás un clúster de tres nodos en Ubuntu 24.04 (un manager y dos workers), desplegarás un stack replicado y practicarás las operaciones del día a día. ## Requisitos previos Para seguir esta guía necesitas: - Tres servidores con Ubuntu 24.04 LTS, por ejemplo VPS de CubePath, con al menos 1 GB de RAM cada uno. - Docker Engine instalado desde el repositorio oficial de Docker en los tres, y tu usuario añadido al grupo `docker` para ejecutar `docker` sin `sudo`. - Una red privada entre los tres servidores. En esta guía se usan estas direcciones de ejemplo, sustitúyelas por las tuyas: | Nodo | Rol | IP privada | |------|-----|------------| | `manager1` | Manager | `10.0.0.11` | | `worker1` | Worker | `10.0.0.12` | | `worker2` | Worker | `10.0.0.13` | - Un nombre de host distinto en cada servidor (`hostnamectl` muestra el actual). Swarm identifica los nodos por su hostname en `docker node ls`. ## Paso 1: Abrir los puertos de Swarm en la red privada Los nodos de Swarm se comunican por estos puertos, que deben estar abiertos solo entre los nodos y nunca hacia Internet: | Puerto | Protocolo | Uso | |--------|-----------|-----| | 2377 | TCP | Gestión del clúster (solo hacia los managers) | | 7946 | TCP y UDP | Descubrimiento y comunicación entre nodos | | 4789 | UDP | Tráfico de las redes overlay (VXLAN) | | ESP (protocolo IP 50) | - | Redes overlay cifradas | Ejecuta en los tres servidores, ajustando `10.0.0.0/24` a tu red privada: ```bash sudo ufw allow OpenSSH sudo ufw allow from 10.0.0.0/24 to any port 2377 proto tcp sudo ufw allow from 10.0.0.0/24 to any port 7946 sudo ufw allow from 10.0.0.0/24 to any port 4789 proto udp sudo ufw allow from 10.0.0.0/24 proto esp sudo ufw enable ``` Comprueba las reglas: ```bash sudo ufw status ``` > Advertencia: Los puertos que publica Docker (`ports:` en un stack o `-p` en `docker run`) se abren mediante reglas de iptables propias de Docker y no pasan por UFW. Un puerto publicado queda accesible desde Internet aunque UFW no tenga una regla para él. Publica solo lo que quieras exponer. ## Paso 2: Inicializar el clúster en el manager En `manager1`, inicializa Swarm indicando la IP privada con `--advertise-addr`. Es la dirección que los demás nodos usarán para conectarse; si no la indicas y el servidor tiene varias interfaces, Docker puede elegir la pública: ```bash docker swarm init --advertise-addr 10.0.0.11 ``` ```output Swarm initialized: current node (k3v9q2x8m1n7b5c4z6a0d2f1g) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx 10.0.0.11:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. ``` Copia el comando `docker swarm join` completo. Si lo pierdes, puedes volver a mostrarlo en cualquier momento desde el manager: ```bash docker swarm join-token worker ``` > Importante: El token de unión da acceso al clúster. No lo guardes en repositorios ni lo compartas. Si se filtra, invalídalo con `docker swarm join-token --rotate worker`. ## Paso 3: Unir los workers al clúster Ejecuta el comando `docker swarm join` que copiaste en `worker1` y en `worker2`: ```bash docker swarm join --token SWMTKN-1-your_worker_token 10.0.0.11:2377 ``` ```output This node joined a swarm as a worker. ``` Vuelve a `manager1` y lista los nodos. Todos los comandos de gestión del clúster (`docker node`, `docker service`, `docker stack`) se ejecutan en un manager: ```bash docker node ls ``` ```output ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION k3v9q2x8m1n7b5c4z6a0d2f1g * manager1 Ready Active Leader 28.4.0 p8w2e5r7t1y3u6i9o0a4s2d5f worker1 Ready Active 28.4.0 h6j3k9l1z4x7c2v8b5n0m3q6w worker2 Ready Active 28.4.0 ``` > Nota: Con un solo manager, si ese servidor cae no podrás gestionar el clúster, aunque los contenedores de los workers sigan funcionando. En producción usa 3 managers, que toleran la caída de uno. Puedes convertir los workers en managers con `docker node promote worker1 worker2`. ## Paso 4: Desplegar un stack en una red overlay cifrada Un stack es un conjunto de servicios definidos en un fichero Compose que Swarm despliega y mantiene en el clúster. Crea el fichero en `manager1`: ```bash mkdir -p ~/stacks nano ~/stacks/demo.yml ``` El servicio usa la imagen `traefik/whoami`, un servidor HTTP mínimo que responde con el nombre del contenedor que atiende la petición. Así podrás ver el balanceo entre réplicas: ```yaml services: whoami: image: traefik/whoami ports: - "8080:80" networks: - app deploy: replicas: 3 update_config: parallelism: 1 delay: 10s failure_action: rollback order: start-first restart_policy: condition: on-failure resources: limits: cpus: "0.25" memory: 64M networks: app: driver: overlay driver_opts: encrypted: "true" ``` Los bloques importantes son: - `replicas: 3`: Swarm mantiene siempre tres contenedores y los reparte entre los nodos disponibles. - `update_config`: las actualizaciones sustituyen los contenedores de uno en uno, esperan 10 segundos entre cada uno, arrancan el nuevo antes de parar el antiguo y vuelven atrás solas si algo falla. - `encrypted: "true"`: el tráfico entre contenedores de distintos nodos por la red `app` va cifrado con IPsec. Por eso abriste ESP en el paso 1. Despliega el stack con el nombre `demo`: ```bash docker stack deploy -c ~/stacks/demo.yml demo ``` ```output Creating network demo_app Creating service demo_whoami ``` Comprueba en qué nodos se han colocado las réplicas: ```bash docker service ps demo_whoami ``` ```output ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS x1c4v7b0n3m6 demo_whoami.1 traefik/whoami:latest worker1 Running Running 20 seconds ago q9w2e5r8t1y4 demo_whoami.2 traefik/whoami:latest worker2 Running Running 20 seconds ago a3s6d9f2g5h8 demo_whoami.3 traefik/whoami:latest manager1 Running Running 20 seconds ago ``` El puerto publicado usa la malla de enrutado (routing mesh) de Swarm: el puerto 8080 responde en todos los nodos y reparte las peticiones entre las réplicas, estén donde estén. Haz varias peticiones contra un mismo nodo: ```bash for i in 1 2 3; do curl -s http://10.0.0.12:8080 | grep Hostname; done ``` ```output Hostname: 5e1f0a9b2c7d Hostname: 8d3c6b1a4f2e Hostname: c7a2e9d4b1f6 ``` Cada respuesta llega de un contenedor distinto aunque siempre preguntas al mismo nodo. ## Paso 5: Escalar y actualizar servicios Para absorber más carga, aumenta el número de réplicas. Swarm crea las nuevas y las reparte entre los nodos: ```bash docker service scale demo_whoami=6 ``` ```output demo_whoami scaled to 6 overall progress: 6 out of 6 tasks verify: Service demo_whoami converged ``` Para que el cambio sea permanente, actualiza también `replicas` en `demo.yml`: si vuelves a ejecutar `docker stack deploy`, el fichero manda. Cualquier cambio en la definición del contenedor (imagen, variables de entorno, límites) se aplica como actualización progresiva según `update_config`. Por ejemplo, añade una variable de entorno: ```bash docker service update --env-add APP_VERSION=2 demo_whoami ``` Swarm sustituye las réplicas de una en una y muestra el progreso hasta que el servicio converge. En tu flujo habitual cambiarás la etiqueta de imagen en `demo.yml` y volverás a ejecutar `docker stack deploy`, que hace lo mismo. Si la nueva versión no se comporta como esperas, vuelve a la anterior: ```bash docker service rollback demo_whoami ``` Revisa el historial de tareas para ver las réplicas sustituidas: ```bash docker service ps demo_whoami ``` Las tareas antiguas aparecen con `DESIRED STATE` en `Shutdown`, y las activas en `Running`. ## Paso 6: Mantenimiento de nodos Antes de reiniciar o actualizar un servidor, drénalo: Swarm deja de asignarle tareas y mueve las que tenía a otros nodos: ```bash docker node update --availability drain worker1 ``` Comprueba que no quedan contenedores en ejecución en `worker1`: ```bash docker node ps worker1 --filter desired-state=running ``` La lista debe salir vacía. Haz el mantenimiento y, al terminar, vuelve a activar el nodo: ```bash docker node update --availability active worker1 ``` > Nota: Al reactivar el nodo, Swarm no mueve las réplicas existentes para equilibrar la carga. Solo coloca ahí las tareas nuevas. Para redistribuirlas, fuerza una actualización con `docker service update --force demo_whoami`. Para fijar un servicio a ciertos nodos, etiqueta el nodo y usa una restricción de colocación. Por ejemplo, para una base de datos que debe correr donde está su disco: ```bash docker node update --label-add storage=ssd worker2 ``` Y en el servicio del fichero de stack: ```yaml deploy: placement: constraints: - node.labels.storage == ssd ``` ## Paso 7: Hacer copia de seguridad del estado del clúster El estado de Swarm (servicios, redes, secretos, configuración) vive en la base de datos Raft de los managers, en `/var/lib/docker/swarm`. Para copiarlo de forma consistente hay que parar Docker en el manager. Con un solo manager, mientras Docker esté parado no podrás gestionar el clúster, pero los contenedores de los workers siguen funcionando: ```bash sudo systemctl stop docker docker.socket sudo tar -czf /root/swarm-backup-$(date +%F).tar.gz -C /var/lib/docker swarm sudo systemctl start docker ``` Comprueba que el manager vuelve a estar operativo: ```bash docker node ls ``` Guarda la copia fuera del servidor. Para restaurar en un manager nuevo, se extrae el archivo en `/var/lib/docker/` con Docker parado y se ejecuta `docker swarm init --force-new-cluster` para que el nodo arranque el clúster con ese estado. Con 3 managers rara vez necesitarás restaurar, porque los otros dos mantienen el estado. ## Solución de problemas - **`docker swarm join` se queda esperando o da `timeout`**: el worker no llega al puerto 2377 del manager. Comprueba la regla de UFW en el manager y que usas la IP privada con `nc -zv 10.0.0.11 2377` desde el worker. - **El servicio responde en un nodo pero no en otros**: falla el tráfico overlay entre nodos. Revisa que 4789/udp, 7946 y ESP están permitidos entre todos los nodos. - **Una tarea se queda en `Pending` con `no suitable node`**: ningún nodo cumple las restricciones de colocación o los recursos pedidos. Consulta el motivo con `docker service ps --no-trunc demo_whoami`. - **La imagen no se descarga en los workers**: si viene de un registro privado, despliega con `docker stack deploy --with-registry-auth` para pasar las credenciales a los nodos. ## Conclusión Tienes un clúster Docker Swarm de tres nodos con un stack replicado en una red overlay cifrada, y sabes escalar, actualizar, revertir y drenar nodos sin cortar el servicio. Como siguientes pasos, promociona dos nodos más a manager para tener alta disponibilidad, guarda contraseñas con `docker secret` en lugar de variables de entorno, y pon un proxy inverso como Traefik o Nginx delante de los servicios publicados para servirlos con HTTPS.