Nginx как настроить балансировку

Балансировка нагрузки с помощью NGINX

В данной инструкции мы рассмотрим процесс настройки балансировки, в основном, http-запросов с помощью веб-сервера NGINX. По большей части, инструкция подойдет для любого дистрибутива Linux, и даже, Windows (за исключением путей расположения конфигурационных файлов). Таким образом настроенный NGINX сможет обеспечить распределение нагрузки и отказоустойчивость нашим сетевым сервисам.

Обратите внимание, что NGINX умеет распределять не только http-запросы. Его можно использовать для балансировки запросов на 4-м уровне модели OSI (TCP и UDP), например, подключения к СУБД, DNS и так далее — по сути, любой сетевой запрос может быть обработан и распределен с помощью данного программного продукта.

Постепенно рассмотрим разные варианты настройки распределения нагрузки в NGINX. Начнем с простого понимания, как работает данная функция и закончим некоторыми примерами настройки балансировки.

Основы

Чтобы наш сервер мог распределять нагрузку, создадим группу веб-серверов, на которые будут переводиться запросы:

* в данном примере мы создаем файл upstreams.conf, в котором можем хранить все наши апстримы. NGINX автоматически читает все конфигурационные файлы в каталоге conf.d.

upstream dmosk_backend <
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

* предполагается, что в нашей внутренней сети есть кластер из трех веб-серверов — 192.168.10.10, 192.168.10.11 и 192.168.10.12. Мы создали апстрим с названием dmosk_backend. Позже, мы настроим веб-сервер, чтобы он умел обращаться к данному бэкенду.

В настройках сайта (виртуального домена) нам необходимо теперь проксировать запросы на созданный upstream. Данная настройка будет такой:

server <
.
location / <
proxy_pass http://dmosk_backend;
>
.
>

* данная настройка для нашего сайта укажет, что все запросы мы должны переводить на апстрим dmosk_backend (который, в свою очередь, будет отправлять запросы на три сервера).

Проверяем корректность нашего конфигурационного файла:

Если ошибок нет, перезапускаем сервис:

systemctl restart nginx

Приоритеты

При настройке бэкендов мы можем указать, кому наш веб-сервер будет отдавать больше предпочтение, а кому меньше.

Синтаксис при указании веса:

По умолчанию приоритет равен 1.

Также мы можем указать опции:

  • backup, которая будет говорить о наличие резервного сервера, к которому будет выполняться подключение только при отсутствии связи с остальными.
  • down, при указании которой, сервер будет считаться постоянно недоступным. Может оказаться полезной, чтобы остановить временно запросы для проведения обслуживания.

Давайте немного преобразуем нашу настройку upstreams:

upstream dmosk_backend <
server 192.168.10.10 weight=100 ;
server 192.168.10.11 weight=10 ;
server 192.168.10.12;
server 192.168.10.13 backup ;
>

* итак, мы указали нашему серверу:

  • переводить на сервер 192.168.10.10 в 10 раз больше запросов, чем на 192.168.10.11 и в 100 раз больше — чем на 192.168.10.12.
  • переводить на сервер 192.168.10.11 в 10 раз больше запросов, чем на 192.168.10.12.
  • на сервер 192.168.10.13 запросы переводятся, только если не доступны все три сервера.

Задержки, лимиты и таймауты

По умолчанию, NGINX будет считать сервер недоступным после 1-й неудачной попытки отправить на него запрос и в течение 10 секунд не будут продолжаться попытки работы с ним. Также каждый сервер не имеет ограничений по количеству к нему подключений.

Изменить поведение лимитов и ограничений при балансировке можно с помощью опций:

  • max_fails — количество неудачных попыток, после которых будем считать сервер недоступным.
  • fail_timeout — время, в течение которого сервер нужно считать недоступным и не отправлять на него запросы.
  • max_conns — максимальное число подключений, при превышении которого запросы на бэкенд не будут поступать. По умолчанию равно 0 (безлимитно).

server max_fails= fail_timeout= ;

В нашем примере мы преобразуем настройку так:

