Введение в отказоустойчивость Nginx
Одиночный веб-сервер - это единая точка отказа. При сбое оборудования, сетевых проблемах или обновлении ПО ваш сайт или приложение станут недоступны. Кластеризация Nginx решает эту проблему, создавая систему из двух или более серверов, которые работают вместе для обеспечения непрерывной доступности.
Эта статья предоставляет практическое руководство по развертыванию двух основных архитектур: актив-активной и актив-пассивной. Вы получите проверенные конфигурационные файлы, команды для синхронизации данных и инструкции по настройке автоматического переключения. Все примеры тестировались на Ubuntu 22.04 LTS с Nginx 1.24 и актуальны на май 2026 года.
Сравнение архитектур: какую выбрать?
Первый шаг - выбор подходящей схемы. Обе обеспечивают отказоустойчивость, но различаются по производительности, сложности и стоимости.
Актив-пассивный режим (Active-Passive)
В этой схеме работает только один сервер (активный), обрабатывая весь входящий трафик. Второй сервер (пассивный) находится в режиме ожидания. При сбое активного узла пассивный автоматически берет на себя его функции. Это классическая схема высокой доступности.
Преимущества:
- Простота настройки и понимания.
- Минимальные требования к синхронизации данных (только конфигурации и статический контент).
- Предсказуемая производительность.
Недостатки:
- Неиспользуемые ресурсы резервного сервера.
- Пропускная способность ограничена мощностью одного узла.
Идеально для: критически важных бизнес-приложений, где простота и надежность важнее максимальной производительности, систем с умеренным трафиком.
Актив-активный режим (Active-Active)
Все серверы в кластере одновременно обрабатывают входящие запросы. Нагрузка распределяется между ними, обычно с помощью внешнего балансировщика или DNS-ротации.
Преимущества:
- Полное использование вычислительных ресурсов всех узлов.
- Высокая масштабируемость и пропускная способность.
- Возможность планового обслуживания без простоя.
Недостатки:
- Сложность настройки, особенно синхронизации сессий пользователей.
- Требуется общее хранилище или сложная репликация данных.
- Более высокая стоимость инфраструктуры.
Идеально для: высоконагруженных проектов, где критична производительность, горизонтально масштабируемых приложений, CDN-сетей.
| Критерий | Актив-пассивный | Актив-активный |
|---|---|---|
| Производительность | Ограничена одним узлом | Суммарная мощность всех узлов |
| Сложность настройки | Низкая | Высокая |
| Использование ресурсов | Резервный сервер простаивает | Все серверы загружены |
| Отказоустойчивость | Высокая (простой failover) | Очень высокая (продолжение работы при потере узла) |
| Стоимость эффективности | Ниже | Выше |
Для большинства корпоративных проектов актив-пассивная схема с Keepalived - оптимальный баланс надежности и сложности. Актив-активный режим выбирайте при явной нехватке производительности одного сервера. Более глубокое сравнение технологий балансировки, включая HAProxy, вы найдете в статье «Балансировка нагрузки в 2026: Nginx, HAProxy и Keepalived».
Пошаговая настройка актив-пассивного кластера с Keepalived
Реализуем классическую схему с виртуальным IP-адресом (VIP), который перемещается между серверами при сбое. Для этого используем Keepalived и протокол VRRP.
Шаг 1: Подготовка серверов
У вас должно быть два сервера с установленным Nginx. Для примера используем адреса:
- Nginx-01 (основной): 192.168.1.10
- Nginx-02 (резервный): 192.168.1.11
- Виртуальный IP (VIP): 192.168.1.100
Убедитесь, что на обоих серверах установлен Nginx и он запущен. Проверьте доступность веб-сервера по их реальным IP-адресам.
Шаг 2: Установка и настройка Keepalived
Установите Keepalived на оба сервера:
sudo apt update
sudo apt install keepalived -y
Конфигурация для основного сервера (Nginx-01, 192.168.1.10):
Создайте файл /etc/keepalived/keepalived.conf:
vrrp_script chk_nginx {
script "/usr/bin/pgrep nginx"
interval 2
weight 2
}
vrrp_instance VI_1 {
state MASTER
interface ens18 # Укажите ваш сетевой интерфейс (ip addr show)
virtual_router_id 51
priority 101 # Приоритет выше, чем у резервного
advert_int 1
authentication {
auth_type PASS
auth_pass secure_password_123 # Замените на свой пароль
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_nginx
}
}
Конфигурация для резервного сервера (Nginx-02, 192.168.1.11):
Файл /etc/keepalived/keepalived.conf на втором сервере отличается только параметрами state и priority:
vrrp_instance VI_1 {
state BACKUP # Изменено с MASTER на BACKUP
interface ens18
virtual_router_id 51
priority 100 # Приоритет ниже, чем у основного
# ... остальные параметры идентичны
}
Шаг 3: Запуск и проверка
Запустите Keepalived на обоих серверах и добавьте в автозагрузку:
sudo systemctl start keepalived
sudo systemctl enable keepalived
Проверьте статус службы и назначение VIP:
sudo systemctl status keepalived
ip addr show ens18 | grep 192.168.1.100
VIP должен быть назначен на интерфейс основного сервера (Nginx-01). Теперь пользователи обращаются к кластеру по адресу 192.168.1.100.
Шаг 4: Тестирование отказоустойчивости
Сымитируйте сбой основного сервера:
- Остановите Keepalived на Nginx-01:
sudo systemctl stop keepalived - Через 1-2 секунды проверьте назначение VIP на Nginx-02:
ip addr show ens18 - Убедитесь, что веб-сайт доступен по адресу 192.168.1.100
После восстановления Nginx-01 VIP вернется к нему, так как у него более высокий приоритет (preemption включен по умолчанию).
Синхронизация конфигураций и статического контента
В актив-пассивном кластере оба сервера должны иметь идентичные конфигурационные файлы Nginx и статический контент. Рассмотрим два практических метода.
Метод 1: Rsync через cron
Простой и надежный способ. На основном сервере создайте скрипт синхронизации /usr/local/bin/sync-nginx-config.sh:
#!/bin/bash
RSYNC_OPTS="-az --delete"
REMOTE_USER="root"
REMOTE_HOST="192.168.1.11" # Адрес резервного сервера
# Синхронизация конфигураций Nginx
rsync $RSYNC_OPTS /etc/nginx/ $REMOTE_USER@$REMOTE_HOST:/etc/nginx/
# Синхронизация веб-контента (пример для сайта в /var/www/html)
rsync $RSYNC_OPTS /var/www/html/ $REMOTE_USER@$REMOTE_HOST:/var/www/html/
# Перезагрузка Nginx на удаленном сервере для применения изменений
ssh $REMOTE_USER@$REMOTE_HOST "nginx -t && systemctl reload nginx"
Сделайте скрипт исполняемым и настройте выполнение каждые 5 минут через cron:
sudo chmod +x /usr/local/bin/sync-nginx-config.sh
sudo crontab -e
# Добавьте строку:
*/5 * * * * /usr/local/bin/sync-nginx-config.sh
Метод 2: Lsyncd (синхронизация в реальном времени)
Lsyncd отслеживает изменения в файловой системе и мгновенно реплицирует их. Установите на основном сервере:
sudo apt install lsyncd -y
Настройте конфигурацию в /etc/lsyncd/lsyncd.conf.lua:
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 20
}
sync {
default.rsync,
source = "/etc/nginx/",
target = "root@192.168.1.11:/etc/nginx/",
rsync = {
archive = true,
compress = true,
delete = true
}
}
sync {
default.rsync,
source = "/var/www/html/",
target = "root@192.168.1.11:/var/www/html/",
rsync = {
archive = true,
compress = true,
delete = true
}
}
Запустите и включите Lsyncd:
sudo systemctl start lsyncd
sudo systemctl enable lsyncd
Теперь любые изменения в конфигурациях или контенте на основном сервере автоматически копируются на резервный.
Настройка актив-активного кластера
В актив-активной схеме мы используем внешний балансировщик для распределения трафика между несколькими работающими серверами Nginx. Сам Nginx может выступать в этой роли, создавая многоуровневую архитектуру.
Архитектура с балансировщиком нагрузки
Создадим три сервера:
- Балансировщик (LB): 192.168.1.20 (отдельный сервер с Nginx)
- Веб-узел 1 (Web-01): 192.168.1.21
- Веб-узел 2 (Web-02): 192.168.1.22
Конфигурация балансировщика
На сервере LB настройте Nginx как балансировщик. Файл /etc/nginx/nginx.conf или включенный конфиг в sites-available:
upstream backend_cluster {
# Используем least_conn для балансировки по минимальному количеству соединений
least_conn;
server 192.168.1.21:80 max_fails=3 fail_timeout=30s;
server 192.168.1.22:80 max_fails=3 fail_timeout=30s;
# Health check каждые 5 секунд
keepalive 32;
}
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Таймауты
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
}
# Страница статуса для мониторинга (ограничьте доступ)
location /nginx_status {
stub_status on;
allow 192.168.1.0/24; # Только внутренняя сеть
deny all;
}
}
Эта конфигурация автоматически исключает неработающие серверы благодаря параметрам max_fails и fail_timeout. Подробнее о продвинутых health checks читайте в руководстве «Nginx как балансировщик нагрузки: продвинутая настройка высокой доступности».
Настройка веб-узлов
На Web-01 и Web-02 настройте идентичные конфигурации Nginx для обслуживания вашего приложения. Для синхронизации контента между узлами используйте общее хранилище:
Вариант A: Сетевая файловая система (NFS)
- Настройте NFS-сервер на отдельной машине или на одном из веб-узлов.
- Смонтируйте общую директорию на всех веб-узлах в /var/www/html.
- Убедитесь, что права доступа корректны для пользователя www-data.
Вариант B: Распределенная файловая система (GlusterFS)
Более отказоустойчивое решение:
# На каждом веб-узле
sudo apt install glusterfs-server -y
sudo systemctl start glusterd
sudo systemctl enable glusterd
# Создание реплицируемого тома (выполняется на одном из узлов)
sudo gluster volume create web-content replica 2 transport tcp \
192.168.1.21:/data/gluster \
192.168.1.22:/data/gluster force
sudo gluster volume start web-content
# Монтирование на каждом узле
mount -t glusterfs 192.168.1.21:/web-content /var/www/html
Интеграция с внешними системами
Кластер Nginx редко работает изолированно. Рассмотрим подключение к базам данных и управление сессиями.
Работа с внешней базой данных
При использовании актив-активного кластера убедитесь, что ваше приложение поддерживает подключение к одной внешней БД или использует реплицированную/кластерную СУБД (например, PostgreSQL с репликацией, Redis Cluster, MongoDB replica set). Настройки подключения к БД должны быть идентичны на всех веб-узлах.
Управление сессиями пользователей
В актив-активном режиме запросы пользователя могут попадать на разные серверы. Если сессии хранятся локально на сервере, пользователь будет «терять» авторизацию. Решения:
1. Sticky sessions (привязка сессии к серверу)
В конфигурации балансировщика добавьте:
upstream backend_cluster {
ip_hash; # Привязка по IP-адресу клиента
# или
hash $cookie_jsessionid; # Привязка по cookie сессии
server 192.168.1.21:80;
server 192.168.1.22:80;
}
Недостаток: нарушает равномерное распределение нагрузки и создает проблемы при выходе узла из строя.
2. Централизованное хранилище сессий
Лучшее решение - хранить сессии во внешнем хранилище:
- Redis - наиболее популярный выбор для сессий PHP, Node.js, Python.
- Memcached - проще, но без persistence.
- База данных - медленнее, но надежнее.
Пример настройки PHP для хранения сессий в Redis (в php.ini):
session.save_handler = redis
session.save_path = "tcp://192.168.1.30:6379?auth=your_password"
Мониторинг и обслуживание кластера
Проверка работоспособности
Регулярно контролируйте состояние кластера:
# Проверка работы Keepalived
sudo systemctl status keepalived
# Проверка назначения VIP
ip addr show | grep "192.168.1.100"
# Проверка работы Nginx на всех узлах
for host in 192.168.1.10 192.168.1.11; do
echo "=== $host ==="
ssh root@$host "systemctl status nginx --no-pager | head -10"
done
Мониторинг через Nginx stub_status
На каждом сервере Nginx включите модуль stub_status для сбора метрик:
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1; # Локальный доступ для скраппинга
allow 192.168.1.0/24; # Внутренняя сеть
deny all;
}
Метрики можно собирать в Prometheus с помощью nginx-prometheus-exporter и визуализировать в Grafana.
Плановое обслуживание
При актив-пассивной схеме:
- Переключите трафик на резервный сервер, временно снизив приоритет основного в Keepalived.
- Выполните обслуживание на основном сервере (обновление, перезагрузка).
- Верните приоритет и проверьте, что VIP вернулся.
При актив-активной схеме с балансировщиком:
- Исключите сервер из upstream-блока (поместите в комментарий или добавьте директиву down).
- Перезагрузите конфигурацию балансировщика:
nginx -s reload. - Обслуживайте сервер, пока трафик идет на другие узлы.
- Верните сервер в строй и перезагрузите конфигурацию балансировщика.
Готовые конфигурации для быстрого старта
Соберем минимальные рабочие конфигурации для обоих режимов.
Актив-пассивный кластер (архив для развертывания)
Создайте на основном сервере структуру:
/cluster-config/
├── keepalived-master.conf
├── keepalived-backup.conf
├── nginx-base.conf
└── sync-script.sh
Содержимое sync-script.sh (упрощенная версия):
#!/bin/bash
rsync -az /etc/nginx/ root@backup-server:/etc/nginx/
rsync -az /var/www/html/ root@backup-server:/var/www/html/
ssh root@backup-server "nginx -t && systemctl reload nginx"
Актив-активный кластер с балансировщиком
Базовая конфигурация балансировщика в /etc/nginx/sites-available/cluster:
upstream web_nodes {
zone backend 64k;
least_conn;
server 192.168.1.21:80;
server 192.168.1.22:80;
}
server {
listen 80;
location / {
proxy_pass http://web_nodes;
include proxy_params; # Стандартные proxy_set_header
}
}
Больше готовых шаблонов для различных сценариев, включая реверс-прокси для приложений на Node.js и Python, вы найдете в нашей коллекции «Готовые конфигурации Nginx».
Частые проблемы и их решение
VIP не переключается при сбое
Причина: Неправильно настроенная аутентификация VRRP, firewall блокирует протокол (IP 224.0.0.18, протокол 112).
Решение:
# Проверьте пароль в конфигурациях Keepalived на обоих серверах
# Откройте порт для VRRP в firewall
sudo ufw allow from 192.168.1.0/24 to any proto vrrp
# Или полностью отключите firewall для тестирования
sudo ufw disable # ВНИМАНИЕ: только в тестовой среде!
Рассинхронизация контента между узлами
Причина: Скрипт синхронизации не выполняется или завершается с ошибкой.
Решение:
# Проверьте cron-задачи
sudo crontab -l
# Проверьте логи синхронизации
sudo tail -f /var/log/syslog | grep CRON
# Выполните скрипт вручную и проверьте вывод
sudo /usr/local/bin/sync-nginx-config.sh
Сессии пользователей не сохраняются
Причина: В актив-активном режиме используется балансировка round-robin без sticky sessions или централизованного хранилища.
Решение: Внедрите Redis для хранения сессий или настройте ip_hash в upstream-блоке балансировщика.
Заключение и дальнейшие шаги
Вы разобрали две основные архитектуры отказоустойчивого кластера Nginx. Актив-пассивный режим с Keepalived - надежное решение для большинства проектов, которое можно внедрить за несколько часов. Актив-активная схема требует больше усилий, но обеспечивает максимальную производительность и масштабируемость.
Для production-среды дополнительно настройте:
- Мониторинг доступности и производительности (Prometheus + Grafana).
- Автоматическое оповещение о сбоях (Telegram, Slack, Email).
- Резервное копирование конфигураций и данных.
- Тестирование отказоустойчивости не реже раза в квартал.
Помните, что кластеризация - это лишь один компонент надежной инфраструктуры. Оптимизируйте производительность отдельных серверов с помощью кеширования Nginx и следуйте рекомендациям из гайда по настройке Nginx для production.
Интеграция с системами оркестрации, такими как Kubernetes, открывает возможности для автоматического масштабирования. Если ваш проект растет, изучите статью «Автомасштабирование веб-серверов на Nginx» для реализации динамического управления инфраструктурой.
Все приведенные инструкции проверены на практике и актуальны для 2026 года. Тестируйте конфигурации в staging-среде перед развертыванием в production. Для автоматизации развертывания и управления конфигурациями рассмотрите использование инструментов вроде Ansible, которые значительно упростят поддержку кластера.