Предисловие
В рамках IPv4 и IPv6 есть понятие Anycast-адресов. Если упрощать, то это IP-адреса выглядящие как обычные «серые» или «белые» адреса, но которые одновременно могут работать как на одном сервере, так и на множестве. Есть мнение, что это сложно настраивается, требует много дополнительных слоев маршрутизирующего оборудования и т.д. Но в данной статье я попробую описать настройку Anycast-адреса где угодно и с минимальными затратами. В качестве тестового стенда у нас будет роутер Mikrotik hAP lite и кластер Proxmox-а на мини-компьютерах RockPi (аналог Raspberry Pi) с виртуальными машинами на базе дистриутива Debian.
Зачем именно кластер Proxmox-а? Да просто так 🙂
Можно было бы обойтись виртуальными машинами на компьютере/ноутбуке созданных с помощью VirtualBox или одним мини-компьютером с Proxmox-ом, но у меня есть вот такая штука для домашних экспериментов, поэтому я использовал её.
Всем привет! Меня зовут Артём Друзь, я работаю старшим инженером в компании Контур, где занимаюсь настройкой и обслуживанием цифровой телефонии на базе Asterisk и OpenSIPS. Для цифровой телефонии в «классическом виде» используется UDP транспорт, и соответственно Anycast-адресация. Для создания отказоустойчивой телефонии, это прям то, что доктор прописал. Кто-то может возразить, что использование UDP – это прошлый век, и сейчас в моде WebSocket/WebRTC или даже QUIC. Но если вы включите WireShark и попробуете найти в огромном потоке вашего трафика обмен голосовыми пакетами в вашем любимом месенджере, то с большой долей вероятности вы найдете UDP трафик. Именно по этой причине настройка отказоустойчивости сервисов, использующих UDP транспорт, при помощи «старых методов и технологий» не теряет актуальности.
Проектируем сеть
Прежде чем начать настройку, накидаем схему того, что мы хотим увидеть в результате. В рамках имеющегося стенда есть ограничение в виде MikroTik hAP lite: из-за чипа на архитектуре smips нам недоступно использование протокола BGP, который рекомендуется для подобных штук. Поэтому возьмем протокол OSPF для анонсов IP-адреса с виртуальных машин. Для сурового продакшена с сотнями тысяч запросов в секунду, где важен каждый пакет данных, это, конечно, не подходит. Но в рамках тестового стенда таких нагрузок не планируется 😉
Для проекта сети этих вводных достаточно, так как остальная часть схемы будет реализована на уровне софта.
Настраиваем OSPF на MikroTik-е
Чтобы настроить в MikroTik-е прием анонсов нам нужна связка из трех элементов:
-
OSPF Instance – здесь задаем имя для нашей OSPF инсталляции
-
OSPF Area – описание OSPF зоны, которая привязывается к OSPF Instance
-
OSPF Interface Template – шаблон, по которому будет происходить аутентификация анонсов от виртуальных машин и создание интерфейсов в привязке к OSPF Area. В нем мы прописываем интерфейсы, в рамках которых нужно работать с анонсами (в моем случаем это общий мост bridge-lan). Здесь же задаются таймеры, согласно которым будут выполняться и обрабатываться анонсы, а отсутствие анонсов в течение Dead Interval будет трактоваться как триггер для удаления анонсирующего сервера из таблицы маршрутизации. У этих интервалов есть взаимосвязь между собой, поэтому нельзя везде назначить 1 секунду для ускорения сходимости при выходе анонсера из строя.
Ниже скриншот с настройками моего стенда.
Настраиваем анонсирование адреса на виртуальных машинах
Сначала создадим dummy-интерфейс на каждой из виртуальных машин и запустим его.
В файл /etc/network/interfaces
добавляем вот такую конструкцию:
auto dummy0 iface dummy0 inet static address 172.18.0.64/32 pre-up ip link add dev dummy0 type dymmy pre-down ip link delete dev dummy0 type dummy
Важно. IP-адрес в конфигурации интерфейса должен быть вне существующих подсетей, иначе схема не сможет корректно работать.
Далее запускаем интерфейс командой ifup dummy0
Для тех у кого дистрибутив Linux использует NetworkManager есть команда, которая делает по сути тоже самое, но одним действием:
nmcli connection add type dummy ifname dummy0 ipv4.method manual ipv4.addresses 172.18.0.64/32
Далее устанавливаем bird
apt install bird2
И вносим правки в /etc/bird/bird.conf
log syslog all; protocol device { } protocol kernel { ipv4 { import none; export all; }; } protocol static { ipv4; } protocol ospf myAnycast { # myAnycast - любое произвольное имя для инстанса OSPF на уровне виртуальной машины ipv4 { import all; export all; }; area 0 { stubnet 172.18.0.64/32 { # 172.18.0.64 - Anycast-адрес не входящий в существующие подсети в локальной сети }; interface "enp0s11" { # enp0s11 - имя сетевого интерфейса с которого должны производиться анонсы Anycast-адреса cost 1; type broadcast; hello 3; # Hello Interval из шаблона в MikroTik retransmit 2; # Retransmit Interval из шаблона в MikroTik wait 2; dead 4; # Dead Interval из шаблона в MikroTik authentication simple; # Authentication из шаблона в MikroTik password "myOSPFpassword"; # Auth. Key из шаблона в MikroTik }; interface "dummy0" { # Имя dummy интерфейса, на котором настроен Anycast-адрес stub; }; }; }
Теперь перезапускаем bird командой systemctl restart bird
, и через несколько секунд в интерфейсе MikroTik-а (при условии, что всё настроено правильно) мы должны увидеть что-то такое:
Проверяем работу Anycast-адреса…
… со стороны роутера
Здесь обойдемся простым ping-ом из консоли:
Есть контакт! На этом можно было бы остановиться, но хочется более живой пример 🙂
… со стороны других виртуальных машин
В данной проверке я решил проверить работу сервиса телефонии при схеме, когда 4 Asterisk-а с разных адресов подключаются к Anycast-адресу, которым пользуются OpenSIPS-ы (по одному на каждой из виртуальных машин, где настроен Anycast-адрес).
Читатель для проверки может использовать вместо SIP-серверов и программных АТС-ок какой-нибудь голосовой сервис работающий через UDP транспорт. На моем скриншоте tmux-а с запущенным sngrep-ом на двух виртуальных машинах (третью на время проверки выключил, чтобы получился читабельный снимок экрана). Видно, что:
-
Asterisk с адресом 172.18.0.24 распределился MiroTik-ом на первый OpenSIPS
-
Asterisk-и с адресами 172.18.0.22, 172.18.0.23 и 172.18.0.25 распределились на второй OpenSIPS
Как сделать другую стратегию распределения трафика (например, чтобы каждый пакет распределялся на анонсеров Anycast-адреса по стратегии round-robin) на MikroTik-е – это отдельная тема, и в данной статье мы её затрагивать не будем.
Таким образом, цель можно считать достигнутой и можно начинать экспериментировать с собственным Anycast-адресом 😉
Заключение
В статье я не упоминал ничего, что привязывало бы читателя к Proxmox-у в целом или к его конкретной реализации на мини-компьютерах с процессором ARM в частности. Статья является инструкцией по настройке Anycast-адреса на своем компьютере или в некой локальной сети, чтобы попробовать реализовать сервис использующий фишки этого вида адресов. В моем примере Proxmox нужен был только как общая среда создания виртуальных машин.
Как итог – у нас теперь есть свой Anycast-адрес, анонсирующийся через OSPF, с которым мы можем экспериментировать и проверять гипотезы. Безусловно, у данной схемы есть недоработки (например, маршрутизация исходящих пакетов через интерфейсы виртуальных машин выполняющих анонсирование). Но для того, чтобы начать разбираться с этой темой, данного трамплина, на мой взгляд, достаточно.
Важные оговорки, про которые выше по тексту в том или ином виде уже упоминались:
-
Описанное в статье решение не для сурового продакшена. Оно может быть использовано для малого бизнеса или задач саморазвития, но точно не для систем с тысячами RPS. Как минимум, для быстрой сходимости маршрутизации при отказе одной из нод вместо OSPF нужно использовать BGP.
-
Anycast-адресация это про UDP трафик, в котором нет понятия гарантированного подключения и доставки данных (анекдот). Если у вас TCP трафик (web-сайты, REST API, подключения к базам данных и прочее), то вам для отказоустойчивости и/или высокой доступности сервисов нужны балансировщики, которые обрабатывают такой трафик или специализируются под конкретный сервис (HAProxy, PgBouncer, Galera Cluster, Redis Sentinel и прочие).
На этом всё. Спасибо, что дочитали статью до конца.
ссылка на оригинал статьи https://habr.com/ru/articles/848676/
Добавить комментарий