upstream dmosk_backend <
server 192.168.10.10 weight=100 max_conns=1000 ;
server 192.168.10.11 weight=10 max_fails=2 fail_timeout=90s ;
server 192.168.10.12 max_fails=3 fail_timeout=2m ;
server 192.168.10.13 backup;
>

  • сервер 192.168.10.10 будет принимать на себя, максимум, 1000 запросов.
  • сервер 192.168.10.10 будет иметь настройки по умолчанию.
  • если на сервер 192.168.10.11 будет отправлено 2-е неудачные попытки отправки запроса, то в течение 90 секунд на него не будут отправлять новые запросы.
  • сервер 192.168.10.12 будет недоступен в течение 2-х минут, если на него будут отправлены 3 неудачных запроса.
Читайте также:  Приложение hdrezka не работает поиск

Метод балансировки

Рассмотрим способы балансировки, которые можно использовать в NGINX:

  1. Round Robin.
  2. Hash.
  3. IP Hash.
  4. Least Connections.
  5. Random.
  6. Least Time (только в платной версии NGINX).

Настройка метода балансировки выполняется в директиве upstream. Синтаксис:

Round Robin

Веб-сервер будет передавать запросы бэкендам по очереди с учетом их весов. Данный метод является методом по умолчанию и его указывать в конфигурационном файле не нужно.

Данный метод определяет контрольную сумму на основе переменных веб-сервера и ассоциирует каждый полученный результат с конкретным бэкендом. Пример настройки:

upstream dmosk_backend <
hash $scheme$request_uri;
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

* это самый распространенный пример настройки hash — с использованием переменных $scheme (http или https) и $request_uri. При данной настройке каждый конкретный URL будет ассоциирован с конкретным сервером.

IP Hash

Ассоциация выполняется исходя из IP-адреса клиента и только для HTTP-запросов. Таким образом, для каждого посетителя устанавливается связь с одним и тем же сервером. Это, так называемый, Sticky Session метод.

Для адресов IPv4 учитываются только первые 3 октета — это позволяет поддерживать одинаковые соединения с клиентами, чьи адреса меняются (получение динамических адресов от DHCP провайдера). Для адресов IPv6 учитывается адрес целиком.

upstream dmosk_backend <
ip_hash;
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

Least Connections

NGINX определяет, с каким бэкендом меньше всего соединений в данный момент и перенаправляет запрос на него (с учетом весов).

Настройка выполняется с помощью опции least_conn:

upstream dmosk_backend <
least_conn;
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

Random

Запросы передаются случайным образом (но с учетом весов). Дополнительно можно указать опцию two — если она задана, то NGINX сначала выберет 2 сервера случайным образом, затем на основе дополнительных параметров отдаст предпочтение одному из них. Это следующие параметры:

  • least_conn — исходя из числа активных подключений.
  • least_time=header (только в платной версии) — на основе времени ответа (расчет по заголовку).
  • least_time=last_byte (только в платной версии) — на основе времени ответа (расчет по полной отдаче страницы).

upstream dmosk_backend <
random two least_conn;
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

Least Time

Данная опция будет работать только в NGINX Plus. Балансировка выполняется исходя из времени ответа сервера. Предпочтение отдается тому, кто отвечает быстрее.

Опция для указания данного метода — least_time. Также необходимо указать, что мы считаем ответом — получение заголовка (header) или когда страница возвращается целиком (last_byte).

upstream dmosk_backend <
least_time header;
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

* в данном примере мы будем делать расчет исходя из того, как быстро мы получаем в ответ заголовки.

upstream dmosk_backend <
least_time last_byte;
server 192.168.10.10;
server 192.168.10.11;
server 192.168.10.12;
>

* в данном примере мы будем делать расчет исходя из того, как быстро мы получаем в ответ целую страницу.

Сценарии настройки

В реальной жизни настройки могут быть несколько сложнее, чем приведенные здесь или в официальной документации. Рассмотрим несколько примеров, что может понадобиться настроить при балансировке.

1. Backend на https

Предположим, что наши внутренние серверы отвечают по SSL-каналу. Таким образом, нам нужно отправлять запрос по порту 443. Также схема проксирования должна быть https.

Настройка сайта:

