Кластеры с балансировкой нагрузки [361.2]

Рейтинг: 67.6% · 8 голосов
Специализация LPIC-3 306 (v3.0): кластеры HA (Pacemaker/Corosync), балансировка (LVS, keepalived, HAProxy), DRBD, кластерные и распределённые ФС (GFS2, OCFS2, GlusterFS, Ceph), iSCSI/multipath, advanced RAID/LVM.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Кластеры с балансировкой нагрузки [361.2]

Сообщение Sergey_Sysadmin »

Оглавление курса (14)
  1. Введение в LPIC-3 306: высокая доступность и хранилища
  2. Концепции и теория высокой доступности [361.1]
  3. Кластеры с балансировкой нагрузки [361.2] (вы здесь)
  4. Failover-кластеры: Corosync и Pacemaker [361.3, часть 1]
  5. Pacemaker: ресурсы, ограничения, fencing [361.3, часть 2]
  6. DRBD [362.1]
  7. Доступ к кластерному хранилищу [362.2]
  8. Кластерные файловые системы [362.3]
  9. Распределённое хранилище GlusterFS [363.1]
  10. Ceph: архитектура [363.2, часть 1]
  11. Ceph: использование и эксплуатация [363.2, часть 2]
  12. Отказоустойчивость узла: железо и сервисы [364.1]
  13. Продвинутый RAID
  14. Продвинутый LVM и сетевая отказоустойчивость [364.3 + 364.4]
Урок 2. Кластеры с балансировкой нагрузки [361.2]

Задача администратора тут двойная: размазать клиентские запросы по пулу одинаковых серверов и сделать так, чтобы падение одного бэкенда или самого балансировщика никто не заметил. В этом уроке разберём два мира. Первый - ядерный балансировщик LVS/IPVS на четвёртом уровне (он не вникает в содержимое пакета, только в адреса и порты). Второй - HAProxy, который умеет и L4, и L7 (читает HTTP, маршрутизирует по URL и заголовкам). Между ними - keepalived с протоколом VRRP, который делает сам балансировщик отказоустойчивым через плавающий IP.

Изображение

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

IPVS живёт внутри ядра Linux как часть netfilter. Вы описываете виртуальный сервис - пару "виртуальный IP плюс порт" (VIP) - и привязываете к нему набор реальных серверов. Дальше ядро само раскидывает соединения, держа таблицу состояний, чтобы пакеты одного TCP-потока шли на один и тот же бэкенд. Управляется это таблицей через утилиту ipvsadm, конфигурация чисто in-kernel, без своего демона.

Ключевое в LVS - три режима пересылки. NAT (masq): балансировщик подменяет адрес назначения, и ответный трафик обязан идти обратно через него, поэтому он становится шлюзом для бэкендов и узким горлом по пропускной способности. DR (direct routing): балансировщик меняет только MAC-адрес кадра, пакет уходит на реальный сервер в том же L2-сегменте, а ответ идёт клиенту НАПРЯМУЮ, минуя балансировщик. Это самый быстрый режим, но требует, чтобы VIP висел на loopback каждого бэкенда и тот не отвечал на ARP по нему. TUN (туннелирование): пакет заворачивается в IPIP, поэтому бэкенды могут стоять в другой подсети или даже другом ЦОДе, ответ тоже идёт напрямую клиенту.

Алгоритмы распределения: rr (по кругу), wrr (по кругу с весами), lc (наименьшее число соединений), wlc (то же с весами - дефолт на практике), а также sh (хэш по source IP для липкости без таблицы) и mh (maglev-хэш, консистентный, появился в современных ядрах). Сам IPVS не проверяет здоровье бэкендов - для этого нужен внешний демон: keepalived или ldirectord. Они опрашивают реальные серверы и вынимают мёртвый узел из таблицы IPVS, а потом возвращают.

keepalived делает две вещи. Во-первых, VRRP: несколько балансировщиков выбирают MASTER по приоритету, и тот держит плавающий VIP. Если MASTER молчит (нет VRRP-advert в течение трёх интервалов), BACKUP с наибольшим приоритетом забирает VIP за секунды. Во-вторых, healthcheck-модуль программирует IPVS и следит за бэкендами (TCP_CHECK, HTTP_GET, MISC_CHECK). ldirectord - более старый перловый демон только для второй задачи (мониторинг + правка IPVS), в 2026 это легаси: на новых стендах берут keepalived, ldirectord держат только для совместимости со старыми кластерами Pacemaker.

HAProxy работает в user space и принимает соединение на себя целиком. Вы описываете frontend (где слушать) и backend (куда слать), а между ними - правила. На L7 он терминирует TCP, читает HTTP и может балансировать по пути, хосту, куке, делать sticky-сессии, повторять запросы, вставлять заголовки. Алгоритмы: roundrobin, leastconn, source (хэш IP), uri, hdr. Health-checks активные (option httpchk) и пассивные (observe). Встроенная страница статистики показывает состояние каждого сервера в реальном времени.

L4 против L7 коротко: L4 (IPVS, режим tcp в HAProxy) быстрый, дёшев по CPU, но слеп к содержимому - не различит /api от /static. L7 видит запрос целиком, умна маршрутизация и TLS-терминация, но платит CPU за разбор каждого запроса.

Команды и примеры

Установка. Debian 13 / Ubuntu 24.04:

Код: Выделить всё

apt install ipvsadm keepalived haproxy
RHEL 10 / Fedora 41+:

Код: Выделить всё

dnf install ipvsadm keepalived haproxy
Ручная настройка IPVS в режиме DR, алгоритм wlc:

Код: Выделить всё

ipvsadm -A -t 203.0.113.10:80 -s wlc
ipvsadm -a -t 203.0.113.10:80 -r 10.0.0.21:80 -g -w 3
ipvsadm -a -t 203.0.113.10:80 -r 10.0.0.22:80 -g -w 1
ipvsadm -L -n --stats
Тут -g это gatewaying (DR), для NAT было бы -m (masq), для туннеля -i (ipip). Сохранение и загрузка правил:

Код: Выделить всё

ipvsadm-save -n > /etc/ipvsadm.rules
ipvsadm-restore < /etc/ipvsadm.rules
На бэкендах для DR гасим ARP по VIP (через sysctl, актуальный способ вместо старых ARP-фокусов):

Код: Выделить всё

ip addr add 203.0.113.10/32 dev lo
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
keepalived с VRRP плюс виртуальным сервисом (/etc/keepalived/keepalived.conf):

Код: Выделить всё

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication { auth_type PASS; auth_pass s3cret }
    virtual_ipaddress { 203.0.113.10/24 dev eth0 }
}
virtual_server 203.0.113.10 80 {
    delay_loop 5
    lb_algo wlc
    lb_kind DR
    protocol TCP
    real_server 10.0.0.21 80 {
        weight 3
        HTTP_GET { url { path /health; status_code 200 } connect_timeout 2 }
    }
    real_server 10.0.0.22 80 {
        weight 1
        TCP_CHECK { connect_timeout 2 }
    }
}
На BACKUP-узле то же самое, но state BACKUP и priority меньше (например 100). Проверка:

Код: Выделить всё

systemctl enable --now keepalived
journalctl -u keepalived -f
ip -br addr show eth0
HAProxy L7 с health-check и статистикой (/etc/haproxy/haproxy.cfg):

Код: Выделить всё

frontend web
    bind 203.0.113.10:80
    default_backend app

backend app
    balance leastconn
    option httpchk GET /health
    http-check expect status 200
    server a 10.0.0.21:80 check weight 3
    server b 10.0.0.22:80 check weight 1 backup

listen stats
    bind 127.0.0.1:9000
    stats enable
    stats uri /haproxy?stats
    stats refresh 5s
Проверка конфига и перезапуск без потери соединений:

Код: Выделить всё

haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl reload haproxy
Частые грабли
  • DR-режим не работает, пока на бэкендах не погашен ARP по VIP - иначе они начинают отвечать на ARP-запросы и крадут трафик у балансировщика.
  • В NAT-режиме забыли назначить балансировщик шлюзом по умолчанию для бэкендов - ответный трафик уходит мимо, соединения зависают.
  • Два MASTER одновременно (split brain): VRRP-адверты режутся файрволом или несовпадает virtual_router_id - оба узла поднимают VIP, в сети конфликт. Проверяйте, что nftables/firewalld пропускает протокол 112 (VRRP) и multicast 224.0.0.18.
  • Сам IPVS не знает, жив ли бэкенд. Без keepalived или ldirectord мёртвый сервер остаётся в таблице, и часть запросов улетает в никуда.
  • HAProxy без явного option httpchk делает только TCP-connect: процесс слушает порт, но приложение отдаёт 500 - балансировщик этого не заметит.
  • Путаница restart и reload у HAProxy: restart рвёт все соединения, нужен reload (или master-worker режим) для бесшовной выкатки.
  • Модуль ip_vs не загружен в ядре - ipvsadm выдаёт пустоту. Подгрузите modprobe ip_vs и нужный алгоритм (ip_vs_wlc).
Мини-лаба
  • Поднимите три ВМ: один балансировщик (LB1) и два бэкенда с nginx, отдающим разный текст на /health и на /.
  • На LB1 настройте IPVS в режиме NAT через ipvsadm, бэкенды переведите шлюзом на LB1. Проверьте балансировку через curl в цикле.
  • Снесите ручные правила и поднимите keepalived с тем же virtual_server, но healthcheck HTTP_GET на /health. Погасите nginx на одном бэкенде и убедитесь, что keepalived вынул его из ipvsadm -L -n.
  • Добавьте LB2 как BACKUP с меньшим приоритетом. Остановите keepalived на LB1 и засеките, за сколько VIP переедет на LB2 (смотрите ip addr и journalctl).
  • Отдельно поднимите HAProxy на L7: frontend на 80 порту, backend с option httpchk, один сервер пометьте backup.
  • Откройте страницу статистики и понаблюдайте, как сервер переходит в DOWN при остановке приложения и обратно в UP.
  • Сравните в выводе ipvsadm и в статистике HAProxy, чем отличается распределение при leastconn и при roundrobin под нагрузкой ab или wrk.
Контрольные вопросы
  • Чем DR-режим LVS отличается от NAT по пути ответного трафика и какие требования к сети накладывает каждый?
  • Какой компонент в связке LVS отвечает за проверку здоровья реальных серверов и почему сам IPVS этого не делает?
  • Как VRRP в keepalived определяет, что MASTER упал, и за счёт чего происходит переезд плавающего IP?
  • В каких ситуациях L7-балансировка HAProxy оправдывает дополнительную нагрузку на CPU по сравнению с L4?
  • Чем грозит и из-за чего возникает ситуация split brain при работе двух балансировщиков на VRRP?
  • Чем отличается алгоритм sh (source hashing) в IPVS от wlc и когда выбирают первый?
👍1 ❤️3 🔥1 😄 🤔
Аватара пользователя
ynitaz
Сообщения: 1
Зарегистрирован: 13 май 2026, 10:19

Re: Кластеры с балансировкой нагрузки [361.2]

Сообщение ynitaz »

А если бэкенды в разных подсетях, DR ведь не взлетит из-за L2? Тогда только TUN остаётся или NAT через шлюз?
👍 ❤️1 🔥 😄 🤔2
Аватара пользователя
rustlord
Сообщения: 1
Зарегистрирован: 14 май 2026, 01:39

Re: Кластеры с балансировкой нагрузки [361.2]

Сообщение rustlord »

Поймал split brain ровно как тут написано - firewalld резал VRRP. Открыл протокол 112 и multicast 224.0.0.18, и BACKUP перестал поднимать второй MASTER.
👍1 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Концепции и теория высокой доступности [361.1]
Следующая глава →
Failover-кластеры: Corosync и Pacemaker [361.3, часть 1]

Все главы курса «LPIC-3 306: высокая доступность и хранилища»

Поделиться темой: ✈ Telegram VK
  • Похожие темы

Вернуться в «LPIC-3 306: высокая доступность и хранилища»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость