Настройка Anycast-адреса в рамках бюджетного тестового стенда

Предисловие

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

Для проекта сети этих вводных достаточно, так как остальная часть схемы будет реализована на уровне софта.

Схема аннонсирования Anycast-адреса

Схема аннонсирования Anycast-адреса

Настраиваем OSPF на MikroTik-е

Чтобы настроить в MikroTik-е прием анонсов нам нужна связка из трех элементов:

  1. OSPF Instance — здесь задаем имя для нашей OSPF инсталляции

  2. OSPF Area — описание OSPF зоны, которая привязывается к OSPF Instance

  3. OSPF Interface Template — шаблон, по которому будет происходить аутентификация анонсов от виртуальных машин и создание интерфейсов в привязке к OSPF Area. В нем мы прописываем интерфейсы, в рамках которых нужно работать с анонсами (в моем случаем это общий мост bridge-lan). Здесь же задаются таймеры, согласно которым будут выполняться и обрабатываться анонсы, а отсутствие анонсов в течение Dead Interval будет трактоваться как триггер для удаления анонсирующего сервера из таблицы маршрутизации. У этих интервалов есть взаимосвязь между собой, поэтому нельзя везде назначить 1 секунду для ускорения сходимости при выходе анонсера из строя.

Ниже скриншот с настройками моего стенда.

Настройки MikroTik-а

Настройки MikroTik-а

Настраиваем анонсирование адреса на виртуальных машинах

Сначала создадим 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-а (при условии, что всё настроено правильно) мы должны увидеть что-то такое:

Скриншот с OSPF Neighbours в MikroTik

Скриншот с OSPF Neighbours в MikroTik

Проверяем работу Anycast-адреса…

… со стороны роутера

Здесь обойдемся простым ping-ом из консоли:

ping из консоли Mikrotik-а

ping из консоли Mikrotik-а

Есть контакт! На этом можно было бы остановиться, но хочется более живой пример :)

… со стороны других виртуальных машин

В данной проверке я решил проверить работу сервиса телефонии при схеме, когда 4 Asterisk-а с разных адресов подключаются к Anycast-адресу, которым пользуются OpenSIPS-ы (по одному на каждой из виртуальных машин, где настроен Anycast-адрес).

sngrep со стороны виртуальных машин

sngrep со стороны виртуальных машин

Читатель для проверки может использовать вместо 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 и прочие).

На этом всё. Спасибо, что дочитали статью до конца.

© Habrahabr.ru