Приватную сеть можно использовать для распределения выполнения загрузки и балансировки запросов между несколькими серверами. Рассмотрим организацию такой балансировки на примере HAProxy – бесплатного ПО, предназначенного для распределения нагрузки и организации проксирования TCP-пакетов между несколькими обслуживающими серверами.
Схема работы в рассматриваемом примере будет следующей:
- Первый сервер (с приватным IP-адресом 10.16.0.5, назовем его haproxy) будет принимать входящие HTTP-запросы. На нем будет запущен HAProxy, который будет распределять их по исполняющим серверам;
- Второй сервер (с приватным IP-адресом 10.16.0.7, назовем его nginx2) будет отдавать JPEG- и PNG-файлы – на нем будет запущен nginx, который будет получать запросы от HAProxy;
- Третий сервер (с приватным IP-адресом 10.16.0.6, назовем его nginx1) будет отдавать весь остальной контент – также через nginx.
Подготовка
Все три сервера будут работать на Ubuntu 20.04. На каждом из них получим и установим обновления системы:
apt update && apt upgrade -y
Установим nginx на серверах nginx1 и nginx2:
apt install nginx -y
На сервер nginx2 в папку /var/www/html положим картинку с осьминогом:
root@nginx2:/var/www/html# ll
total 320
drwxr-xr-x 2 root root 4096 Oct 19 06:33 ./
drwxr-xr-x 3 root root 4096 Oct 19 06:30 ../
-rw-r--r-- 1 root root 612 Oct 19 06:30 index.nginx-debian.html
-rw-r--r-- 1 root root 312162 Apr 26 14:48 octo.png
На сервере nginx1 создадим файл index.html с небольшой HTML-страницей и картинкой, которую мы будем брать с другого сервера:
root@nginx1:~# cat /var/www/html/index.html
<html>
<head>
<title>Beget HAProxy Test</title>
</head>
<body>
<h1>Beget HAProxy Test</h1>
<img src="octo.png">
</body>
</html>
Если мы сейчас попробуем обратиться напрямую к серверу nginx1 – то увидим, что изображение не загрузится, ведь его физически нет на сервере:

Установка HAProxy
Перейдем к установке и настройке HAProxy. Установим его из репозитория на сервер haproxy:
apt install haproxy -y
Откроем конфигурационный файл HAProxy (/etc/haproxy/haproxy.cfg
) любым текстовым редактором. Те настройки, которые уже объявлены в конфигураторе, мы изменять не будем.
Для начала укажем, что HAProxy будет принимать все входящие подключения на 80 порт:
frontend website
bind :80
В качестве бэкенд-серверов у нас будут два сервера с nginx – укажем их отдельно:
backend static
server static1 10.16.0.7:80
backend main
server main1 10.16.0.6:80
Сервера объявлены – теперь настроим правила балансировки. Расширим блок с объявлением frontend-сервера в конфигурационном файле – укажем, что если имя файла заканчивается на .jpg или .png, запрос должен уйти на сервер для статики, все остальное пусть обрабатывает основной сервер:
frontend website
bind :80
use_backend static if { path_end .jpg .png }
default_backend main
Весь конфигурационный файл будет выглядеть так:
root@haproxy:~# cat /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-A
ES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend website
bind :80
use_backend static if { path_end .jpg .png }
default_backend main
backend static
server static1 10.16.0.7:80
backend main
server main1 10.16.0.6:80
Сохраним конфиг и перезапустим HAProxy:
systemctl restart haproxy
Откроем браузер и попробуем обратиться к серверу haproxy – мы увидим страницу с изображением, а значит, все работает!

Если посмотреть логи запросов к nginx на конечных серверах – можно увидеть, что все запросы идут с приватного IP сервера, где поднят HAProxy. При этом на сервер для изображений пришли только запросы к .png:
root@nginx2:~# cat /var/log/nginx/access.log
10.16.0.5 - - [19/Oct/2021:06:56:09 +0000] "GET /octo.png HTTP/1.1" 200 312162 "http://45.147.177.163/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
10.16.0.5 - - [19/Oct/2021:06:56:23 +0000] "GET /octo.png HTTP/1.1" 200 312162 "http://45.147.177.163/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
Остальные запросы, как и было необходимо, ушли на другой сервер:
root@nginx1:~# cat /var/log/nginx/access.log
10.16.0.5 - - [19/Oct/2021:06:56:05 +0000] "GET / HTTP/1.1" 200 123 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
10.16.0.5 - - [19/Oct/2021:06:56:09 +0000] "GET /favicon.ico HTTP/1.1" 404 197 "http://45.147.177.163/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
10.16.0.5 - - [19/Oct/2021:06:56:23 +0000] "GET / HTTP/1.1" 200 123 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
С помощью HAProxy можно делать и более сложные цепочки правил распределения запросов, настраивать лимиты по количеству подключений, управлять таймаутами и многое другое. Более подробно о настройке HAProxy можно прочесть в официальной документации.
Свежие комментарии