Cómo implementar Docker Swarm
Paso a paso cómo instalar y configurar un cluster de Docker Swarm
La siguiente es una guía rápida paso a paso de como instalar y habilitar un cluster de Docker Swarm para desplegar servicios y aplicaciones con la posibilidad de tener alta disponibilidad (HA).
¿Por qué Swarm?
Durante un tiempo estuve desplegando contenedores utilizando docker compose, lo cual me parecía una forma práctica de desplegar rápidamente y mantener un template que puede ser migrado en cualquier momento. Los problemas que veo en este enfoque son los siguientes.
- No permite alta disponibilidad: Si bien es posible definir múltiples replicas en docker compose, esto realmente no es alta disponibilidad, ya que estaríamos desplegando contenedores en el mismo host.
- Downtime: Cada vez que se requiere hacer un cambio y/o actualización en la definición de docker compose es necesario bajar los contenedores (
docker compose down
) y volverlos a levantar (docker compose up -d
) lo que genera que el servicio se encuentre abajo por al menos unos segundos.
Docker Swarm no es una opción muy popular pero considero que cumple en estos dos puntos sin llegar a ser tan complejo como Kubernetes.
Instalación
Para la instalación de este entorno he dispuesto de dos host basados en Debian en mi hipervisor Proxmox que se utilizarán para conformar el Swarm.
Instalación de paquetes
Como mis hosts son Debian 12, instalaré docker siguiendo esta guía.
- Agregar repositorio apt
1
2
3
4
5
6
7
8
9
10
11
12
13
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
- Instalar paquetes
1
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Una vez hecho esto podemos correr la imagen hello-world para verificar que todo se haya instalado correctamente
1
sudo docker run hello-world
Funciona correctamente, ahora toca replicar lo mismo en el segundo host.
Configuración Swarm
Ahora viene lo interesante, el objetivo es hacer que estos dos host funcionen en Swarm mode de la siguiente forma.
swarm-blog-01
-> Manager nodeswarm-blog-02
-> Worker node
Comenzando por el que será el Manager node, ejecutaremos el comando.
reemplazar IP por la del host |
1
docker swarm init --advertise-addr 192.168.1.131
Con esto ya tendríamos el nodo principal listo. El output entrega el comando para ejecutar en un nodo secundario y unir al Swarm.
Antes, podemos verificar el estado de los nodos con docker node ls
Ahora iremos al nodo secundario (swarm-blog-02
) y ejecutaremos el comando.
1
docker swarm join --token <TOKEN> 192.168.1.131:2377
Es importante no exponer el Token, ya que con él es posible unirse al Swarm directamente
Vemos que se ha unido sin problema pero ha quedado como Manager igual que el nodo principal. Pueden haber casos en los que se requiere más de un manager, pero en mi caso lo que quiero lograr es tener un Manager y un Worker.
Volviendo swarm-blog-01
obtendremos el ID del nodo secundario con docker node ls
y ejecutaremos
1
docker node demote <ID>
Despliegue de Stack
Ahora que el cluster ya se encuentra conformado desplegaré un stack simple de nginx con dos replicas. Para esto tenemos un par de opciones, desplegar en modo global
o con 2 o más replicas.
De cualquier forma se necesitará una interfaz de red de tipo Overlay.
1
docker network create --driver overlay nginx-net
En un clúster, las réplicas de un servicio (como Nginx) pueden ejecutarse en distintos nodos. La red overlay asegura que esas réplicas puedan intercambiar datos y recibir tráfico sin importar en qué nodo estén, permitiendo el balanceo de carga y la alta disponibilidad.
- nginx.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '3.8'
networks:
nginx-net:
driver: overlay
services:
nginx:
image: nginx:alpine
ports:
- target: 80
published: 80
protocol: tcp
mode: host
networks:
- nginx-net
deploy:
replicas: 2
restart_policy:
condition: on-failure
Con el archivo nginx.yaml
en el nodo Manager, lo desplegaremos como stack de la siguiente manera.
1
docker stack deploy -c nginx.yaml nginx --detach=false
Esto nos creará un elemento stack
y service
en Docker.
Ahora si verificamos con docker ps
podremos ver que se generó un contenedor en ambos nodos.
Y ambos servicios son accesibles simultáneamente.
Construye, automatiza, repite. ¡Nos vemos en el próximo post!