Настройка BGP с Anycast: доступность и отказоустойчивость

Настройка BGP с Anycast: высокая доступность и отказоустойчивость

В тексте рассмотрим настройку BGP с Anycast на двух серверах, которые работают с CMS WordPress из разных локаций.

BGP в сочетании с Anycast — мощный инструмент для повышения производительности и надежности сетевых сервисов. Технологии обеспечивают быстрое и эффективное перенаправление трафика, минимизируя задержки и увеличивая доступность ресурсов. 

Исходные данные

Использование BGP с Anycast обеспечивает высокую доступность сервисов. В случае сбоя на основном сервере трафик автоматически перенаправляется на резервный, что гарантирует непрерывную работу сайта.

В инструкции рассмотрим настройку BGP с Anycast на двух серверах: основной сервер — в пуле ru-3 (Санкт-Петербург), резервный — в ru-7 (Москва). Оба подключены к виртуальным машинам с MySQL, изначально репликация между ними не настроена.

Для подключения BGP+Anycast в инфраструктуре Selectel нужно любое оборудование, которое поддерживает протокол динамической маршрутизации BGP:

После подключения услуги в тикете будут предоставлены параметры для настройки. В нашем случае:

ПулIP BGP neighbor SelectelAS SelectelIP BGP neighbor clientAS client
ru-781.163.24.95034081.163.24.1464859
ru-3188.246.228.16149505188.246.228.16664859

Значения столбцов

  • IP BGP neighbor Selectel — адреса соседей для Selectel.
  • AS Selectel — автономная система со стороны Selectel.
  • IP BGP neighbor client — адреса соседей для клиента.
  • AS client — автономная система, созданная для клиента.

Используемая адресация

  • ru-7: ВМ с CMS — 81.163.24.14, ВМ с MySQL — 185.149.243.3
  • ru-3: ВМ с CMS — 188.246.228.166, ВМ с MySQL — 185.10.186.138

Примечание. Если базы данных должны находиться в локальной сети, для связи между ВМ с CMS и БД используйте глобальный роутер. Подробнее о решении — в обзоре, а инструкция по настройке — в документации.

Настройка BGP + Anycast с помощью BIRD

Для настройки Anycast с использованием BGP на сервере Linux можно применить демон BIRD — эффективное средство для маршрутизации, которое поддерживает различные протоколы, включая BGP. Пошагово рассмотрим установку и настройку BIRD.1. Установим демон BIRD. Для этого воспользуемся пакетным менеджером apt:


    sudo apt install bird

2. Настроим BIRD с помощью конфигурационного файла /etc/bird/bird.conf. Откроем его в текстовом редакторе nano, но вы можете использовать любой другой:


    sudo nano /etc/bird/bird.conf

Пример конфигурации для сервера 81.163.24.14:


    router id 81.163.24.14;  # В качестве router-id используется IP-адрес, принадлежащий BGP-пулу

# Настройка протокола kernel
protocol kernel {
    scan time 60;   # Интервал сканирования таблицы маршрутов
    import all;     # Импорт всех маршрутов
    export none;    # Не экспортировать маршруты
}

# Настройка протокола device
protocol device {
    scan time 60;   # Интервал сканирования сетевых интерфейсов
}

# Настройка прямого протокола для всех интерфейсов
protocol direct {
    interface "*";  # Использование всех доступных интерфейсов
}

# Фильтр маршрутов для манипуляции с AS-PATH
filter out_prefix {
    if ( net ~ [31.184.217.64/29] ) then {
        bgp_path.prepend(64859);  # Ухудшение маршрута с помощью AS-PATH Prepend
        bgp_path.prepend(64859);
        bgp_path.prepend(64859);
        accept;  # Принимаем этот маршрут
    }
    else reject;  # Отклоняем все остальные маршруты
}

# Настройка BGP
protocol bgp {
    local as 64859;   # Используем AS клиента с Anycast-подсетью
    import all;       # Импортируем все маршруты
    export filter out_prefix;  # Применяем фильтр при экспорте
    multihop 10;      # Максимальное количество хопов
    neighbor 81.163.24.9 as 50340;  # IP и AS-сосед для связи с маршрутизатором провайдера
}

3. Запустим и проверим службу BIRD:


    sudo birdc show protocols

Пример вывода:


    BIRD 1.6.8 ready.
name     proto    table    state  since       info
kernel1  Kernel   master   up     13:57:20    
device1  Device   master   up     13:57:20    
direct1  Direct   master   up     13:57:20    
bgp1     BGP      master   up     13:57:25    Established

Если сессия BGP установлена (состояние Established) — конфигурация работает корректно.