server <
.
location / <
proxy_pass https://dmosk_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
>
.
>

* обратите внимание на 2 момента:

  1. Мы в схеме подключения proxy_pass указали https. В противном случае при подключении NGINX будет возвращать ошибку 400.
  2. Мы задали дополнительные опции proxy_set_header, которых не было в примерах выше.

Настройка upstream:

upstream dmosk_backend <
server 192.168.10.10:443;
server 192.168.10.11:443;
server 192.168.10.12:443;
>

* в данном примере мы указали конкретный порт, по которому должно выполняться соединение с бэкендом. Для упрощения конфига дополнительные опции упущены.

2. Разные бэкенды для разных страниц

Нам может понадобиться разные страницы сайта переводить на разные группы внутренних серверов.

Настройка сайта:

server <
.
location /page1 <
proxy_pass http://backend1;
>

location /page2 <
proxy_pass http://backend2;
>
.
>

* при такой настройке мы будем передавать запросы к странице page1 на группу backend1, а к page2 — backend2.

Настройка upstream:

upstream backend1 <
server 192.168.10.10;
server 192.168.10.11;
>

upstream backend2 <
server 192.168.10.12;
server 192.168.10.13;
>

* в данном примере у нас есть 2 апстрима, каждый со своим набором серверов.

3. На другой хост

Может быть необходимым делать обращение к внутреннему ресурсу по другому hostname, нежели чем будет обращение к внешнему. Для этого в заголовках проксирования мы должны указать опцию Host.

Читайте также:  Head up display не работает

Настройка сайта:

server <
.
location / <
proxy_pass https://dmosk_backend;
proxy_set_header Host internal.domain.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
>
.
>

* в данном примере мы будем проксировать запросы на бэкенды, передавая им имя хоста internal.domain.com.

4. TCP-запрос

Рассмотрим, в качестве исключения, TCP-запрос на порт 5432 — подключение к базе PostgreSQL.

Настройка сайта:

server <
listen 5432;
proxy_pass tcp_postgresql;
>

* в данном примере мы слушаем TCP-порт 5432 и проксируем все запросы на апстрим tcp_postgresql.

Настройка upstream:

upstream tcp_postgresql <
server 192.168.10.14:5432;
server 192.168.10.15:5432;
>

* запросы будут случайным образом передаваться на серверы 192.168.10.14 и 192.168.10.15.

5. UDP-запрос

Рассмотрим также и возможность балансировки UDP-запросов — подключение к DNS по порту 53.

Настройка сайта:

server <
listen 53 udp;
proxy_pass udp_dns;
proxy_responses 1;
>

* в данном примере мы слушаем UDP-порт 53 и проксируем все запросы на апстрим udp_dns. Опция proxy_responses говорит о том, что на один запрос нужно давать один ответ.

Настройка upstream:

upstream udp_dns <
server 192.168.10.16:53;
server 192.168.10.17:53;
>

* запросы будут случайным образом передаваться на серверы 192.168.10.16 и 192.168.10.17.

Читайте также

Возможно, данные инструкции также будут полезны:

Источник

Настройка балансировки нагрузки Nginx и SSL-терминации

Данное руководство покажет, как настроить балансировку нагрузки Nginx и SSL-терминацию, используя всего один SSLсертификат на балансировщике нагрузки. Это позволяет сократить расходы на управление SSL, так как управлять обновлениями OpenSSL, ключами и сертификатами теперь можно с самого балансировщика.

Что такое терминация SSL?

Nginx можно настроить как балансировщик нагрузки, что позволяет распределять входящий трафик между несколькими внутренними серверами. SSL-терминация является процессом на балансировщике нагрузки, который обрабатывает шифрование и дешифровку SSL таким образом, чтобы трафик между балансировщиком и внутренними серверами был в HTTP. Серверы на бэкэнде должны быть защищены путем ограничения доступа к IP балансировщика нагрузки, о чём и пойдёт рчь в данной статье.

Требования

Все команды нужно запускать с правами root или sudo. Подробнее об этом можно прочитать в этом руководстве.

Кроме того, могут оказаться полезными следующие руководства:

В целом, стек LAMP не является обязательным, но далее он будет использован в качестве примера.

Подготовка серверов

В данном руководстве будет использовано три облачных сервера:

Сервер 1 (фронт-энд)

  • Ubuntu 14.04
  • Имя хоста: loadbalancer
  • IP-адрес: 10.130.227.33

Сервер 2 (бэкэнд)

  • Ubuntu 14.04
  • Имя хоста: web1
  • IP-адрес: 10.130.227.11

Сервер 3 (бэкэнд)

  • Ubuntu 14.04
  • Имя хоста: web2
  • IP-адрес: 10.130.227.22

Условное доменное имя – example.com.

Кроме того, на всех серверах нужно включить поддержку частной сети.

Обновите программы на всех серверах:

apt-get update && apt-get upgrade -y

Перезапустите каждый сервер, чтобы активировать обновления. Это очень важно, так как для работы понадобится последняя версия OpenSSL.

Далее нужно будет создать для домена новый виртуальный хост Nginx с модулем upstream.

Если веб-сервер Nginx не был установлен на облачный сервер ранее, установите его при помощи команды:

apt-get install nginx

На серверах бэкэнда обновите репозитории и установите Apache:

apt-get install apache2

Также на эти серверы нужно установить PHP:

apt-get install php5 libapache2-mod-php5 php5-mcrypt

Примечание: Более подробную информацию по установке этих программ можно найти здесь.

Генерирование ключей и создание SSL-сертификата

Примечание: Подробнее об этом можно прочесть здесь.

Создайте каталог для хранения SSL-сертификата и перейдите в него:

mkdir -p /etc/nginx/ssl/example.com
cd /etc/nginx/ssl/example.com

Создайте закрытый ключ:

openssl genrsa -des3 -out server.key 2048

Удалите фразовый пароль:

openssl rsa -in server.key -out server.key

Создайте запрос на подпись сертификата (CSR):

openssl req -new -key server.key -out server.csr

Используйте этот CSR, чтобы подписать сертификат в надёжном центре сертификации, или же создайте самоподписанный сертификат при помощи команды:

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

После этого в каталоге появятся следующие файлы:

  • server.key – закрытый ключ
  • ca-certs.pem – промежуточные сертификаты (появится только в случае подписи сертификата в ЦС).
  • server.crt – SSL-сертификат для доменного имени.

Виртуальный хост и модуль Upstream

Создайте виртуальный хост в каталоге Nginx:

nano /etc/nginx/sites-available/ example.com

Добавьте модуль upstream, указав IP-адреса серверов бэкэнда:

upstream mywebapp1 <
server 10.130.227.11 ;
server 10.130.227.22 ;
>

После этой строки внесите в файл хоста код блока server. Этот код содержит доменное имя, ссылки на серверы upstream и заголовки, которые нужно передать бэкэнду.

Читайте также:  Как можно унитаз починить

server <
listen 80;
server_name example.com www.example.com ;
location / <
proxy_pass http:// mywebapp1 ;
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;
>
>

Директива proxy_set_header используется для передачи важной информации о запросе серверам upstream.

Сохраните файл и создайте символьную ссылку на каталог sites-enabled.

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Проверьте конфигурацию на наличие ошибок.

service nginx configtest

Если ошибок не обнаружено, перезапустите сервер nginx.

service nginx reload

Теперь настройка балансировки нагрузки для HTTP завершена.

Включение SSL

Добавьте следующие директивы в файл виртуального хоста (/etc/nginx/sites-available/example.com) в блок server <>.

listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/example.com/server.crt ;
ssl_certificate_key /etc/nginx/ssl/example.com/server.key ;
ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem ;

Пропустите директиву ssl_trusted_certificate, если вы используете самоподписанный сертификат. Теперь блок server выглядит так:

server <
listen 80;
listen 443 ssl;
server_name example.com www.example.com ;
ssl on;
ssl_certificate /etc/nginx/ssl/ example.com /server.crt;
ssl_certificate_key /etc/nginx/ssl/ example.com /server.key;
ssl_trusted_certificate /etc/nginx/ssl/ example.com /ca-certs.pem;
location / <
proxy_pass http:// mywebapp1 ;
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;
>
>

