Keepalived: настройка высокой доступности и плавающих IP адресов в CentOS 7

Keepalived: настройка высокой доступности и плавающих IP адресов в CentOS 7

В этой статье мы рассмотрим настройку отказоустойчивой конфигурации из двух прокси серверов squid для доступа пользователей в Интернет из корпоративной сети с простой балансировкой нагрузки через Round Robin DNS. Для построения отказоустойчивой конфигурации мы создадим HA-кластер с помощью keepalived.

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

  • Проверка состояния серверов;
  • Автоматическое переключение ресурсов в случае отказа сервера;

Обе эти задачи позволяет выполнить keepalived. Keepalived – системный демон на Linux системах, позволяющего организовать отказоустойчивость сервиса и балансировку нагрузки. Отказоустойчивость достигается за счет “плавающего» IP адреса, который переключается на резервный сервер в случае отказа основного. Для автоматического переключения IP адреса между серверами keepalived используется протокол VRRP (Virtual Router Redundancy Protocol), он стандартизирован, описан в RFC (https://www.ietf.org/rfc/rfc2338.txt).

Принципы работы протокола VRRP

В первую очередь нужно рассмотреть теорию и основные определения протокола VRRP.

  • VIP — Virtual IP, виртуальный IP адрес, который может автоматически переключаться между серверами в случае сбоев;
  • Master — сервер, на котором в данный момент активен VIP;
  • Backup — сервера на которые переключится VIP, в случае сбоя мастера;
  • VRID — Virtual Router ID, сервера объединенные общим виртуальным IP(VIP) образуют так называемый виртуальный роутер, уникальный идентификатор которого, принимает значения от 1 до 255. Сервер может одновременно состоять в нескольких VRID, при этом для каждой VRID должны использоваться уникальные виртуальные IP адреса.

Общий алгоритм работы:

Установка и настройка keepalived на CentOS

Установку и настройку будем проводить на примере серверов proxy-serv01 и proxy-serv02 на Centos 7 с установленным прокси сервером Squid. В нашей схеме мы будем использовать простейший способ распределения (балансировки) нагрузки — Round Robin DNS. Этот способ предполагает, что для одного имени в DNS регистрируется несколько IP адресов, и клиенты, при запросе получают поочередно сначала один адрес, потом другой. Поэтому нам понадобится два виртуальных IP адреса, которые будут зарегистрированы в DNS на одно имя и на которые в итоге будут обращаться клиенты. Схема сети:

настройка отказоустойчивого балансировщика нагрузки с плавающим IP адресом с помощью keepalived

У каждого Linux сервера есть два физических сетевых интерфейса: eth1 с белым IP адресом и доступом в Интернет, и eth0 в локальной сети.

В качестве реальных IP адресов серверов используются:
192.168.2.251 — для proxy-server01
192.168.2.252 — для proxy-server02

В качестве виртуальных IP адресов, которые будут автоматически переключаться между серверами в случае сбоев используются:
192.168.2.101
192.168.2.102

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

Установить пакет keepalived нужно на обоих серверах, командой:

yum install keepalived

После завершения установки на обоих серверах правим конфигурационный файл

/etc/keepalived/keepalived.conf

Цветом выделены строки с отличающимися параметрами:

на сервере proxy-serv01 на сервере proxy-serv02
keepalived - конфиг master сервера keepalived - конфиг backup сервера

Разберем опции более подробно:

  • vrrp_instance — секция, определяющая экземпляр VRRP;
  • state — начальное состояние при запуске;
  • interface — интерфейс, на котором будет работать VRRP;
  • virtual_router_id — уникальный идентификатор VRRP экземпляра, должен совпадать на всех серверах;
  • priority — задает приоритет при выборе MASTER, сервер с большим приоритетом становится MASTER;
  • virtual_ipaddress — блок виртуальных IP адресов, которые будут активны на сервере в состоянии MASTER. Должны совпадать на всех серверах внутри VRRP экземпляра.

Примечание. Можно встретить множество примеров, в которых при настройке VRRP используется опция authentication. Однако в документации keepalived упоминается о том, что аутентификация была удалена из VRRPv2 в спецификации RFC3768(https://tools.ietf.org/html/rfc3768) в 2004 году, так как не обеспечивала реальной безопасности. Рекомендуется избегать использования этой опции.

Если текущая сетевая конфигурация не позволяет использовать multicast, в keepalived есть возможность использовать unicast, т.е. передавать VRRP пакеты напрямую серверам, которые задаются списком. Чтобы использовать unicast, понадобятся опции:

  • unicast_src_ip — адрес источник для VRRP пакетов;
  • unicast_peer — блок IP адресов серверов, на которые будут рассылаться VRPP пакеты.

Таким образом, наша конфигурация определяет два VRRP экземпляра, proxy_ip1 и proxy_ip2. При штатной работе, сервер proxy-serv01 будет MASTER для виртуального IP 192.168.2.101 и BACKUP для 192.168.2.102, а сервер proxy-serv02 наоборот, будет MASTER для виртуального IP 192.168.2.102, и BACKUP для 192.168.2.101.

Если на сервере активирован файрвол, то нужно добавить разрешающие правила для multicast траффика и vrrp протокола с помощью iptables:

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

Активируем автозагрузки и запустим службу keepalived на обоих серверах:

systemctl enable keepalived
systemctl start keepalived

После запуска службы keepalived, виртуальные IP будут присвоены интерфейсам из конфигурационного файла. Посмотрим текущие IP адреса на интерфейсе eth0 серверов:

ip a show eth0

На сервере proxy-serv01:

ip a show eth0 master keepalived

На сервере proxy-serv02:

ip a show eth0 backup keepalived

Keepalived: отслеживание состояния приложений и интерфейсов

Благодаря протоколу VRRP штатно обеспечивается мониторинг состояния сервера, например, при полном физическом отказе сервера, или сетевого порта на сервере или коммутаторе. Однако, возможны и другие проблемные ситуации:

  • ошибка в работе службы прокси сервера — клиенты, которые попадут на виртуальный адрес этого сервера, будут получать сообщение в браузере с ошибкой, что прокси сервер недоступен;
  • отказ в работе второго интерфейса в интернет — клиенты, которые попадут на виртуальный адрес этого сервера, будут получать сообщение в браузере с ошибкой, что не удалось установить соединение.

Для обработки перечисленных выше ситуаций, воспользуемся следующими опциями:

  • track_interface — мониторинг состояния интерфейсов, переводит VRRP экземпляр в состояние FAULT, если один из перечисленных интерфейсов находится в состоянии DOWN;
  • track_script — мониторинг с использованием скрипта, который должен возвращать 0 если проверка завершилась успешно , 1 — если проверка завершилась с ошибкой.

Обновим конфигурацию, добавим мониторинг интерфейса eth1 (по умолчанию, VRRP экземпляр будет проверять интерфейс, к которому он привязан, т.е. в текущей конфигурации eth0):

track_interface {
eth1

}

Директива track_script запускает скрипт с параметрами, определенными в блоке vrrp_script, который имеет следующий формат:

vrrp_script  {
script 
interval  - периодичность запуска скрипта, по умолчанию 1 секунда
fall  - количество раз, которое скрипт вернул не нулевое значение, при котором перейти в состояние FAULT
rise  - количество раз, которое скрипт вернул нулевое значение, при котором выйти из состояния FAULT
timeout  - время ожидания, пока скрипт вернет результат, после которого вернуть ненулевое значение.
weight  - значение, на которое будет уменьшен приоритет сервера, в случае перехода в состояние FAULT. По умолчанию 0, что означает, что сервер перейдет в состояние FAULT, после неудачного выполнения скрипта за количество раз, определенное параметром fall.
}

Настроим мониторинг работы Squid. Проверить, что процесс активен, можно командой:

squid -k check

Создадим vrrp_script, с параметрами периодичности выполнения каждые 3 секунды. Этот блок определяется за пределами блоков vrrp_instance.

vrrp_script chk_squid_service {
script "/usr/sbin/squid -k check"
interval 3
}

Добавим наш скрипт в мониторинг, внутри обоих блоков vrrp_instance:

track_script {
chk_squid_service
}

Теперь при ошибке в работе службы прокси Squid, виртуальный IP адрес переключится на другой сервер.

Вы можете добавить дополнительные действия при изменении состояния сервера.

Если Squid настроен на прием подключений с любого интерфейса, т.е. http_port 0.0.0.0:3128, то при переключении виртуального IP адреса, никаких проблем не возникнет, Squid будет принимать подключения на новом адресе. Но, если настроены конкретные IP адреса, например:

http_port 192.168.2.101:3128
http_port 192.168.2.102:3128

то Squid не узнает о том, что в системе появился новый адрес, на котором нужно слушать запросы от клиентов. Для обработки подобных ситуаций, когда нужно выполнить дополнительные действия при переключении виртуального IP адреса, в keepalived заложена возможность выполнения скрипта при наступлении события изменения состояния сервера, например, с MASTER на BACKUP, или наоборот. Реализуется опцией:

notify "путь к исполняемому файлу"

Keepalived: тестирование переключения при отказе

После настройки виртуальных IP, проверим, насколько корректно происходит обработка сбоев. Первая проверка — имитация сбоя одного из серверов. Отключим от сети внутренний сетевой интерфейс eth0 сервера proxy-serv01, при этом он перестанет отправлять VRRP пакеты и сервер proxy-serv02 должен активировать у себя виртуальный IP адрес 192.168.2.101. Результат проверим командой:

ip a show eth0

На сервере proxy-serv01:

keepalived - state DOWN

На сервере proxy-serv02:

keepalived - state up

Как и ожидалось, сервер proxy-serv02 активировал у себя виртуальный IP адрес 192.168.2.101. Посмотрим, что при этом происходило в логах, командой:

cat /var/log/messages | grep -i keepalived

на сервере proxy-serv01 на сервере proxy-serv02
Keepalived_vrrp[xxxxx]:
Kernel is reporting: interface eth0 DOWN
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering FAULT STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) removing protocol VIPs.
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Now in FAULT state
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Transition to MASTER STATE
Keepalived получает сигнал, что интерфейс eth0 находится в состоянии DOWN, и переводит VRRP экземпляр proxy_ip1 в состояние FAULT, освобождая виртуальные IP адреса. Keepalived переводит VRRP экземпляр proxy_ip1 в состояние MASTER, активирует адрес 192.168.2.101 на интерфейсе eth0 и отправляет gratuitous ARP.

VRRP Entering FAULT STATEVRRP_Instance Transition to MASTER STATE

И проверим, что после включения в сеть интерфейса eth0 на сервере proxy-serv01, виртуальный IP 192.168.2.101 переключится обратно.

на сервере proxy-serv01 на сервере proxy-serv02
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) forcing a new MASTER election
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Transition to MASTER STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering MASTER STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) setting protocol VIPs.
Keepalived_vrrp[xxxxx]:
Sending gratuitous ARP on eth0 for 192.168.2.101
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Received advert with higher priority 255, ours 100
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering BACKUP STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) removing protocol VIPs.
Keepalived получает сигнал о восстановлении интерфейса eth0 и начинает новые выборы MASTER для VRRP экземпляра proxy_ip1. После перехода в состояние MASTER, активирует адрес 192.168.2.101 на интерфейсе eth0 и отправляет gratuitous ARP. Keepalived получает пакет с большим приоритетом для VRRP экземпляра proxy_ip1 и переводит proxy_ip1 в состояние BACKUP и освобождает виртуальные IP адреса.

Вторая проверка – имитация сбоя интерфейса внешний сети, для этого отключим от сети внешний сетевой интерфейс eth1 сервера proxy-serv01. Результат проверки проконтролируем по логам.

на сервере proxy-serv01 на сервере proxy-serv02
Keepalived_vrrp[xxxxx]:
Kernel is reporting: interface eth1 DOWN
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering FAULT STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) removing protocol VIPs.
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Now in FAULT state
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Transition to MASTER STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering MASTER STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) setting protocol VIPs.
Keepalived_vrrp[xxxxx]:
Sending gratuitous ARP on eth0 for 192.168.2.101

Keepalived получает сигнал, что интерфейс eth1 находится в состоянии DOWN, и переводит VRRP экземпляр proxy_ip1 в состояние FAULT, освобождая виртуальные IP адреса. Keepalived переводит VRRP экземпляр proxy_ip1 в состояние MASTER, активирует адрес 192.168.2.101 на интерфейсе eth0 и отправляет gratuitous ARP.

Keepalived Now in FAULT state

Третья проверка — имитация сбоя работы службы прокси Squid, для этого вручную оставим службу командой:
systemctl stop squid
Результат проверки проконтролируем по логам.

на сервере proxy-serv01 на сервере proxy-serv02
Keepalived_vrrp[xxxxx]:
VRRP_Script(chk_squid_service) failed
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering FAULT STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) removing protocol VIPs.
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Now in FAULT state
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Transition to MASTER STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) Entering MASTER STATE
Keepalived_vrrp[xxxxx]:
VRRP_Instance(proxy_ip1) setting protocol VIPs.
Keepalived_vrrp[xxxxx]:
Sending gratuitous ARP on eth0 for 192.168.2.101
Скрипт проверки активности службы прокси squid завершается с ошибкой. Keepalived переводит VRRP экземпляр proxy_ip1 в состояние FAULT, освобождая виртуальные IP адреса. Keepalived переводит VRRP экземпляр proxy_ip1 в состояние MASTER, активирует адрес 192.168.2.101 на интерфейсе eth0 и отправляет gratuitous ARP.