4. Настроим алиас на интерфейсе — это нужно для использования Anycast-адреса (например, 31.184.217.66) на сервере. Для этого добавим соответствующую конфигурацию в файл /etc/network/interfaces.


    auto eth0:0
iface eth0:0 inet static
    address 31.184.217.66/29   # Anycast-адрес

5. Отключим утилиту cloud-init. Она часто встречается при использовании услуг от облачных провайдеров и может перезаписывать сетевые настройки при каждой перезагрузке ВМ. Для нас важно избежать этого:


    echo "network: {config: disabled}" | sudo tee -a /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

Шаг предотвратит автоматическое изменение сетевых настроек на вашем сервере при его перезагрузке.

Ознакомиться с подробной инструкцией по изменению сетевых настроек можно в документации.

Для настройки сервера с IP-адресом 188.246.228.166 и Anycast последовательность действий будет практически аналогичной, как и в рассмотренном примере. Изменения лишь в конфигурации фильтра маршрутов и адресе BGP-соседа:


    router id 188.246.228.166;
protocol kernel {
        scan time 60;
        import all;
        export none;
        }
protocol device {
        scan time 60;
}
protocol direct {
        interface "*";
}
filter out_prefix {
        if ( net ~ [31.184.217.64/29] ) then {
                accept;
        }
        else reject;
}
protocol bgp {
    local as 64859;
    import all;
    export filter out_prefix;
    multihop 10;
    neighbor 188.246.228.161 as 49505;
}

После этого нужно запустить службу BIRD и проверить состояния BGP-сессий и маршрутов. Далее — добавить Anycast-адрес (31.184.217.66) алиасом и отключить cloud-init.

Тестирование

Переходим по адресу 81.163.24.14 и видим тестовую страницу:

Скриншот страницы по адресу 81.163.24.14. Наполнение страницы: 

Блог_msk
Привет, мир!
Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите ее, затем начинайте создавать!
Страница по адресу 81.163.24.14.

Аналогично при переходе на 188.246.228.166:

Скриншот страницы по адресу 188.246.228.166. Наполнение страницы: 

Блог_spb
Привет, мир!
Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите ее, затем начинайте создавать!
Страница по адресу 188.246.228.166.

При переходе по Anycast-адресу 31.184.217.66 пользователи перенаправляются на страницу с основного сервера в Санкт-Петербурге, так как он является главным. Резервный сервер находится в Москве.

Скриншот из панели управления, выключение основного сервера (статус SHUTOFF).
Выключение основного сервера.
Скриншот страницы по адресу 31.184.217.66. Наполнение страницы: 

Блог_msk
Привет, мир!
Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите ее, затем начинайте создавать!
Страница по адресу 31.184.217.66.

Если включить основной сервер обратно, то по Anycast-адресу снова будет передаваться информация от петербургского сервера:

Скриншот из панели управления, включение основного сервера (статус ACTIVE).
Включение основного сервера.
Скриншот страницы по адресу 31.184.217.66. Наполнение страницы: 

Блог_spb
Привет, мир!
Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите ее, затем начинайте создавать!
Страница по адресу 31.184.217.66.

Настройка репликации для БД

Если необходимо сделать так, чтобы данные в БД были одинаковые, следует настроить репликацию между ними.

Основные понятия

Репликация MySQL — процесс, при котором данные из одного MySQL-сервера (мастера) автоматически копируются (реплицируются) на другие (слейвы). Это один из механизмов обеспечения высокой доступности, масштабируемости и балансировки нагрузки в распределенных системах.

Рассмотрим основные компоненты репликации MySQL.

Мастер (Master) — сервер, на котором выполняются все операции записи (INSERT, UPDATE, DELETE). Это главный источник данных, а все изменения на мастере передаются на Slave-серверы.

Слейв (Slave) — сервер, который получает копии данных с мастера и применяет их. Обычно на слейвах проходят только операции чтения, а запись — только на мастере. Они могут быть настроены на разные способы обработки репликации: как обычный слейв или с возможностью принимать запросы на запись (в случае использования, например, master-master репликации).

Бинарный лог (Binary Log) — на мастере включен бинарный лог, который содержит все изменения данных в базе. Этот лог используется слейвами для синхронизации с мастером.

GTID (Global Transaction ID) — уникальный идентификатор для каждой транзакции в MySQL. Помогает упростить управление репликацией, улучшая устойчивость к сбоям и гарантируя целостность данных.

Идентификатор сервера (server-id) — уникальный идентификатор для каждого сервера в системе. Нужен для корректного функционирования репликации и помогает каждому серверу отличать свои операции от операций остальных серверов.

Как работает репликация MySQL

1. Мастер-сервер записывает изменения в бинарный лог. Это могут различные операции: добавление, изменение или удаление данных в базе и т. д.

