Как стать автором
Обновить

Настройка Nginx multiple reverse proxy для k3s+istio

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров7K

Немного воды

Всем читателям, привет! Хочется поделиться своим опытом по созданию Nginx reverse proxy для интересного кейса. Не судите строго но критике и предложениям буду рад.

Начало

Поступил вызов о необходимости реализации следующего кейса:

  • Есть 1 ip и на него нацелено n доменов

  • Есть n серверов (за NAT)

  • Когда пользователь заходит на домен_1 попадает на сервер_1

  • Когда пользователь заходит на домен_2 попадает на сервер_2

  • Когда пользователь заходит на домен_n попадает на сервер_n

Казалось бы, тривиальная задача... Но не с инфраструктурой которая есть

Немного о инфраструктуре

Из за отсутствия необходимости реверсивного прокси схема инфраструктуры выглядела так как на рис.1.

рис.1
рис.1

Естественно, для реализации кейса, необходимо было встроить Nginx в эту схему. Итоговая схема представлена на рис.2

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

Настройка Nginx reverse proxy

Немного вводных:

  1. ОС виртуализации Centos7

  2. Iptables настроен на полный запрет иных портов кроме 443

  3. Istio нацелен на доменное имя которое соответствует ВМ

Так как у меня ОС Centos7 конфиги http и server будут совмещены. Но важно понимать что если у вас раздельные конфиги как в Ubuntu это так же будет работать. Главное поместить нужный код в нужные места ;)

Итоговый конфиг для nginx выглядит так:

worker_processes 10;
    events {
    worker_connections 1024;
}
http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    #ВМ_1
    server {
        server_name test1.domain.ru;
        listen       443 ssl;
        listen [::]:443 ssl;
        ssl_certificate      /home/CERT.crt;
        ssl_certificate_key  /home/CERT.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_protocols        TLSV1.1 TLSV1.2 TLSV1.3;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        location / {
            proxy_pass https://192.168.0.21;
            proxy_http_version  1.1;
            proxy_cache_bypass  $http_upgrade;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Host  $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Port  $server_port;
        }
    #ВМ_2
    server {
        server_name test2.domain.ru;
        listen       443 ssl;
        listen [::]:443 ssl;
        ssl_certificate      /home/CERT.crt;
        ssl_certificate_key  /home/CERT.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_protocols        TLSV1.1 TLSV1.2 TLSV1.3;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        location / {
            proxy_pass https://192.168.0.21;
            proxy_http_version  1.1;
            proxy_cache_bypass  $http_upgrade;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Host  $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Port  $server_port;
        }
    }
    #ВМ_n
    server {
        server_name testn.domain.ru;
        listen       443 ssl;
        listen [::]:443 ssl;
        ssl_certificate      /home/CERT.crt;
        ssl_certificate_key  /home/CERT.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_protocols        TLSV1.1 TLSV1.2 TLSV1.3;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        location / {
            proxy_pass https://192.168.0.x;
            proxy_http_version  1.1;
            proxy_cache_bypass  $http_upgrade;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Host  $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Port  $server_port;
        }
    }
}

Теперь давайте немного разберем основные параметры.

Общий блок:

  • worker_processes - Колличество возможных рабочих процессов при подключении к одному IP. Как правило, на ядро запускается 1 рабочий процесс;

  • worker_processes - Колличество пользователей могут одновременно обслуживаться Nginx;

Блок http {

  • keepalive_timeout - Максимальное время поддержания keepalive-соединения, в случае, если пользователь по нему ничего не запрашивает.

Блок http { server {

  • server_name - Ожидаемое доменное имя по которому будет доступен сервер. Например testn.domain.ru

  • listen - Указывает на порт по которому будет доступен сервер. В случае с https/443 необходимо контролировать наличие подписи ssl в строке.

  • ssl_certificate/ssl_certificate_key - доменнные сертификаты

  • ssl_session_cache - Кеширование сессий. Необходимо для повторного использования ключей, чтобы не повторять хэндшейк.

  • ssl_protocols - Определение возможных TLS протоколов для работы с сервером.

Блок http { server { location / {

ВАЖНО
В случае если у вас есть фронт с url testn.domain.ru/front не получится использовать другие location кроме как корневой (/). Связано с передачей url от nginx на сервер во время proxy. istio будет отбивать такие запросы и rewrite не поможет

  • proxy_pass - Сервер на которое осуществляется проксирование домена, указанного в server_name блока server. 

  • proxy_http_version - Позволяет использовать HTTP/1.1 вместо дефолтного параметра HTTP/1.0

  • proxy_cache_bypass - В нашем случае не отдаются данные об изменении http запроса ($http_upgrade)

  • proxy_set_header - Записывает заголовки для передачи на сервер назначения proxy_pass

Подробнее можете почитать в доках nginx.

Должен отметить что по незнанию к такому конфигу я шел достаточно долго. 3 рабочих дня если быть точным.
Я долго не мог заставить дружить istio и nginx и перелопатил кучу информации. И что в итоге? Самый важный параметр всего этого конфига - это proxy_cache_bypass.

В чем же суть этого proxy_cache_bypass?
proxy_cache_bypass
 — Задает условия, при которых nginx не станет брать ответ из кэша, а сразу перенаправит запрос на бэкенд. Если хотя бы один из параметров не пустой и не равен “0”. Подробнее почитайте вот тут

В итоге у нас получается достаточно гибкая конфигурация прокси сервера которую легко аадминистрировать. Основной изменяемый/удаляемый/добавляемый блок - это блок http { server {

    #ВМ_n
    server {
        server_name testn.domain.ru;
        listen       443 ssl;
        listen [::]:443 ssl;
        ssl_certificate      /home/CERT.crt;
        ssl_certificate_key  /home/CERT.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_protocols        TLSV1.1 TLSV1.2 TLSV1.3;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
        location / {
            proxy_pass https://192.168.0.x;
            proxy_http_version  1.1;
            proxy_cache_bypass  $http_upgrade;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Host  $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Port  $server_port;
        }
    }

Итоги

На мой взгляд получилась достаточно гибкая конфигурация отвечающая всем условиям кейса. Надеюсь будет полезно. Спасибо за внимание.

Теги:
Хабы:
Всего голосов 1: ↑1 и ↓0+1
Комментарии14

Публикации

Истории

Работа

DevOps инженер
43 вакансии

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область