Проверьте код на наличие ошибок и перезапустите сервер Nginx:

service nginx configtest && service nginx reload

Защита серверов бэкэнда

В настоящее время сайт размещается на серверах бэкэнда, доступных любому пользователю, который знает их внешний IP-адрес. Это необходимо исправить; для этого нужно настроить эти серверы для прослушивания только персонального интерфейса. На веб-сервере Apache это делается следующим образом.

Найдите следующую строку:

Замените номер порта закрытым IP-адресом сервера, например:

Listen 10.130.227.22 :80

Выполните это на всех серверах бэкэнда и перезапустите Apache.

service apache2 restart

Затем нужно ограничить HTTP-доступ к внутреннему IP балансировщика нагрузки. Для этого добавьте следующее правило брандмауэра:

iptables -I INPUT -m state —state NEW -p tcp —dport 80 ! -s 10.130.227.33 -j DROP

Не забудьте указать свой IP-адрес.

Тестирование настройки

Создайте файл PHP на всех серверах бэкэнда (в данном случае web1 и web2). Он нужен для тестирования, после этого его можно удалить.

Он должен содержать доменное имя, IP-адрес сервера, IP-адрес пользователя, и порт для доступа.

Откройте этот файл в браузере несколько раз при помощи команды curl.

Примечание: В случае использования самоподписанного сертификата используйте команду curl –k, чтоб игнорировать ошибки SSL.

curl https:// example.com /test.php https:// example.com /test.php https:// example.com /test.php

Вывод будет выглядеть так:

Host: example.com
Remote Address: 10.130.245.116
X-Forwarded-For: 117.193.105.174
X-Forwarded-Proto: https
Server Address: 10.130.227.11
Server Port: 80
Host: example.com
Remote Address: 10.130.245.116
X-Forwarded-For: 117.193.105.174
X-Forwarded-Proto: https
Server Address: 10.130.227.22
Server Port: 80
Host: example.com
Remote Address: 10.130.245.116
X-Forwarded-For: 117.193.105.174
X-Forwarded-Proto: https
Server Address: 10.130.227.11
Server Port: 80

Обратите внимание: Server Address изменяется при каждом запросе, а это значит, что запросы обрабатываются разными серверами.

Защита SSL

В данном разделе показано, как защитить SSL от уязвимостей. Полный код можно найти в конце раздела.

Включение кэша SSL-сессий увеличивает производительность сайтов HTTPS. Добавьте следующие директивы после ssl_trusted_certificate. Это включит кэш в 20 мегабайт со сроком хранения в 10 минут.

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;

Укажите протоколы и шифры, используемые для подключения SSL. Ниже пропущен SSLv2 и отключены ненадёжные шифры (такие как MD5 и DSS).

ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

Strict Transport Security рекомендует браузерам использовать только HTTPS. Для этого добавьте директиву add_header:

add_header Strict-Transport-Security «max-age=31536000»;

Проверьте конфигурации на наличие ошибок и перезапустите Nginx.

service nginx configtest && service nginx reload

Полная конфигурация

В результате настройки и защиты SSL конфигурационный файл будет иметь такой вид:

/etc/nginx/sites-available/ example.com
upstream mywebapp1 <
server 10.130.227.11 ;
server 10.130.227.22 ;
>
server <
listen 80;
listen 443 ssl;
server_name example.com www.emxaple.com ;
ssl on;
ssl_certificate /etc/nginx/ssl/example.com/server.crt ;
ssl_certificate_key /etc/nginx/ssl/example.com/server.key ;
ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem ;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
add_header Strict-Transport-Security «max-age=31536000»;
location / <
proxy_pass http:// mywebapp1 ;
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;
>
>

Выполните SSL Server Test, чтобы убедиться, что эта конфигурация надёжна.

Запустите curl, и вы увидите, что всё работает должным образом:

curl https:// example.com /test.php https:// example.com /test.php https:// example.com /test.php

Примечание: Дополнительную информацию о настройке балансировки нагрузки можно получить здесь.

Источник

Оцените статью