Keepalived — небольшой демон, который реализует протокол VRRP и умеет переключать виртуальный IP между серверами. Это самый простой способ сделать отказоустойчивым обратный прокси, балансировщик, шлюз или панель управления, не покупая оборудование и не усложняя схему. Ниже — рабочая конфигурация из двух узлов, проверка сервиса, защита от разделения сети и разбор ошибок, которые встречаются чаще всего.

Как работает VRRP

Два и более узла объединяются в виртуальный маршрутизатор с общим идентификатором VRID. Один узел становится MASTER и отвечает на ARP-запросы для виртуального адреса, остальные находятся в состоянии BACKUP и слушают служебные пакеты. Если MASTER перестаёт отправлять анонсы, BACKUP ждёт истечения таймера и забирает адрес себе.

Пакеты VRRP передаются по multicast на адрес 224.0.0.18, протокол номер 112. Это важно для настройки фильтра пакетов: если вы разрешили только TCP и ICMP, VRRP молча не заработает. В облачных сетях, где multicast запрещён, используется режим unicast_peer с явным списком адресов.

Установка и базовая проверка

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

sudo apt install keepalived
systemctl status keepalived --no-pager
ip -br addr show
ip route show default

В примерах ниже используется интерфейс eth0, адреса 10.0.0.11 и 10.0.0.12, виртуальный адрес 10.0.0.10 и VRID 51. Замените их на свои, но сохраните логику: у каждого узла свой приоритет, а virtual_router_id и пароль совпадают.

Конфигурация MASTER

Файл /etc/keepalived/keepalived.conf читается при старте. Параметр state задаёт желаемую роль, но итоговое состояние определяется приоритетом: узел с большим priority становится MASTER. Параметр advert_int задаёт интервал анонсов в секундах.

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ChangeMe2026
    }
    virtual_ipaddress {
        10.0.0.10/24 dev eth0
    }
}

На втором узле меняются только state, priority и, при желании, ничего больше. Второй узел получает priority 100 и state BACKUP. Пароль должен совпадать: несовпадение — классическая причина, по которой оба узла остаются в состоянии BACKUP или конфликтуют за адрес.

Проверки доступности сервиса

VRRP следит за сетевым интерфейсом, но не за приложением. Если nginx упал, а хост жив, адрес останется на нём, и пользователи получат ошибку. Решение — скрипт проверки, который уменьшает приоритет при сбое. Модуль weight должен превышать разницу приоритетов, иначе после снижения узел всё равно останется MASTER.

vrrp_script check_nginx {
    script "/usr/bin/curl -fsS -o /dev/null http://127.0.0.1/health"
    interval 2
    timeout 2
    fall 3
    rise 2
    weight -60
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    track_script {
        check_nginx
    }
    virtual_ipaddress {
        10.0.0.10/24 dev eth0
    }
}

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

Проверка состояния и переключения

Утилита ip показывает, на каком узле сейчас находится виртуальный адрес. Журнал демона фиксирует переходы роли и причины. Для теста остановите keepalived на MASTER или погасите nginx и наблюдайте за вторым узлом.

ip -br addr show eth0
sudo journalctl -u keepalived -n 50 --no-pager
sudo systemctl stop keepalived
ping -c 4 10.0.0.10

После остановки службы на основном узле адрес должен появиться на резервном в течение нескольких секунд. Если этого не происходит, проверьте, что оба узла видят друг друга, VRID совпадает, а интерфейс не находится в состоянии DOWN.

Защита от split-brain

Split-brain — ситуация, когда оба узла считают себя MASTER и одновременно отвечают на ARP. Обычно причина в потере связи между узлами при живых сервисах. Последствия неприятны: часть клиентов уходит на один узел, часть на другой, сессии теряются, а данные могут разойтись.

Меры профилактики: отдельный канал связи между узлами, unicast вместо multicast в облаке, запрет на два узла с одинаковым приоритетом и внешний арбитр. Если приложение пишет данные, плавающий IP сам по себе не гарантирует целостность — нужна репликация или общее хранилище.

Unicast в облаке и фильтр пакетов

В облачных сетях multicast часто запрещён, и VRRP приходится переводить в режим явных адресов. Тогда каждый узел знает, кому отправлять анонсы, и служебный трафик идёт обычным unicast. Это же решение помогает в сетях, где IGMP-снупинг настроен непредсказуемо.

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    unicast_src_ip 10.0.0.12
    unicast_peer {
        10.0.0.11
    }
    virtual_ipaddress {
        10.0.0.10/24 dev eth0
    }
}

Не забудьте разрешить протокол 112 между адресами узлов. Правило вида «разрешить весь трафик внутри подсети» работает, но слишком широко: ограничьте источник и назначение конкретными адресами. Для диагностики используйте tcpdump с фильтром proto 112 — он покажет, доходят ли анонсы и совпадают ли VRID.

Типичные ошибки

  • Одинаковый priority на обоих узлах: роль выбирается непредсказуемо.
  • Разные virtual_router_id или пароли: узлы не объединяются в группу.
  • Закрытый протокол 112 на межсетевом экране: анонсы не доходят.
  • Скрипт проверки без веса или с малым weight: приоритет не меняется, переключения нет.
  • Виртуальный адрес не в той подсети: клиенты не могут до него достучаться.
  • Отсутствие проверки приложения: адрес остаётся на сломанном узле.

Чек-лист внедрения

  • Приоритеты различаются минимум на величину weight скрипта.
  • Проверка сервиса возвращает ошибку при реальной деградации.
  • VRRP разрешён на обоих узлах, multicast или unicast настроен явно.
  • Виртуальный адрес не пересекается с DHCP-пулом.
  • Переключение протестировано вручную и под нагрузкой.
  • Настроен мониторинг того, на каком узле находится адрес.

Итог

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

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте