avatar Ubuntu Балансировка сетевой нагрузки с помощью DNS сервера Bind в Ubuntu - DNS Round-Robin

Иногда, когда проект вырастает до больших размеров, ему требуется масштабируемость, целью которой является, повышение производительности системы.
Масштабируесть бывает 2х видов: горизонтальная и вертикальная.
Вертикальная осуществляется за счет увеличения ресурсов самого сервера, например-добавление процессоров или оперативной памяти.
Горизонтальная осуществляется за счет увеличения количества серверов.
Как-то я уже писал про технологию балансировки сетевой нагрузки WEB серверов, в статье Балансировка сетевой нагрузки с помощью Nginx, там система работала на одном балансировщике и 3х WEB серверах, также в качестве примера была представлена схема работы mail.ru, доступ к которой осуществлялся через 4 маршрутизатора, но что находилось за ними, для нас осталось тайной. В этой статье я попытаюсь немного рассказать о том как осуществляется работа похожей схемы. Также, крайне рекомендую, ознакомиться со статьей по настройке DNS-сервера BIND, на ее основе будет поднят тестовый DNS сервер, 3 сервера поднимать нет необходимости, в качестве тестового полигона нам хватит и одного DNS сервера.

round-robin

Для примера, у нас, во внешний мир, будет выставлено 4 балансировщика нагрузки, а сколько их будет находиться внутри, для пользователя, который подключается к нашему сервису, не будет известно, но для тех кто это создавал, все будет логично и просто, а главное, это работает и является отлично управляемой системой!
Собственно, нас интересует только 4 сервера которые выставлены в интернет +1 DNS север, но в взаимодействие с ними осуществляется за счет службы DNS. Для тестирования нет необходимости поднимать все 4 WEB сервера, достаточно указать 4 IP адреса.
Обращаю ваше внимание, что мы НЕ будем конфигурировать WEB сервера, а попробуем немного «запилить» DNS сервер Bind, чтобы он распределял запросы между серверами. Я уже написал о том как настроить DNS сервер в статье: Настройка DNS-сервера BIND Master & Slave, все дальнейшие действия мы будем стоить на ее основе, правда 3 сервера разворачивать совершенно не обязательно, для тестирования хватит и одного.
Предполагается что DNS сервер Bind настроен и работает.
В качестве примера, мой DNS сервер будет иметь IP 192.168.1.10

Настройка файла зоны
Если DNS был сделан по статье, ссылку на которую я привел ранее, то у вас есть файл с настройками зоны:
nano /var/lib/bind/example.org.db


Со следующим содержимым:

$TTL 3600      ;
example.org.        IN      SOA     ns01.example.org. root.example.org. (
                                1        ; Serial
                                600      ; Refresh
                                3600     ; Retry
                                1w       ; Expire
                                300      ; Minimum TTL
                        )
        IN      NS      ns01.example.org.
        IN      NS      ns02.example.org.
        IN      NS      ns03.example.org.
        IN      A       192.168.10.20
ns01    IN      A       192.168.10.50
ns02    IN      A       192.168.10.60
ns03    IN      A       192.168.10.70
www     IN      A       192.168.10.20
test    IN      A       192.168.10.12


Давайте почистим файл от всего лишнего, чтобы не путаться, ну и укажем IP адреса, который обслуживаются в данны момент и оставим только:
$TTL 3600      ;
example.org.        IN      SOA     ns01.example.org. root.example.org. (
                                1        ; Serial
                                600      ; Refresh
                                3600     ; Retry
                                1w       ; Expire
                                300      ; Minimum TTL
                        )
        IN      NS      ns01.example.org.
        IN      NS      ns02.example.org.
        IN      NS      ns03.example.org.
        IN      A       192.168.10.20
ns01    IN      A       192.168.1.10
ns02    IN      A       192.168.1.60
ns03    IN      A       192.168.1.70


Настраиваем распределение запросов к адресу example.org

Давайте представим ситуацию, что у нас есть сайт example.org запросы к которому мы хотим распределять между четырьмя серверами с IP адресами:
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4

Также у нам нужно сделать возможность чтобы пользователи могли заходить по адресу www.example.org www- используется довольно давно, и многие пользователи набирают его на автомате, считая что сайтов без www не бывает, в общем нам нужно обеспечить полный доступ чтобы ни один клиент не пропал и не получил ошибку что сайт не найден.

В данным момент в конфигурационном файле запись example.org ведет на IP 192.168.10.20 (попробуйте найти запись отвечающую за это).
Для начала нам нужно обеспечить распределение запросов добавив соответствующую запись:
nano /var/lib/bind/example.org.db


$TTL 3600      ;
example.org.        IN      SOA     ns01.example.org. root.example.org. (
                                1        ; Serial
                                600      ; Refresh
                                3600     ; Retry
                                1w       ; Expire
                                300      ; Minimum TTL
                        )
        IN      NS      ns01.example.org.
        IN      NS      ns02.example.org.
        IN      NS      ns03.example.org.

example.org.        IN      A       10.0.0.1
example.org.        IN      A       10.0.0.2
example.org.        IN      A       10.0.0.3
example.org.        IN      A       10.0.0.4

ns01    IN      A       192.168.1.10
ns02    IN      A       192.168.1.60
ns03    IN      A       192.168.1.70


Сохраняем изменения перезапускаем Bind
/etc/init.d/bind9 restart


Теперь выполним запрос с клиентского ПК к нашему DNS серверу (у меня клиент windows):
nslookup example.org 192.168.1.10

Где:
nslookup -команда выполнения запроса к DNS серверу
example.org — запись которую мы запрашиваем
192.168.1.10 -IP адрес сервера у которого мы пытаемся получить запрос.
В ответ, мы получим то что указано на скриншоте:
nslookup example.org

Если выполнить запрос еще раз, то вы увидите что IP, который стоит первым в списке, меняется и клиенту при каждом запросе вдается другой IP.
теперь попробуем выполнить запрос к адресу www.example.org
nslookup www.example.org 192.168.1.10

Это завершиться ошибкой т.к. этой записи не существует-пока…
Возвращаемся к
nano /var/lib/bind/example.org.db

Можно «запилить» запись вида:
www        IN      A       10.0.0.1
www        IN      A       10.0.0.2
www        IN      A       10.0.0.3
www        IN      A       10.0.0.4

И это будет работать, уж поверьте, благодаря разработчикам Bind, он и не такую ахинею «переваривает».
В общем данная запись является дурным тоном и показателем малограмотности человека который это настраивает.
Для подобный целей есть запись типа cname, следите за мыслью:

www.example.org->ведет к->example.org->к нужным IP адресам

Создаем запись www.example.org
Запись CNAME имеет следующий вид:
www     IN      CNAME   example.org.

Точка, в конце, ОБЯЗАТЕЛЬНА!!!

В результате всех действий у нас получится файл со следующим содержанием:
$TTL 3600      ;
example.org.        IN      SOA     ns01.example.org. root.example.org. (
                                1        ; Serial
                                600      ; Refresh
                                3600     ; Retry
                                1w       ; Expire
                                300      ; Minimum TTL
                        )
        IN      NS      ns01.example.org.
        IN      NS      ns02.example.org.
        IN      NS      ns03.example.org.

example.org.        IN      A       10.0.0.1
example.org.        IN      A       10.0.0.2
example.org.        IN      A       10.0.0.3
example.org.        IN      A       10.0.0.4
www     IN      CNAME   example.org.

ns01    IN      A       192.168.10.50
ns02    IN      A       192.168.10.60
ns03    IN      A       192.168.10.70

Сохраняем изменения перезапускаем Bind
/etc/init.d/bind9 restart


Выполним запрос:
nslookup www.example.org 192.168.1.10

получаем
nslookup www.example.org
Распределение запросов работает нормально, но тут возникает один момент. Каждая запись имеет срок жизни, который определяется параметром TTL (time to live), с помощью которого определяется ее актуальность т.к. клиентское устройство будет хранить у себя в кеше, пока не закончится срок жизни данной записи, после этого запись будет считаться не актуальной и будет выполнен следующий запрос к DNS серверу, проблема в том что клиент получив IP будет все время ломиться на него+кеширующие DNS сервера провайдеров, получив первый IP адрес будут перенаправлять клиентов на один IP, в результате на одном IP адресе может создаться высокая нагрузка, а другие будут простаивать. Чтобы распределить нагрузку более равномерно, нам нужно уменьшить вермя жизни записей, чтобы они быстро устаревали, и клиенты обращались снова к DNS серверу. Записи всей зоны у нам трогать нет необходимости, требуется уменьшить время жизни только для тех записей где производится распределение нагрузки. В документации от разработчиков BIND указано что оптимально указывать время жизни 5 мин ( остальное подбирается экспериментально исходя из ваших условий) вот это мы и будем использовать. Если срок жизни записи не указан, то он берется из параметра $TTL зоны, который у нас равен 3600 сек. Если 5 мин перевести в сек, то получается что в 5 мин = 300 сек
тогда DNS запись принимает вид:
$TTL 3600      ;
example.org.        IN      SOA     ns01.example.org. root.example.org. (
                                1        ; Serial
                                600      ; Refresh
                                3600     ; Retry
                                1w       ; Expire
                                300      ; Minimum TTL
                        )
        IN      NS      ns01.example.org.
        IN      NS      ns02.example.org.
        IN      NS      ns03.example.org.

example.org.  300s      IN      A       10.0.0.1
example.org.  300s      IN      A       10.0.0.2
example.org.  300s      IN      A       10.0.0.3
example.org.  300s      IN      A       10.0.0.4
www     IN      CNAME   example.org.

ns01    IN      A       192.168.10.50
ns02    IN      A       192.168.10.60
ns03    IN      A       192.168.10.70

Сохраняем изменения, перезапускаем Bind-все должно работать.
Теперь срок жизни записи example.org равен 5 мин и клиенты будут чаще обращаться к вашему DNS серверу за обновлением записи.
В общем? как догадались самые внимательные, Bind будет выдавать IP адреса серверов, принципу «револьвера» т.к. по кругу.
На этом на сегодня все, если возникли вопросы, прошу в комментарии, нашли ошибку-строчите в личку ну или на почту, указана в нижнем левом углу.

0 комментариев

Есть что добавить? Регистрируйся и оставляй комментарии!