Práctica 1.10.b

Implantación de Aplicaciones Web

Curso 2026/2027

1 Balanceador de carga con Nginx

En esta práctica vamos a configurar Nginx para que trabaje como un balanceador de carga. Se recomienda la lectura del artículo Nginx Load Balancing - HTTP Load Balancing.

1.1 ¿Qué es un proxy inverso?

Un proxy inverso (reverse proxy) es un servidor que se sitúa delante de uno o varios servidores web y recibe las peticiones de los clientes en su nombre. El cliente se comunica únicamente con el proxy inverso, que reenvía cada petición al servidor interno correspondiente y devuelve la respuesta al cliente. De este modo, el cliente no sabe qué servidor ha atendido realmente su petición.

A diferencia de un proxy directo (forward proxy), que actúa en nombre de los clientes para acceder a Internet, un proxy inverso actúa en nombre de los servidores.

Entre las funciones más habituales de un proxy inverso se encuentran:

En esta práctica utilizaremos Nginx como proxy inverso para realizar el balanceo de carga entre dos frontales web y la terminación HTTPS con un certificado de Let’s Encrypt.

1.2 Infraestructura necesaria

La infraestructura propuesta consta de cuatro máquinas virtuales, una para el balanceador de carga (Load Balancer), dos como frontales web (Front-End) y una como servidor de base de datos MySQL (Back-End).

1.3 Breve descripción de los requisitos

1.4 Arquitectura de una aplicación web en tres niveles

1.5 Instalación de Nginx

En primer lugar, tendremos que instalar el servidor web Nginx.

sudo apt update
sudo apt install nginx -y

Una vez instalado, podemos examinar los directorios donde se almacenan los archivos de configuración de los Virtual Hosts de Nginx:

En la instalación por defecto solo tendremos un archivo de configuración default en ambos directorios.

Una posible configuración para un Virtual Host que responde peticiones HTTP en el puerto 80 podría ser la siguiente:

server {
    listen 80;

    server_name _;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

1.6 Cómo configurar Nginx como balanceador de carga

Para configurar Nginx como balanceador de carga, vamos a deshabilitar el sitio por defecto eliminando el enlace simbólico con el siguiente comando:

sudo unlink /etc/nginx/sites-enabled/default

Una vez eliminado, vamos a crear un nuevo archivo de configuración llamado load-balancer.conf en el directorio /etc/nginx/sites-available/ con el siguiente contenido:

upstream frontend_servers {
    server IP_FRONTEND_1;
    server IP_FRONTEND_2;
}

server {
    listen 80;
    server_name DOMAIN_NAME;

    location / {
        proxy_pass http://frontend_servers;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Tenga en cuenta que deberá reemplazar los siguientes valores:

Las directivas proxy_set_header permiten que los frontales reciban el nombre de dominio original (Host), la dirección IP del cliente (X-Real-IP y X-Forwarded-For) y el protocolo utilizado por el cliente (X-Forwarded-Proto). Si no se configuran, Nginx enviará a los frontales la cabecera Host: frontend_servers y algunas aplicaciones web pueden generar URLs incorrectas o bucles de redirección cuando se utiliza HTTPS.

Habilite el nuevo Virtual Host que acaba de crear.

sudo ln -s /etc/nginx/sites-available/load-balancer.conf /etc/nginx/sites-enabled/

Recargue la configuración de Nginx.

sudo systemctl reload nginx

Nota: Si tiene algún problema al recargar el servicio de Nginx, puede ejecutar el siguiente comando para revisar la sintaxis del archivo de configuración.

sudo nginx -t

1.7 Métodos de balanceo de carga

Nginx nos permite configurar algunos métodos de balanceo de carga dentro de la directiva upstream.

1.8 Entregables

Deberá crear un repositorio en GitHub con el nombre de la práctica y añadir al profesor como colaborador.

El repositorio debe tener el siguiente contenido:

Además del contenido anterior, puede ser necesario crear otros archivos de configuración. A continuación se muestra un ejemplo de cómo puede ser la estructura del repositorio:

.
├── README.md
├── conf
│   ├── load-balancer.conf
│   └── 000-default.conf
└── scripts
    ├── .env
    ├── install_load_balancer.sh
    ├── install_lamp_frontend.sh
    ├── install_lamp_backend.sh
    ├── setup_letsencrypt_https.sh
    ├── deploy_frontend.sh
    └── deploy_backend.sh

1.8.1 Documento técnico

El documento técnico README.md tiene que estar escrito en Markdown y debe incluir como mínimo los siguientes contenidos:

1.8.2 Archivos de configuración

El directorio conf debe incluir los siguientes archivos:

1.8.3 Scripts de Bash

El directorio scripts debe incluir los siguientes archivos:

1.8.4 Configuración del proxy inverso a partir de una plantilla

Para no tener que editar manualmente el archivo de configuración de Nginx, se recomienda utilizar el archivo conf/load-balancer.conf como plantilla. Esta plantilla contiene unos valores que actúan como marcadores y que el script install_load_balancer.sh reemplazará por los valores reales definidos en el archivo .env.

Plantilla conf/load-balancer.conf

upstream frontend_servers {
    server IP_FRONTEND_1;
    server IP_FRONTEND_2;
}

server {
    listen 80;
    server_name DOMAIN_NAME;

    location / {
        proxy_pass http://frontend_servers;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Variables del archivo scripts/.env

# Direcciones IP privadas de los frontales web
FRONTEND_1_PRIVATE_IP=172.31.10.11
FRONTEND_2_PRIVATE_IP=172.31.10.12

# Nombre de dominio registrado
CERTIFICATE_DOMAIN=practica-nginx.example.org

Script scripts/install_load_balancer.sh

#!/bin/bash

# Muestra los comandos que se ejecutan y detiene el script si hay algún error
set -ex

# Importamos las variables de configuración
source .env

# Instalamos Nginx
apt update
apt install nginx -y

# Deshabilitamos el sitio por defecto (si sigue habilitado)
if [ -L /etc/nginx/sites-enabled/default ]; then
    unlink /etc/nginx/sites-enabled/default
fi

# Copiamos la plantilla al directorio de sitios disponibles
cp ../conf/load-balancer.conf /etc/nginx/sites-available/

# Reemplazamos los marcadores por los valores del archivo .env
sed -i "s/IP_FRONTEND_1/$FRONTEND_1_PRIVATE_IP/" /etc/nginx/sites-available/load-balancer.conf
sed -i "s/IP_FRONTEND_2/$FRONTEND_2_PRIVATE_IP/" /etc/nginx/sites-available/load-balancer.conf
sed -i "s/DOMAIN_NAME/$CERTIFICATE_DOMAIN/" /etc/nginx/sites-available/load-balancer.conf

# Habilitamos el sitio (-f sobrescribe el enlace si ya existe)
ln -sf /etc/nginx/sites-available/load-balancer.conf /etc/nginx/sites-enabled/

# Comprobamos la sintaxis y recargamos la configuración
nginx -t
systemctl reload nginx

El script se debe ejecutar desde el directorio scripts, ya que utiliza rutas relativas para acceder a los archivos .env y ../conf/load-balancer.conf:

cd scripts
sudo ./install_load_balancer.sh

Observe que la plantilla original del directorio conf no se modifica, ya que el comando sed -i se aplica sobre la copia que se encuentra en /etc/nginx/sites-available/. De este modo, el script se puede volver a ejecutar tantas veces como sea necesario.

2 Referencias

3 Licencia

Licencia de Creative Commons
Esta página forma parte del curso Implantación de Aplicaciones Web de José Juan Sánchez Hernández y su contenido se distribuye bajo una licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional.