Проблема
Одиночный сервер, на котором работают nginx и ваше веб-приложение, неизбежно становится точкой отказа. Выход из строя аппаратного обеспечения, сбой питания, плановое обслуживание или даже кратковременная потеря сетевой связности приводят к тому, что пользователи теряют доступ к сервису. В небольших проектах, где ещё нет полноценного облачного балансировщика, администраторы часто мирятся с простоями, хотя добавить высокую доступность можно буквально за час. Keepalived в связке с nginx позволяет организовать отказоустойчивый кластер из двух и более узлов, где один сервер активно обрабатывает запросы, а второй находится в горячем резерве и автоматически подхватывает трафик при сбое основного. При этом клиентам не нужно менять IP-адрес: виртуальный IP (VIP) всегда остаётся одним и тем же.
Решение
Мы построим классическую схему Active-Passive с двумя узлами. На обоих серверах будет установлен nginx, обслуживающий один и тот же набор сайтов. Keepalived управляет виртуальным IP-адресом: пока мастер-узел жив, VIP висит на нём; как только мастер перестаёт отвечать, VIP моментально мигрирует на резервный узел. Механизм базируется на протоколе VRRP (Virtual Router Redundancy Protocol), описанном в RFC 3768 и реализованном демоном keepalived, чья документация доступна на официальном сайте. В качестве health-проверки будем использовать vrrp_script, который следит за состоянием nginx: если веб-сервер упал, мастер добровольно отдаёт VIP резервному узлу, чтобы тот начал отвечать на запросы, пока проблема не будет устранена.
Пошаговая инструкция
Шаг 1. Подготовка двух серверов и настройка сети
Понадобятся два сервера с Linux (Debian/Ubuntu или RHEL-подобные). Оба должны находиться в одном L2-сегменте (одна подсеть), так как VRRP использует multicast 224.0.0.18. Пример конфигурации:
-
Узел 1 (master): IP
192.168.1.10 -
Узел 2 (backup): IP
192.168.1.11 -
Виртуальный IP (VIP):
192.168.1.100
Убедитесь, что сетевые интерфейсы сконфигурированы статически и оба сервера могут пинговать друг друга.
Шаг 2. Установка nginx на оба сервера
На обоих узлах выполните:
bash
sudo apt update && sudo apt install nginx -y # Debian/Ubuntu
# sudo dnf install nginx -y # RHEL/Rocky Linux
Для теста замените содержимое стандартного index.html на что-то, указывающее на конкретный сервер:
bash
echo "Server 1" | sudo tee /var/www/html/index.html # на первом
echo "Server 2" | sudo tee /var/www/html/index.html # на втором
Проверьте, что nginx отвечает локально: curl localhost.
Шаг 3. Установка keepalived
На обоих серверах установите пакет keepalived. Он доступен в стандартных репозиториях:
bash
sudo apt install keepalived -y
После установки демон запустится и будет читать конфигурацию из /etc/keepalived/keepalived.conf.
Шаг 4. Настройка keepalived на мастере (Узел 1)
Создайте конфигурационный файл /etc/keepalived/keepalived.conf:
bash
sudo nano /etc/keepalived/keepalived.conf
Содержимое для мастер-узла:
nginx
global_defs {
router_id SRV1
}
# Скрипт проверки, жив ли nginx
vrrp_script chk_nginx {
script "killall -0 nginx" # возвращает 0, если процесс существует
interval 2 # интервал проверки, секунды
weight -2 # сколько вычесть из приоритета при провале
}
vrrp_instance VI_1 {
state MASTER # начальное состояние
interface eth0 # замените на ваш интерфейс (ip a)
virtual_router_id 51 # уникальный ID (1-255), должен совпадать на обоих узлах
priority 100 # приоритет (на мастере выше)
advert_int 1 # интервал анонсов VRRP, секунды
authentication {
auth_type PASS
auth_pass secret123 # общий пароль (только первые 8 символов значимы)
}
virtual_ipaddress {
192.168.1.100/24 # виртуальный IP
}
track_script {
chk_nginx # отслеживаем состояние nginx
}
}
Пояснения:
-
router_id— произвольное имя, полезно для логов. -
vrrp_script chk_nginxкаждые 2 секунды запускаетkillall -0 nginx. Если процесс не найден, скрипт возвращает ненулевой код, и приоритет мастера снижается на 2 (weight -2). В результате приоритет становится 98, что ниже, чем у резервного узла (приоритет 99), и VIP переезжает. -
auth_pass secret123— пароль для VRRP-аутентификации; должен совпадать на обоих узлах. Хотя VRRP-аутентификация не является надёжным шифрованием, она защищает от случайного появления в сети другого VRRP-роутера.
Шаг 5. Настройка keepalived на резервном узле (Узел 2)
Файл /etc/keepalived/keepalived.conf на втором сервере:
nginx
global_defs {
router_id SRV2
}
vrrp_script chk_nginx {
script "killall -0 nginx"
interval 2
weight -2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass secret123
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_nginx
}
}
Отличия: state BACKUP, priority 99, router_id SRV2. Всё остальное идентично.
Шаг 6. Запуск и проверка кластера
На обоих серверах перезапустите службу keepalived и убедитесь, что она активна:
bash
sudo systemctl restart keepalived
sudo systemctl status keepalived
Проверьте, что на мастер-узле VIP появился на интерфейсе:
bash
ip addr show eth0 | grep 192.168.1.100
Выполните тестовый HTTP-запрос на VIP:
bash
curl http://192.168.1.100
Вы должны увидеть «Server 1».
Теперь сымитируем отказ nginx на мастере:
bash
sudo systemctl stop nginx
Через несколько секунд VIP должен мигрировать на резервный узел. Повторите curl http://192.168.1.100 — теперь ответом должно быть «Server 2». Запустите nginx снова (sudo systemctl start nginx). VIP вернётся на мастер, так как его приоритет снова станет выше.
Шаг 7. Мониторинг и логи
Логи keepalived записываются в системный журнал. Просматривайте их для диагностики:
bash
sudo journalctl -u keepalived -f
При переключении вы увидите сообщения о смене состояния (MASTER/BACKUP) и причине (например, снижение приоритета из-за провала скрипта проверки).
Для более детального мониторинга можно настроить оповещения через почту или скрипты, используя директивы notify_master, notify_backup, notify_fault в конфигурации VRRP-инстанса.
Устранение распространённых проблем
| Симптом | Вероятная причина | Решение |
|---|---|---|
| VIP не появляется ни на одном узле, в логах «Keepalived started» и тишина | Разные virtual_router_id на узлах, multicast заблокирован firewall или интерфейсы в разных VLAN | Проверьте, что ID совпадают. Убедитесь, что firewall разрешает протокол VRRP (IP protocol 112). Временно отключите брандмауэр для теста: sudo ufw disable. |
| VIP одновременно висит на обоих узлах (split-brain) | Потеря связи между узлами (сетевой разрыв), multicast не доходит | Проверьте связность ping 192.168.1.11 с первого узла и наоборот. Убедитесь, что switch не блокирует multicast. Добавьте опцию garp_master_delay 5 в vrrp_instance для задержки Gratuitous ARP. |
| При остановке nginx VIP не уходит с мастера | Скрипт killall -0 nginx не работает или track_script не настроен | Проверьте скрипт вручную: killall -0 nginx; echo $?. Убедитесь, что пакет psmisc установлен (для killall). Добавьте логирование в скрипт: echo "nginx is dead" >> /tmp/vrrp.log. |
| VIP возвращается на мастер слишком быстро после восстановления nginx | Низкий advert_int или отсутствие задержки | Увеличьте advert_int до 2-3 секунд и добавьте preempt_delay 60 в инстанс, чтобы мастер ждал минуту перед возвратом VIP. |
| Keepalived не запускается, ошибка «Configuration file error» | Синтаксическая ошибка в keepalived.conf | Проверьте конфигурацию командой sudo keepalived -t. Логи укажут на строку с ошибкой. |
Keepalived в паре с nginx это минималистичный, но очень эффективный способ избавиться от единой точки отказа для веб-сервисов. Два сервера, пара десятков строк конфигурации и несколько минут настройки дают вам горячий резерв с автоматическим переключением, не требуя дорогих аппаратных балансировщиков или облачных услуг. Такая схема отлично работает в корпоративных интранет-порталах, на сайтах с умеренной нагрузкой и в инфраструктуре, где критически важна высокая доступность без значительного усложнения администрирования.







