Обратный прокси на Nginx может оказаться очень полезным компонентом вашей инфраструктуры веб-сервисов, позволяя горизонтально масштабировать ресурсы между множеством серверов или виртуальных машин. С его помощью разные ресурсы (например blog.site.tld и forum.site.tld) можно разместить на разных экземплярах ОС.
Если вам интересна тематика Debian и связанных с ним приложений, рекомендую обратиться к тегу Debian на моем блоге
Содержание
Обратный прокси на Nginx
Чтение статей не избавляет вас от ответственности ознакомления с официальной 1 документацией! Также рекомендую обратиться к книге Администрирование сервера NGINX, из которой я почерпнул для себя множество нюансов, частично описанных в этой статье. Итак, начнем.
Предлагаю ознакомиться с другими статьями про Nginx на моем блоге:
Приятного чтения!
Балансировщик layer 7
Если в статье Простейший отказоустойчивый балансировщик layer 4 шла речь о балансировке на уровне tcp-соединений, то в этот раз я хочу рассказать про балансировку 7 уровня, на котором происходит анализ заголовков протоколов более высокого уровня (в частности http).
Подготовка
Сделаем бэкап основного конфига Nginx (всегда рекомендую начинать именно с этого):
1 |
cp /etc/nginx/nginx.conf{,.backup} |
Перенесем актуальные строчки конфигурации из бэкапа в основной nginx.conf:
1 |
sed '/^[^#]/!d;/^[[:space:]]*#.*$/d' /etc/nginx/nginx.conf.backup > /etc/nginx/nginx.conf |
Итоговый дефолтный конфиг для версии nginx 1.10.3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } |
Можно переходить к дальнейшей настройке.
Базовая конфигурация
Допустим на этом этапе ваша основная цель просто спрятать веб-ресурс за обратным прокси и не использовать какие-либо нестандартные настройки, начав, что называется, с простого. Для этого достаточно в секцию http (см. конфиг выше) добавить следующие настройки:
1 2 3 4 5 6 7 8 9 |
upstream blog { server 172.16.0.10:80; # your webserver's ip } server { server_name site.tld blog.site.tld; location / { proxy_pass http://blog; } } |
Не забываем перезапустить демона командой:
1 |
systemctl restart nginx.service |
Или:
1 |
service nginx restart |
Полная конфигурация:
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 |
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; upstream blog { server 172.16.0.10:80; # your webserver's ip } server { server_name site.tld blog.site.tld; location / { proxy_pass http://blog; } } } |
Выше я прописал лишь явно необходимые опции и опустил необязательные. Например nginx по умолчанию прослушивает порт 80, но это можно и не упоминать. Если нужно слушать на другом порту, вы можете задать опцию внутри секции server вот так:
1 2 3 4 5 |
server { listen 8080; server_name site.tld blog.site.tld; ... } |
По умолчанию используется режим балансировки round-robin, но вы можете выбрать другой и прописать его в секции upstream:
1 2 3 4 5 |
upstream blog { least_conn; server 172.16.0.10; # your webserver's ip ... } |
Если в будущем у вас появится несколько экземпляров серверов в вашем бэкэнд-пуле, не стесняйтесь добавлять их в конфигурацию. Вы можете сделать это с разными весами в зависимости от мощности серверов. В том числе поддерживается сценарий размещения на одном и том же сервере:
1 2 3 4 5 6 |
upstream blog { least_conn; server 172.16.0.10 weight=6; server 172.16.0.12:8080 weight=2; server 172.16.0.12:8081 weight=2; } |
Пришло время рассмотреть более разнообразные варианты.
Разные URL для одного домена
Может возникнуть ситуация, когда разные адреса нужно обрабатывать по-разному. Например при отдаче статического контента отправлять пользователей на один бэкэнд, а при запросе динамических данных – на другой. При этом никто вам не запрещает иметь несколько бэкэндов.
Вот как это может выглядеть:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
upstream blog { server 172.16.0.10; } upstream old_blog { server 172.16.0.15; } server { listen 8080; server_name site.tld blog.site.tld; location / { proxy_pass http://blog; } location /some-path/ { proxy_pass http://old_blog; } } |
Рассмотренный вариант конфигурации представляет из себя лишь базовую конструкцию, вы можете усложнить её дополнительными условиями и обработчиками.
Регулярные выражения
Дабы избежать излишнее размножение местоположений, рекомендуется использовать регулярные выражения 2 3. Разумеется, где это возможно:
1 2 3 |
location ~^/(old|archive)/ { proxy_pass http://old_blog; } |
Стоит отметить, что nginx будет выбирать вариант с наиболее точным соответствием.
Несколько доменов
Один из распространенных вариантов конфигурации – необходимость обработки нескольких доменных имен. В зависимости от того или иного имени может понадобиться разная логика обработки.
Вот так может выглядеть ваша конфигурация:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
server { listen 8080; server_name site.tld blog.site.tld; location ~^/(old|archive)/ { ... } ... } server { listen 8080; server_name old-site.site.tld old-archive.site.tld; location / { ... } ... } |
На этом базовой информации для быстрого старта должно быть достаточно.