Была поставлена задача о реализации отказоустойчивого решения для двух веб-серверов и, при возможности, реализация распределения нагрузки между веб-серверами, так как иногда одна база данных не справлялась со всеми запросами. Покупать специальное оборудование не было возможности, в связи с чем была придумана следующая схема. Возможно, идея неоригинальная, но в интернете ничего подобного не нашел. Топология у нас такая:
Есть Cisco Router, который выводит веб-сервера в интернет. Два веб-сервера на Centos 7 c nginx-ом. Ip адреса первого и второго веб-сервера — 192.168.20.176/24 и 192.168.20.177/24 соответственно. Для реализации плана, веб-серверам необходимо задать одинаковый вторичный ip адрес. Это может быть любой приватный ip адрес, который не используется в вашей сети. Я выбрал 192.168.120.175 и прописал его вторичным ip адресом основного интерфейса eth0 веб-серверов. На Centos-е это делается при помощи создания файла eth0:0 в директории /etc/sysconfig/network-scripts/. Содержимое файла:
TYPE="Ethernet"
DEVICE=eth0:0
BOOTPROTO="static"
IPADDR=192.168.120.175
NETMASK=255.255.255.255
ONBOOT="yes"
Важно заметить, что используется маска 255.255.255.255 и это позволяет избежать каких-либо ip конфликтов, так как веб-сервера не будут использовать его для генерации траффика. Так сказать, у нас будет Loopback интерфейсы на веб-серверах.
После этого, на маршрутизаторе можно реализовать распределение нагрузки при помощи статической маршрутизации. Данная технология реализуется при помощи Ip Cef на маршрутизаторах Cisco. Ссылка тут. У остальных вендоров, возможно, могут быть определенные нюансы.
В Cisco распределение потоков может быть двумя способами:
- Per-Destination (по умолчанию). Данный вариант нам и нужен. Все пакеты одного потока будут отправляться одному из двух серверов. Принцип работы заключается в том, что вычисляется хэш по source и destination ip адреса и в зависимости от этого хэша выбирается либо первый маршрут (сервер), либо второй. Далее, мы немного изменим данное поведение.
- Per-Packet. Данный вариант нам не подходит, так как балансировка будет происходит по пакетам. Грубо говоря, первый пакет по первому маршруту, второй пакет по второму.
Прописываем два маршрута это при помощи команд:
ip route 192.168.120.175 255.255.255.255 GigabitEthernet0/0 192.168.20.176
ip route 192.168.120.175 255.255.255.255 GigabitEthernet0/0 192.168.20.177
Таким образом, оба маршрута будут установлены в таблицу маршрутизации и по ним будет осуществляться распределение нагрузки:
Проверяем также правильно ли выбран способ балансировки:
Source IP адрес будет изменяться, а Destination IP всегда будет оставаться один. Это может влиять на равномерность балансировки, учитывая NAT. Для оптимизации можно учитывать source port, который будет рандомно разным, в зависимости от сессии клиента. Для этого используем следующую команду:
ip cef load-sharing algorithm include-ports source
Также надо настроить static NAT для перенапраления веб запросов на адрес 192.168.120.175:
ip nat inside source static tcp 192.168.120.175 80 interface GigabitEthernet0/1 80
Что же у нас получается? Запросы от пользователей из интернета будут попадать на наш маршрутизатор, который будет их распределять между нашими сервера по потокам, в зависимости от source port в TCP. При открытии новой сессии, клиент, возможно, попадет на новый сервер.
Что будет, если один из серверов упадет? Маршрут, который вел к этому серверу, будет удален из таблицы маршрутизации. Для оптимизации этого процесса можно использовать IP SLA. Следить за состояние серверов по пингу каждые 10 секунд:
ip sla 10
icmp-echo 192.168.20.176
frequency 10
ip sla schedule 10 life forever start-time now
ip sla 20
icmp-echo 192.168.20.177
frequency 10
ip sla schedule 20 life forever start-time now
Далее, добавив мониторинг к соответствующим маршрутам:
ip route 192.168.120.175 255.255.255.255 GigabitEthernet0/0 192.168.20.176 track 10
ip route 192.168.120.175 255.255.255.255 GigabitEthernet0/0 192.168.20.177 track 20
IP SLA на маршрутизаторах Cisco позволяет проводить мониторинг также по HTTP GET запросам, что поможет определить падение веб-сервера не только по его отсутствию в сети, но и при нерабочем состоянии веб сервиса.
Таким образом, для построение такой схемы не требуется дополнительное оборудование и какой-либо софт для веб-серверов. Необходим лишь маршрутизатор с возможностью балансировки траффика.
Автор: Ruslan_Mammadov