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

Для примера, у нас, во внешний мир, будет выставлено 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
Со следующим содержимым:
Давайте почистим файл от всего лишнего, чтобы не путаться, ну и укажем IP адреса, который обслуживаются в данны момент и оставим только:
Давайте представим ситуацию, что у нас есть сайт 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 (попробуйте найти запись отвечающую за это).
Для начала нам нужно обеспечить распределение запросов добавив соответствующую запись:
Сохраняем изменения перезапускаем Bind
Теперь выполним запрос с клиентского ПК к нашему DNS серверу (у меня клиент windows):
Где:
nslookup -команда выполнения запроса к DNS серверу
example.org — запись которую мы запрашиваем
192.168.1.10 -IP адрес сервера у которого мы пытаемся получить запрос.
В ответ, мы получим то что указано на скриншоте:

Если выполнить запрос еще раз, то вы увидите что IP, который стоит первым в списке, меняется и клиенту при каждом запросе вдается другой IP.
теперь попробуем выполнить запрос к адресу www.example.org
Это завершиться ошибкой т.к. этой записи не существует-пока…
Возвращаемся к
Можно «запилить» запись вида:
И это будет работать, уж поверьте, благодаря разработчикам Bind, он и не такую ахинею «переваривает».
В общем данная запись является дурным тоном и показателем малограмотности человека который это настраивает.
Для подобный целей есть запись типа cname, следите за мыслью:
www.example.org->ведет к->example.org->к нужным IP адресам
Точка, в конце, ОБЯЗАТЕЛЬНА!!!
В результате всех действий у нас получится файл со следующим содержанием:
Сохраняем изменения перезапускаем Bind
Выполним запрос:
получаем

Распределение запросов работает нормально, но тут возникает один момент. Каждая запись имеет срок жизни, который определяется параметром TTL (time to live), с помощью которого определяется ее актуальность т.к. клиентское устройство будет хранить у себя в кеше, пока не закончится срок жизни данной записи, после этого запись будет считаться не актуальной и будет выполнен следующий запрос к DNS серверу, проблема в том что клиент получив IP будет все время ломиться на него+кеширующие DNS сервера провайдеров, получив первый IP адрес будут перенаправлять клиентов на один IP, в результате на одном IP адресе может создаться высокая нагрузка, а другие будут простаивать. Чтобы распределить нагрузку более равномерно, нам нужно уменьшить вермя жизни записей, чтобы они быстро устаревали, и клиенты обращались снова к DNS серверу. Записи всей зоны у нам трогать нет необходимости, требуется уменьшить время жизни только для тех записей где производится распределение нагрузки. В документации от разработчиков BIND указано что оптимально указывать время жизни 5 мин ( остальное подбирается экспериментально исходя из ваших условий) вот это мы и будем использовать. Если срок жизни записи не указан, то он берется из параметра $TTL зоны, который у нас равен 3600 сек. Если 5 мин перевести в сек, то получается что в 5 мин = 300 сек
тогда DNS запись принимает вид:
Сохраняем изменения, перезапускаем Bind-все должно работать.
Теперь срок жизни записи example.org равен 5 мин и клиенты будут чаще обращаться к вашему DNS серверу за обновлением записи.
В общем? как догадались самые внимательные, Bind будет выдавать IP адреса серверов, принципу «револьвера» т.к. по кругу.
На этом на сегодня все, если возникли вопросы, прошу в комментарии, нашли ошибку-строчите в личку ну или на почту, указана в нижнем левом углу.
Масштабируесть бывает 2х видов: горизонтальная и вертикальная.
Вертикальная осуществляется за счет увеличения ресурсов самого сервера, например-добавление процессоров или оперативной памяти.
Горизонтальная осуществляется за счет увеличения количества серверов.
Как-то я уже писал про технологию балансировки сетевой нагрузки WEB серверов, в статье Балансировка сетевой нагрузки с помощью Nginx, там система работала на одном балансировщике и 3х WEB серверах, также в качестве примера была представлена схема работы mail.ru, доступ к которой осуществлялся через 4 маршрутизатора, но что находилось за ними, для нас осталось тайной. В этой статье я попытаюсь немного рассказать о том как осуществляется работа похожей схемы. Также, крайне рекомендую, ознакомиться со статьей по настройке DNS-сервера BIND, на ее основе будет поднят тестовый DNS сервер, 3 сервера поднимать нет необходимости, в качестве тестового полигона нам хватит и одного DNS сервера.

Для примера, у нас, во внешний мир, будет выставлено 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 адрес сервера у которого мы пытаемся получить запрос.
В ответ, мы получим то что указано на скриншоте:

Если выполнить запрос еще раз, то вы увидите что 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
получаем

Распределение запросов работает нормально, но тут возникает один момент. Каждая запись имеет срок жизни, который определяется параметром 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 комментариев