Balanceo de carga en Docker Swarm
Implementación de balanceo de carga en Docker Swarm utilizando Nginx Proxy Manager
Hoy continuamos trabajando en el Homelab, y esta vez el tema es: Balanceo de carga en Docker Swarm. Utilizaremos Nginx Proxy Manager, que ya tenemos desplegado en nuestro entorno de Docker Swarm, configurado posts anteriores.
Te dejo los enlaces a ambos posts por si quieres repasarlos:
Si bien contamos con un entorno de Docker Swarm, esto no garantiza directamente ya contar con el balanceo de carga. Para esto es necesario contar con un elemento intermedio que pueda recibir una solicitud de un nombre, por ejemplo host.mydomain.com
y entregarla a los hosts que sirvan este contenido.
Implementación
Para este laboratorio desplegaré dos contenedores de nginx web a ambos nodos del Swarm. Cada nginx mostrará un contenido distinto para poder identificar a cual estamos accediendo. El diagrama se vería de la siguiente forma.
Haciendo esto, podriamos consultar el nombre nginx.home.cervant.net
-que utilizaremos durante este laboratorio- y obtendríamos el contenido del nginx de swarm-01
o de swarm-02
.
Es importante recordar que el registro DNS
nginx.home.cervant.net
debe apuntar a la IP de Nginx Proxy Manager, que funcionará como proxy y balanceador de carga.
Creación de Stack
Crearemos el archivo de stack para desplegar dos replicas de nginx.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
version: "3.8"
services:
nginx1:
image: nginx:latest
deploy:
replicas: 1
placement:
constraints:
- "node.role == manager"
restart_policy:
condition: on-failure
ports:
- target: 80
published: 8081
mode: host
command: /bin/sh -c 'echo "NGINX 1" > /usr/share/nginx/html/index.html && nginx -g "daemon off;"'
networks:
- swarm-frontend
nginx2:
image: nginx:latest
deploy:
replicas: 1
placement:
constraints: [node.role == worker]
restart_policy:
condition: on-failure
ports:
- target: 80
published: 8081
mode: host
command: /bin/sh -c 'echo "NGINX 2" > /usr/share/nginx/html/index.html && nginx -g "daemon off;"'
networks:
- swarm-frontend
networks:
swarm-frontend:
external: true
Ahora si voy al Swarm Cluster Visualizer de Portainer, puedo ver que ambos contenedores están operativos y cada uno en un nodo distinto del Swarm.
Configuración Nginx Proxy Manager
Como hemos lanzado el stack de nginx exponiendo el puerto 8081
, deberemos asegurarnos de dirigir el tráfico a este puerto. Las IP de mis nodos Swarm son 192.168.1.121
y 192.168.1.124
, por lo que nginx deberá apuntar a.
192.168.1.121:8081
(swarm-01)192.168.1.124:8081
(swarm-02)
Agregaremos un nuevo Proxy Host apuntando al nodo principal y luego en la pestaña Custom locations agregaremos el nodo secundario.
Si no recuerdas como agregar un Proxy Host puedes leer el post de Nginx Proxy Manager para el paso a paso.
Acá agregamos el nombre DNS que utilizaremos y la IP de swarm-01
.
Agregaremos un Custom location apuntando a la raíz (/
) con la IP de swarm-02
Finalmente nos aseguraremos de que haya un certificado SSL válido para nuestro subdominio.
Al hacer pruebas vemos que los nginx de ambos nodos responden al mismo DNS que se ha creado para el balanceo de carga.
Luego de muchas pruebas me he dado cuenta que más que Load Balancing, lo que Nginx realiza es un Failover. He forzado la detención del contenedor en
swarm-01
y comencé a ver el contenido desde el contenedor deswarm-02
. De todas formas cumple como alta disponibilidad.
Construye, automatiza, repite. ¡Nos vemos en el próximo post!