Гостевой пост: опыт использования VRRP

VRRP Selectel Guest Post

Сегодня мы публикуем необычный пост — его написали наши клиенты.

Компания ITSumma занимается удаленным администрированием серверов и технической поддержкой веб-сайтов, обеспечивает доступность веб-сервисов при высоких и очень высоких нагрузках.

В статье Антон Баранов, Виктория Андриенко и Евгений Потапов делятся практическим опытом использования нашей услуги «Резервирование маршрутизатора (VRRP)». Если вы работаете над обеспечением высокой доступности и отказоустойчивости собственного проекта, вам будет интересно ознакомиться с этим опытом.

Горячее резервирование в Selectel. Достоинства и возможные недостатки, механизмы применения

Немного о резервировании

Относительно недавно Selectel анонсировал возможность использования VRRP (Virtual Router Redundancy Protocol) для своих площадок — эта технология дает очень редкую для российского хостинга возможность практически прозрачного переключения проекта с основной площадки на резервную «на лету». Это решение мы и хотим рассмотреть в деталях.

Когда проект разрастается до требований полноценной доступности 24/7, возникает необходимость в резервном сервере, на который синхронизируются данные, пишется реплика базы данных. В этот момент появляется главный вопрос: как переключать пользователей на этот резервный сервер? При этом необходимо соблюсти согласованность данных на всех уровнях (файлы, БД, настройки ПО) между основным сервером и резервом. Очень важно, чтобы при отказе основного сервера запросы новых посетителей сайта мгновенно переключались на резерв: ведь если по каким-то причинам после переключения запросы посетителей продолжают приходить на недоступный сервер, то мы теряем потенциальных клиентов.

Прежде всего мы рекомендуем, чтобы резервный сервер находился в другом дата-центре (возможно — той же компании), ведь так же часто, как мы видим падения отдельных серверов, мы видим и проблемы на уровне стойки (в периоды мощных DDoS-атак на других клиентов хостинга), проблемы на уровне дата-центра целиком, проблемы на уровне сетевых каналов к дата-центру.

В идеале резервный сервер должен находиться в другом дата-центре другой хостинг-компании и на других сетевых каналах. Однако, даже размещение в нескольких ДЦ одной компании уже может значительно улучшить надёжность проекта. Главное, что мы рекомендуем — не держать резерв в том же физическом дата-центре.

Вне зависимости от того, где будет расположена резервная площадка, возникает вопрос: каким образом пользователи будут переведены на резервный сервер? Смена IP-адреса в DNS зависит от времени кэширования записи, часть пользователей будет долгое время видеть старый IP-адрес. Использование прокси-сервера или облачного балансировщика (например, от Amazon) создает новую возможную точку ошибки, добавляет накладных расходов, а в случае с Amazon’ом, ко всему прочему, могут возникнуть вопросы, связанные с соблюдением закона о персональных данных. Поэтому хочется просто иметь возможность переключить IP- адрес, однако доступных для небольших проектов технологий не так много. Не каждый проект может купить себе подсеть и договориться с дата-центрами о ее анонсе.

VRRP и резервирование в Selectel: устройство и характерные особенности

Изначально протокол VRRP использовался для упрощения ручного труда при авариях в локальной сети.

Пусть в пределах одной локальной сети есть несколько маршрутизаторов и серверов. Если с одним из основных серверов или маршрутизаторов этой сети происходит авария, то нам достаточно просто поднять на сетевом интерфейсе резервного сервера/маршрутизатора IP-адрес основного, и весь трафик внутри сети пойдет на него.

Программное обеспечение, использующее протокол VRRP, обменивается между основным и резервным узлами данными о том, кто выполняет роль «мастера» в рамках резервной группы, и о том, какие узлы — резервные, и какой приоритет у их использования в случае аварии на основном сервере. Каждый из узлов получает от других данные о его роли и весе, и если вдруг узел понимает, что он играет резервную роль, но в сети не осталось узлов с весом выше него (и соответственно — пропал мастер, вес у которого максимальный) — этот узел автоматически поднимает у себя IP-адрес основного узла, берет на себя роль «мастера». В случае, если в сети снова появился узел с более высоким приоритетом — резервный узел, взявший на себя роль «мастера», возвращается в состояние резерва и выключает на интерфейсе IP-адрес основного узла.