2. Slave-серверы подключаются к мастеру, получают копии бинарного лога и применяют изменения на своем сервере. Это гарантирует, что слейв всегда будет синхронизирован с мастером, пока репликация не прервана.

3. Репликация может быть настроена с различной задержкой (логи могут передаваться на slave с небольшим интервалом). Задержка репликации называется lag и зависит от объема данных, а также скорости сети.

Настройка репликации

Репликация позволяет создать копию базы данных для повышения отказоустойчивости, масштабируемости и производительности. В инструкции рассмотрим пошаговую настройку репликации Master-Slave.

Шаг 1. Подготовка серверов

Перед настройкой репликации важно выполнить проверку. 

1. Убедимся, что на всех серверах (Master и Slave) установлены одинаковые версии MySQL.2. Проверим, что серверы могут взаимодействовать друг с другом. Самый простой вариант это сделать — использовать команду ping.

Шаг 2. Настройка Master-сервера

На этом этапе настроим мастер-сервер, который будет передавать изменения в базу данных на slave-сервер. Для этого нужно выполнить несколько ключевых шагов.

  1. Включить бинарные логи (binlog) — это файлы, которые содержат историю всех изменений в базе данных. Они используются для передачи изменений на slave.
  2. Задать уникальный идентификатор сервера (server-id), который позволяет MySQL отличать master от slave.
  3. Создать пользователя для репликации с необходимыми правами.
  4. Получить текущий статус бинарных логов, чтобы slave «понимал», с какой точки начать синхронизацию.
  5. Скопировать дамп базы данных на slave и подготовить его к репликации.

После выполнения этих действий мастер-сервер будет готов к передаче данных на slave-сервер.

1. Отредактируем файл конфигурации MySQL (обычно /etc/my.cnf или /etc/mysql/my.cnf) на Master:


    [mysqld]
server-id = 1            # Уникальный идентификатор сервера
log_bin = /var/log/mysql/mysql-bin.log  # Включение бинарных логов
binlog_format = ROW      # Формат бинарных логов

2. Перезапустим MySQL для применения изменений:


    systemctl restart mysql

3. Создадим пользователя, который будет использоваться для репликации:


    CREATE USER 'replicator'@'%' IDENTIFIED BY 'репликационный_пароль';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;

4. Получим текущий статус (позицию) бинарного лога:


    SHOW MASTER STATUS;

Результат покажет File — имя текущего бинарного лога, а также Position — текущую позицию.

5. Скопируем данные на реплику. Для этого создадим дамп базы данных:


    sudo mysqldump -u root db > db.sql

5.1 Разблокируем таблицы (если применимо):


    UNLOCK TABLES;

5.2 Выйдем из MySQL:


    exit

5.3 Используем scp для копирования дампа на реплику:


    scp db.sql username@replica_server_ip:/tmp/

5.4 Войдем в MySQL на реплике и создадим базу данных:


    sudo mysql
CREATE DATABASE db;
exit

5.5 Восстановим дамп:


    sudo mysql db < /tmp/db.sql

Шаг 3. Настройка Slave-сервера

Настроим slave-сервер, который будет принимать изменения с мастер-сервера. Этот этап включает несколько ключевых шагов.

  1. Настроить конфигурацию MySQL: установить уникальный server-id и включить relay log, который будет хранить передаваемые данные от мастера.
  2. Перезапустить MySQL, чтобы применить изменения.
  3. Настроить подключение к мастер-серверу, указав его IP-адрес, имя пользователя и пароль для репликации, а также бинарный лог и позицию, полученные ранее.
  4. Запустить репликацию и убедиться, что slave корректно принимает данные.
  5. Проверить статус репликации

После успешного завершения этих шагов slave-сервер будет автоматически получать обновления от мастера.

1. Отредактируем файл конфигурации MySQL на Slave:


    [mysqld]
server-id = 2            # Уникальный идентификатор сервера
relay_log = /var/log/mysql/mysql-relay-bin.log  # Логи реплики

2. Перезапустим MySQL:


    systemctl restart mysql

3. Войдем в MySQL на Slave и выполним команду для настройки подключения к Master:


    CHANGE MASTER TO
  MASTER_HOST = 'ip_адрес_master',
  MASTER_USER = 'replicator',
  MASTER_PASSWORD = 'репликационный_пароль',
  MASTER_LOG_FILE = 'имя_бинарного_лога_с_master',
  MASTER_LOG_POS = позиция_с_master;

Пример для заполнения настроек:


    CHANGE MASTER TO
  MASTER_HOST = '185.10.186.138',
  MASTER_USER = 'replicator',
  MASTER_PASSWORD = 'password123',
  MASTER_LOG_FILE = 'mysql-bin.000001',
  MASTER_LOG_POS = 154;

4. Запустим репликацию:


    START SLAVE;