Все три проверки пройдены успешно, keepalived настроен корректно. В продолжении этой статьи будет произведена настройка HA-кластера с помощью Pacemaker, и рассмотрена специфика каждого из этих инструментов.

Итоговый конфигурационный файл /etc/keepalived/keepalived.conf для сервера proxy-serv01:

vrrp_script chk_squid_service {
script "/usr/sbin/squid -k check"
interval 3
}
vrrp_instance proxy_ip1 {
state MASTER
interface eth0
virtual_router_id 1
priority 255
virtual_ipaddress {
192.168.2.101/24 dev eth0 label eth0:1
}
track_interface {
eth1
}
track_script {
chk_squid_service
}
}
vrrp_instance proxy_ip2 {
state BACKUP
interface eth0
virtual_router_id 2
priority 100
virtual_ipaddress {
192.168.2.102/24 dev eth0 label eth0:2
}
track_interface {
eth1
}
track_script {
chk_squid_service
}
}

Итоговый конфигурационный файл /etc/keepalived/keepalived.conf для сервера proxy-serv02:

vrrp_script chk_squid_service {
script "/usr/sbin/squid -k check"
interval 3
}
vrrp_instance proxy_ip1 {
state BACKUP
interface eth0
virtual_router_id 1
priority 100
virtual_ipaddress {
192.168.2.101/24 dev eth0 label eth0:1
}
track_interface {
eth1
}
track_script {
chk_squid_service
}
}
vrrp_instance proxy_ip2 {
state MASTER
interface eth0
virtual_router_id 2
priority 255
virtual_ipaddress {
192.168.2.102/24 dev eth0 label eth0:2
}
track_interface {
eth1
}
track_script {
chk_squid_service
}
}

Linux
Keepalived: настройка высокой доступности и плавающих IP адресов в CentOS 7