Основа системы горячего резервирования с использованием протокола VRRP в Selectel’е — виртуальная локальная сеть между двумя физическими дата-центрами, в Москве и Санкт-Петербурге. Как и в любой локальной сети, IP адрес может быть назначен любому из ее элементов. Соответственно, в указанной виртуальной сети выбираются: основной маршрутизатор и основной сервер в одном из дата-центров, резервный маршрутизатор и резервный сервер в другом дата-центре. Все узлы находятся в пределах одной виртуальной подсети.

Услуга по резервированию не полностью автоматическая: организация резервирования серверов — задача пользователя/администратора (достаточно просто «погасить» IP на основном сервере и «поднять» на резервном), резервирование маршрутизаторов осуществляет сам Selectel, и это отдельная история.

После заказа услуги VRRP Selectel предоставляет подсеть /29, состоящую из 6 ip-адресов. Пусть в нашем примере это будет подсеть 98.76.54.24/29. Назначение IP-адресов в этой подсети распределено следующим образом:

1) IP основного сервера — 98.76.54.28
2) Основной шлюз — 98.76.54.25
3) IP резервного сервера — 98.76.54.29
4) Резервный шлюз — 98.76.54.26
5) Broadcast-IP — 98.76.54.31
6) VRRP IP — 98.76.54.27 (этот IP должен быть по умолчанию поднят на основном сервере 98.76.54.28)

VRRP Selectel

Для резервирования на основном и резервном сервере поднимаются демоны keepalived, которые, обмениваясь между собой информацией или используя скрипт проверки, определяют доступность остальных узлов в схеме резервирования ( фактически резервный сервер пытается понять, доступен или нет основой сервер, и, в случае его недоступности, поднимает VRRP IP на своем интерфейсе).

Подобное резервирование поможет защититься от следующих аварий:

  • падение основного сервера, аппаратные проблемы с основным сервером;
  • падение стойки, в которой находится основной сервер (если бы взяли второй сервер в том же ДЦ, в той же стойке — проект бы упал), DDoS на стойку.

Резервирование на уровне сервера не защитит от следующих проблем:

  • нефатальные проблемы с каналом (потеря пакетов, тормоза) в основном дата-центре
    аппаратное падение основного маршрутизатора;
  • аппаратное падение основного дата-центра;
  • падение основного дата-центра в результате ошибки сетевой конфигурации.

Для решения такого рода проблем применяется резервирование на уровне маршрутизаторов. Отметим, что эта часть системы резервирования лежит целиком на Selectel’e, то есть контроля над этим процессом у пользователя/администратора нет.

Разберём каждый из из аварийных случаев, и посмотрим, какие действия на стороне маршрутизаторов должны произойти в каждом из них.

VRRP Selectel

Аппаратное падение основного маршрутизатора

Это именно тот случай, в случае которого резервирование на уровне маршрутизаторов организованное Selectel’ом практически гарантировано защитит — резервный маршрутизатор увидит недоступность основного маршрутизатора и возьмет роль основного на себя.

Аппаратное падение основного дата-центра: тоже случай, от которого резервирование на уровне маршрутизаторов защитит, даже по «локальной» оптике резервный маршрутизатор увидит недоступность основного ДЦ и возьмет на себя роль основного.

Полное падение основного дата-центра

Этот случай — самый сложный. В идеале откат в случае аварии на уровне дата-центра происходит следующим образом:

1. Пусть основной дата-центр находится в Москве, резервный — в Санкт-Петербурге.
2. Дата-центр в Москве теряет все свои аплинки, при этом оптика между Санкт-Петербургом и Москвой, по которой связаны ДЦ, остается, виртуальные маршрутизаторы видят доступность друг друга и не переключаются.
3. Идеальный случай: Московский ДЦ перестает анонсировать свои сети, ДЦ в Санкт-Петербурге их анонсирует, трафик по аплинкам идет в Санкт-Петербург затем идет по оптике в Москву на основной маршрутизатор и уже оттуда — на основной сервер.

Прецедентов полного падения одного из дата-центров в Selectel’е мы не видели, поэтому не можем с уверенностью говорить о том, что это резервирование действительно работает и сработает эффективно, — например, при аварии, обусловленной человеческим фактором, когда основной ДЦ перестанет быть виден извне, а его канал до резервного ДЦ останется активным.