5. Проверим статус репликации:


    SHOW SLAVE STATUS\G;

Обратите внимание на два параметра: если оба в значении Yes, репликация работает корректно.

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes

Проверьте, что данные, добавленные на Master, появляются на Slave. Если возникают ошибки — изучите Last_IO_Error и Last_SQL_Error из вывода SHOW SLAVE STATUS\G.После этого нужно изменить адрес базы данных в конфигурации WordPress для резервного сервера в Москве. Для этого измените данные в файле wp-config.php:


    define('DB_NAME', 'db'); # Имя базы данных
define('DB_USER', 'username'); # Пользовать БД
define('DB_PASSWORD', 'password'); # Пароль к БД
define('DB_HOST', '185.10.186.138'); # Адрес БД

Полезные команды

В процессе настройки репликации могут возникнуть ситуации, когда нужно временно приостановить, возобновить или сбросить настройки репликации. Ниже приведены ключевые команды, которые помогут управлять этими процессами.

Паузу репликации используют, чтобы временно остановить поток репликации, например, для обслуживания базы данных или устранения ошибок.


    STOP SLAVE;

Возобновление репликации — запускает процесс получения и обработки изменений с мастер-сервера после паузы.


    START SLAVE;

Очистка настроек репликации — полностью сбрасывает все параметры репликации на слейве, что полезно при необходимости настроить репликацию заново.


    RESET SLAVE ALL;

Используйте эти команды с осторожностью, особенно RESET SLAVE ALL, так как она полностью удаляет информацию о текущем мастер-сервере и скачанных бинарных логах.

Failover

При выключении мастера сайт по Anycast-адресу становится недоступен:

Скриншот сайта. 504 Gateway Time-out.

Если мастер в MySQL-кластере становится недоступным, нужно выполнить процедуру переключения ролей (failover). Для этого следует назначить одного из slave новым мастером, а также изменить адрес базы данных в конфигурации WordPress. Разберем этот процесс по шагам.

1. Приостановим поток получения данных/обновлений с мастера:


    STOP SLAVE IO_THREAD;
SHOW PROCESSLIST;

Дождитесь, пока не появится сообщение вида «Has read all relay log; waiting for the slave I/O thread to update it». Оно подтверждает, что все команды из relay-лога были успешно обработаны slave-сервером. Сразу останавливать поток не рекомендуем, так как SQL-команды могут отставать, а при преждевременной паузе можно потерять данные, которые еще не были «проиграны».

2. Убедимся, что бинарный лог включен на slave-сервере и он не записывает запросы от мастера:


    SHOW VARIABLES LIKE 'log_bin';
log_bin       | ON
SHOW VARIABLES LIKE 'log_slave_updates';
log_slave_updates | OFF

3. Остановим все процессы slave-сервера и очистим бинарный лог:


    STOP SLAVE IO_THREAD;
SHOW PROCESSLISTSTOP SLAVE;
RESET MASTER;
;

Команда RESET MASTER очищает бинарный лог на новом мастере. Это важно, чтобы избежать воспроизведения устаревших или лишних записей на подключенных slave-серверах.

4. Теперь, когда slave-сервер готов стать мастером, выполним команду для переключения его на новый мастер-сервер:


    STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='#new_master_host_name#';

5. Чтобы наше веб-приложение (например, на WordPress) работало с новым мастером, нужно изменить настройки подключения к базе данных в конфигурационном файле wp-config.php. В нем укажем нового пользователя и адрес хоста для подключения к БД нового мастера:


    define('DB_NAME', 'db'); # Имя базы данных
define('DB_USER', 'username'); # Пользовать БД
define('DB_PASSWORD', 'password'); # Пароль к БД
define('DB_HOST', '185.10.186.138'); # Адрес БД

6. Сайт снова функционирует. Добавим в нем новый комментарий и проверим корректность отображения в БД:

Скриншот комментария в БД.
Комментарии в терминале.

Заключение

В качестве примера мы использовали простую инфраструктуру, но инструкцию можно адаптировать для более сложных сценариев. Например, вы можете сделать одну из виртуальных машин маршрутизатором, настроив на ней пересылку пакетов, а сервисы разместить за ней. Также можно создать виртуальную машину с базой данных в локальной сети, как мы упоминали ранее.

Использование BGP совместно с Anycast позволяет эффективно распределять трафик между несколькими серверами, минимизируя задержки и обеспечивая отказоустойчивость. Особенно важно для высоконагруженных приложений и веб-ресурсов.

Настроив BGP с Anycast, вы можете улучшить географическое распределение трафика. Это способствует более быстрому доступу для пользователей по всему миру, а также повышает стабильность сети, гарантируя бесперебойную работу сайта даже в случае отказа одного из серверов.