Таким образом, VRRP в Selectel’е — это очень полезная технология, которая все же имеет свои особенности, и о них не стоит забывать. Переключение на резервный сервер не всегда означает переключение на резервные каналы.

За пределами сетевого стека важно учесть: любое переключение на резерв всегда связано с двумя возможными проблемами. Первая: резервная площадка по какой-то причине может быть неработоспособна (и проект переключится, например, с плохо работающего сайта на абсолютно неработающий). Вторая: может случиться, что данные и операции, которые были проведены в период работы на резервной площадке, останутся только на ней и не будут синхронизованы с основной площадкой.

Для минимизации этих рисков важно вести мониторинг резервной площадки так же тщательно, как и основной: внимательно следить за репликацией между площадками и быть крайне осторожными с синхронизацией. У вас есть два варианта. С одной стороны, можно организовать резервирование по схеме «мастер-слейв» и в случае аварии превратить резервную площадку в основную, а на основной — «переподнять» резервирование. С другой стороны, можно организовать репликацию по схеме «мастер — мастер». При выборе этого варианта следует учитывать все возможные риски: если данные будут случайны удалены на резервере, то же самое произойдёт и на мастере; переключение на резерв и обратно при нарушении синхронизации приведёт рассинхронизации данных и т.п.

Что следует держать на мониторинге

1. На обeих машинах нужно поднять URL, сообщающий о том, откуда отдаются текущие данные, для примера: http://mysite.com/vrrp.txt возвращаюий msk в случае сервера в Москве и spb в случае сервера в Санкт-Петербурге. При смене значения/недоступности URL — оповещение.
2. Состояние репликации между основным и резервным сервером.
3. Состояние файловой синхронизации между основным и резервным сервером.
4. Доступность URL проекта на резервном сервере.

Бонус-трек: Настройка VRRP в Selectel’e

На стороне linux-серверов VRRP может быть реализован с помощью демона keepalived. Рассмотрим его настройку.

После заказа услуги VRRP провайдер предоставляет нам подсеть /29 , состоящую из 6 ip-адресов. Пусть в нашем примере это будет подсеть 98.76.54.24/29 . Назначение IP-адресов в этой подсети распределено следующим образом:

1) IP основного сервера — 98.76.54.28
2) Основной шлюз — 98.76.54.25
3) IP резервного сервера —98.76.54.29
4) Резервный шлюз — 98.76.54.26
5) Broadcast-IP — 98.76.54.31
6) VRRP IP — 98.76.54.27

После этого от нас требуется только три вещи:

1) Сконфигурировать сетевые интерфейсы сервера

Сетевые настройки основного сервера:

[root@main-server root]# cat /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE="eth0"
BOOTPROTO="static"
BROADCAST="98.76.54.31"
DNS1="8.8.8.8"
GATEWAY="98.76.54.25"
HWADDR="0C:C4:7A:4E:DF:A2"
IPADDR="98.76.54.28"
NETMASK="255.255.255.248"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="c90e6f8e-6c10-48bd-adc5-4039077b8ed1"

Сетевые настройки резервного сервера:

[root@reserve-server root]# cat /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE="eth0"
BOOTPROTO="static"
BROADCAST="98.76.54.31"
DNS1="8.8.8.8"
GATEWAY="98.76.54.26"
HWADDR="22:00:0A:49:C8:AB"
IPADDR="98.76.54.29"
NETMASK="255.255.255.248"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="4a7f24f0-d507-425a-a8cd-f9bd42410bb8"

Обратите внимание, что IP интерфейса и шлюз мы указываем для каждого сервера свой.

2) Сконфигурировать keepalived

Для начала установим keepalived. Как правило, он есть в стандартных репозиториях. Пример для CentOS:

[root@main-server root]# yum install keepalived

Далее нужно его корректно сконфигурировать.

Настройки keepalived на основном сервере:

[root@main-server root]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {
     support@yourdomain.ru
   }
   notification_email_from vrrp@yourserver.ru
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id main
}


vrrp_instance nginx1 {
        state MASTER
        interface eth0
        virtual_router_id 51
        priority 201
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass jaecheFaeva9Kai
        }
        virtual_ipaddress {
                98.76.54.27/29
        }
}

Настройки keepalived на резервном сервере:

[root@reserve-server root]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   notification_email {
     support@yourdomain.ru
   }
   notification_email_from vrrp@yourserver.ru
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id reserve
}


vrrp_instance nginx1 {
        state BACKUP
        interface eth0
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass jaecheFaeva9Kai
        }
        virtual_ipaddress {
                98.76.54.27/29
        }
}

Обратите внимание на следующие моменты:

а) Мы не добавляем keepalived в автозагрузку сервера. Т.к. сервера перезагружаются крайне редко, если это не запланированное обслуживание, а авария, то нам не нужен запущенный keepalived на сервере до того, как мы устраним все причины/последствия аварии, а так же актуализируем данные на этом сервере.
б) Priority у резервного сервера обязательно должен быть меньше, чем у основного.
в) Virtual_router_id должен быть разным у каждой пары серверов с VRRP-ip. Хотя в в документации указано, что он должен быть разным только для разных интерфейсов в рамках одного сервера,  на практике мы сталкивались с тем, что когда у разных пар серверов был одинаковый virtual_router_id, возникали проблемы.

3) Прописать соответствующие правила фаерволла для открытия VRRP и мультикаста:

-A INPUT -i eth0 -p vrrp -j ACCEPT
-A INPUT -d 224.0.0.0/8 -i eth0 -j ACCEPT

После этого можно запускать keepalived:

[root@main-server root]# service keepalived start

Если мы просмотрим логи, то они должный выглядеть примерно так:

На основном сервере

Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Netlink reflector reports IP 98.76.54.28 added
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Netlink reflector reports IP fe80::ec4:7bff:fe4e:dfa2 added
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Registering Kernel netlink reflector
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Registering Kernel netlink command channel
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Registering gratuitous ARP shared channel
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Configuration is using : 61900 Bytes
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: Using LinkWatch kernel netlink reflector...
Nov 20 23:09:56 main-server Keepalived_vrrp[24629]: VRRP sockpool: [ifindex(3), proto(112), unicast(0), fd(10,11)]
Nov 20 23:09:57 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Transition to MASTER STATE
Nov 20 23:09:58 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Entering MASTER STATE
Nov 20 23:09:58 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) setting protocol VIPs.
Nov 20 23:09:58 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Sending gratuitous ARPs on eth0 for 98.76.54.27
Nov 20 23:10:03 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Sending gratuitous ARPs on eth0 for 98.76.54.27
Nov 20 23:16:31 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Received lower prio advert, forcing new election
Nov 20 23:16:31 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Sending gratuitous ARPs on eth0 for 98.76.54.27
Nov 20 23:16:32 main-server Keepalived_vrrp[24629]: VRRP_Instance(nginx1) Received lower prio advert, forcing new election

На резервном сервере

Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Netlink reflector reports IP 98.76.54.29 added
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Netlink reflector reports IP fe80::ec4:7bff:fe4e:df2e added
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Registering Kernel netlink reflector
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Registering Kernel netlink command channel
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Registering gratuitous ARP shared channel
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Configuration is using : 61900 Bytes
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: Using LinkWatch kernel netlink reflector...
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Entering BACKUP STATE
Nov 20 23:10:12 reserve-server Keepalived_vrrp[25944]: VRRP sockpool: [ifindex(3), proto(112), unicast(0), fd(10,11)]
Nov 20 23:10:16 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Transition to MASTER STATE
Nov 20 23:10:17 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Entering MASTER STATE
Nov 20 23:10:17 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) setting protocol VIPs.
Nov 20 23:10:17 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Sending gratuitous ARPs on eth0 for 98.76.54.27
Nov 20 23:10:22 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Sending gratuitous ARPs on eth0 for 98.76.54.27
Nov 20 23:17:59 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Received higher prio advert
Nov 20 23:17:59 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) Entering BACKUP STATE
Nov 20 23:17:59 reserve-server Keepalived_vrrp[25944]: VRRP_Instance(nginx1) removing protocol VIPs.

Если логи выглядет по-другому, значит что-то где-то настроено неверно. Стоит перепроверить настройки фаерволла и keepalived.

Если же логи примерно совпадают с приведёнными выше примерами, то поздравляем: вы настроили VRRP на своем сервере! Обратите внимание, что проверка доступности серверов может быть реализована с помощью check-скриптов, документацию по работе с которыми вы можете найти по ссылке ниже.

Ссылки для более детального изучения затронутых тем: