Выберите продукт

IPVS на VDS: LVS/DR/NAT, keepalived и производительность L4

Практический гид по IPVS: выбор NAT или DR, конфигурация keepalived и VRRP, алгоритмы, персистентность и проверки TCP/HTTP. Разберём ARP и rp_filter для DR, тюнинг conntrack, сетевых очередей и offload‑ов, IRQ, плюс готовые конфиги.
IPVS на VDS: LVS/DR/NAT, keepalived и производительность L4

IPVS (Linux Virtual Server) — ядровой L4 балансировщик, который распределяет TCP/UDP‑трафик по пулу бэкендов с минимальными накладными расходами. Он прост, очень быстрый, стабилен и идеален, когда нужен максимум пропускной способности и низкая латентность без L7‑логики. На VDS это один из самых предсказуемых способов поднять отказоустойчивый фронт. Ниже — рабочие схемы и проверенные настройки.

Когда выбирать L4 и IPVS

Если вам нужен только транспортный проксирование/балансировка (TCP/UDP) без анализа HTTP/SMTP/прочих протоколов, IPVS даёт максимальную производительность. Он работает в ядре, не парсит заголовки и не держит сложные контексты приложения. Это снижает задержки и экономит CPU. Типичные кейсы: HTTP(S) фронт без необходимости модифицировать заголовки, базы данных (TCP), бинарные протоколы, gRPC на TCP, DNS (UDP/TCP), RADIUS и т.п.

IPVS — не замена L7‑прокси. Если вам нужны переписывание заголовков, сложные правила маршрутизации, канареечные релизы по cookie/URI — берите L7 (например, на фронте), а L4 используйте как быстрый транспортный слой под ним.

Если нужен альтернативный вариант на базе Nginx stream, посмотрите материал про балансировку TCP/UDP в Nginx stream: разбор stream‑балансировки.

Режимы LVS: NAT, DR и TUN

IPVS поддерживает три способа доставки пакетов к бэкендам (real servers):

  • NAT — директор (LB) делает DNAT запросам и SNAT ответам. Весь трафик (вход/выход) проходит через LB.
  • DR (Direct Routing) — LB меняет только MAC назначения и отправляет пакет в L2 к бэкенду без изменения IP. Ответ уходит напрямую от бэкенда к клиенту, минуя LB.
  • TUN — инкапсуляция IP‑в‑IP (IPIP). Применяется реже, полезно, когда между LB и бэкендами есть L3‑сегменты без единого L2.

Для VDS‑сценариев в пределах одного L2 (или одного провайдера) чаще всего актуальны NAT и DR. TUN удобен при сложной маршрутизации между площадками, но вносит инкапсуляционные накладные расходы и вопросы с MTU.

Потоки трафика в режимах NAT и DR для IPVS

Что выбрать: NAT или DR

Быстрый выбор:

  • Нужна простота, все пакеты и ответы должны идти через балансировщик — выбирайте NAT. Проще в отладке и безопасности, но LB становится узким местом по трафику.
  • Нужен максимум пропускной способности, ответы должны идти напрямую от RS к клиенту — выбирайте DR. Минимум нагрузки на LB, но есть нюансы с ARP и L2‑топологией.

По опыту, DR даёт существенно более высокую пиковую пропускную способность (особенно на больших ответах), так как обратный трафик не проходит через LB. В NAT режиме директор обрабатывает и запросы, и ответы, быстрее упираясь в CPU/IRQ/сетевую карту.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Схемы потоков пакетов

NAT

Клиент обращается к VIP на LB. IPVS выполняет DNAT к одному из бэкендов. Ответы бэкенд отправляет на LB (благодаря SNAT), а директор возвращает их клиенту. Контроль полностью у LB: удобно для ограничения, аудита, метрик и TLS‑терминации на внешнем уровне при необходимости. Сертификаты удобно хранить и обновлять через SSL-сертификаты.

DR

Клиент обращается к VIP. LB на L2 меняет MAC назначения на MAC бэкенда и отправляет пакет. Бэкенд видит VIP как локальный адрес (на интерфейсе loopback) и отвечает клиенту напрямую. LB задействуется только на входящих пакетах. Нужно правильно погасить ARP‑ответы на VIP со стороны бэкендов, иначе случится ARP‑флит и трафик будет идти мимо LB.

Алгоритмы балансировки и персистентность

IPVS поддерживает множество алгоритмов:

  • rr — классический round‑robin.
  • wrr — взвешенный rr.
  • lc, wlc — (взвешенная) наименьшая загрузка (по количеству соединений).
  • sh — source hashing (по IP клиента).
  • mh — консистентный хеш по 5‑tuple/адресам для стабильного распределения.
  • sed, nq — алгоритмы с минимизацией задержек/очередей.

Для stateful приложений без разделяемых сессий часто выбирают персистентность: IPVS «приклеивает» клиента к бэкенду на заданное время. Это задаётся параметрами персистентности, а также алгоритмами sh/mh. Если у вас CDN/прокси спереди, продумайте, что будет являться источником персистентности: реальный src IP клиента или адрес прокси/CDN. В DR режиме шифрование и terminations обычно не на L4, поэтому персистентность чаще строят именно по IP.

Keepalived: VRRP, виртуальные серверы и проверки

Keepalived — удобный менеджер для IPVS и VRRP. Он поднимает VIP, обеспечивает failover между двумя LB, управляет таблицей IPVS и делает health‑checks бэкендов. Конфигурация состоит из двух частей: VRRP‑блоки (виртуальные маршрутизаторы) и virtual_server‑блоки (настройка IPVS).

VRRP даёт быстрый перехват VIP вторым балансировщиком при отказе первого. При правильной настройке общий даунтайм — считанные сотни миллисекунд.

Подготовка системы

Установите инструменты и модули ядра:

apt update
apt install -y keepalived ipvsadm

# Загрузить модули
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh

# Зафиксировать загрузку модулей на старте
printf "%s\n" ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh > /etc/modules-load.d/ipvs.conf

Общие sysctl‑настройки для L4 LB (безопасные значения по умолчанию могут отличаться в разных дистрибутивах, проверьте):

# Включить маршрутизацию (для NAT и DR)
sysctl -w net.ipv4.ip_forward=1

# Увеличить очереди и минимизировать потери на pps
sysctl -w net.core.somaxconn=1024
sysctl -w net.core.netdev_max_backlog=5000

# TCP параметры для лучшей производительности и устойчивости
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
sysctl -w net.ipv4.tcp_syncookies=1

# Коннтрек для NAT (см. раздел NAT)
# Примерно: sysctl -w net.netfilter.nf_conntrack_max=262144

NAT: быстрая и понятная схема

В NAT режиме бэкенды не должны знать о VIP, никакой особой настройки на них не требуется. Директор делает DNAT входящего трафика и SNAT исходящего ответа. Это упрощает безопасность (весь трафик проходит через LB), но увеличивает нагрузку на LB.

Пример keepalived для NAT

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass strongpass
    }
    virtual_ipaddress {
        203.0.113.10/32 dev eth0
    }
}

virtual_server 203.0.113.10 80 {
    delay_loop 2
    lb_algo wlc
    lb_kind NAT
    protocol TCP

    persistence_timeout 300

    real_server 10.0.0.11 80 {
        weight 2
        TCP_CHECK {
            connect_timeout 3
            connect_port 80
            nb_get_retry 2
            delay_before_retry 2
        }
    }

    real_server 10.0.0.12 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            connect_port 80
            nb_get_retry 2
            delay_before_retry 2
        }
    }
}

Второй балансировщик получает такой же конфиг, но со state BACKUP и меньшим priority. VIP будет перемещаться между ними по VRRP.

Особенности NAT

  • Нужен трекинг соединений. Если потоков много, увеличьте nf_conntrack_max, выделите память под таблицу и мониторьте conntrack -S.
  • Ставьте адекватные таймауты в IPVS для TCP/UDP, иначе таблица коннтрека может разрастаться.
  • Для hairpin‑трафика проверьте политику маршрутизации; при необходимости добавьте правила, чтобы возвращаемый SNAT шёл обратно через LB.

DR: максимум пропускной способности

В DR LB обрабатывает только входящие пакеты, перенаправляя их в L2 на выбранный бэкенд. Ответы идут напрямую от RS к клиенту. Основная тонкость — ARP‑поведение: бэкенды не должны отвечать на ARP запросы по VIP, иначе трафик обойдёт LB.

Настройка бэкендов для DR

На каждом бэкенде добавьте VIP на loopback и настройте ARP:

# Добавляем VIP на lo (маска /32, чтобы не было маршрутизации в подсети)
ip addr add 203.0.113.10/32 dev lo
ip link set lo up

# Гасим ARP для VIP
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
sysctl -w net.ipv4.conf.lo.arp_ignore=1
sysctl -w net.ipv4.conf.lo.arp_announce=2

# rp_filter может ломать DR, отключаем строгость
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.default.rp_filter=0

Эти значения зафиксируйте в /etc/sysctl.d/*.conf, чтобы переживали перезагрузки.

Пример keepalived для DR

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass strongpass
    }
    virtual_ipaddress {
        203.0.113.10/32 dev eth0
    }
}

virtual_server 203.0.113.10 443 {
    delay_loop 1
    lb_algo sh
    lb_kind DR
    protocol TCP

    persistence_timeout 600

    real_server 10.0.0.21 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            connect_port 443
            nb_get_retry 2
            delay_before_retry 2
        }
    }

    real_server 10.0.0.22 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            connect_port 443
            nb_get_retry 2
            delay_before_retry 2
        }
    }
}

Алгоритм sh (source hashing) помогает держать стабильное соответствие клиент → бэкенд без sticky‑таблиц. Если важен равномерный вес с стабильностью, рассмотрите mh.

DR и сеть

DR требует, чтобы LB и бэкенды находились в общем L2 (или сквозной L2‑доставке). Если между ними L3‑роутер, пакет с заменённым MAC может не дойти. В таких случаях практичнее NAT или TUN. Проверьте MTU на всех участках, чтобы исключить фрагментацию.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Health‑checks: TCP против HTTP

Keepalived умеет как TCP‑проверки (простая попытка подключения к порту), так и HTTP(S)‑проверки (запрос URI с проверкой кода). Для L4 обычно достаточно TCP_CHECK: он быстрый и мало затратный. Если сервис сложный и «успешный TCP» ещё не гарантирует работоспособность (например, нужен доступ к БД), включите HTTP_GET с проверкой кода/строки.

virtual_server 203.0.113.10 80 {
    delay_loop 2
    lb_algo wrr
    lb_kind NAT
    protocol TCP

    real_server 10.0.0.11 80 {
        weight 2
        HTTP_GET {
            url {
                path "/health"
                digest 9b74c9897bac770ffc029102a200c5de
            }
            connect_timeout 3
            nb_get_retry 2
            delay_before_retry 2
        }
    }
}

Для внешнего контроля живости удобно подключить blackbox‑пробинг. См. практику: проверки Prometheus Blackbox (HTTP/TCP/ICMP).

Производительность L4: практическая оптимизация

Сетевые очереди и IRQ

Чаще всего упираются в PPS/IRQ и NUMA, а не в «сырые» мегабайты. На виртуальных серверах важно правильно распределить IRQ по vCPU и включить RSS/RPS на драйвере:

# Посмотреть IRQ и распределить по CPU
cat /proc/interrupts
# Примерно: установить smp_affinity для очередей NIC
# echo <mask> > /proc/irq/<IRQ>/smp_affinity

# RPS: количество очередей RX и маппинг CPU
# Настраивается через /sys/class/net/eth0/queues/rx-*/rps_cpus

Следите, чтобы vCPU балансировались равномерно, а NUMA‑пересечения были минимальными (для крупных инстансов). Виртуализация может скрывать детали, но общие принципы работают.

Тюнинг сетевых IRQ, RSS и очередей на Linux

Offload‑ы

GRO/LRO, TSO/GSO снижают нагрузку на CPU при больших потоках. Для L4 LB это обычно плюс, но тестируйте: иногда GRO мешает точному измерению PPS. Проверяйте текущие параметры через ethtool -k и меняйте точечно.

Таймауты IPVS и conntrack

Для NAT‑сценариев увеличьте лимиты nf_conntrack пропорционально нагрузке, а также выставьте адекватные таймауты. Для коротких HTTP‑запросов таймауты держите ниже, чтобы быстрее очищать состояние. Для длительных TCP — выше, чтобы не терять соединения.

IPVS имеет собственные параметры в /proc/sys/net/ipv4/vs (например, conn_reuse_mode, expire_nodest_conn, expire_quiescent_template) — изучите их и подберите под профиль нагрузки. Практически полезно включить повторное использование шаблонов соединений при агрессивном коротком трафике.

Очереди сокетов

Повышение net.core.somaxconn и net.core.netdev_max_backlog часто уменьшает потери на пиках. Для TCP‑сервисов также посмотрите на net.ipv4.tcp_max_syn_backlog и tcp_synack_retries. Не забывайте, что увеличение очередей без достаточного CPU даёт рост задержек.

Алгоритмы и персистентность

Если у вас сильно неоднородные бэкенды, используйте взвешенные алгоритмы (wrr, wlc) и динамически меняйте веса. Для sticky‑поведения выбирайте persistence_timeout и sh/mh. Старайтесь, чтобы таймаут персистентности был соизмерим с жизненным циклом сессии приложения; слишком длинные значения мешают перераспределению нагрузки.

Наблюдаемость и отладка

Основные инструменты:

  • ipvsadm -Ln --stats --rate — состояние виртуальных серверов и бэкендов, текущие скорости.
  • watch -n1 cat /proc/net/ip_vs_stats — агрегированные счётчики.
  • conntrack -S — состояние коннтрека (NAT).
  • ss -s, ss -tn 'sport = :80' — быстрый обзор сокетов.
  • Логи keepalived — причины перевыборов VRRP, падения бэкендов.

При DR проверяйте ARP: ip neigh на LB и RS, отсутствие ARP‑ответов на VIP со стороны RS. При NAT смотрите, не упёрлись ли в nf_conntrack_max и скорость GC.

Деплой без даунтайма и дренаж трафика

Чтобы безопасно увести бэкенд на обновление, снизьте его weight до нуля или используйте механизмы quiesce, дождитесь падения активных соединений и только затем останавливайте сервис. В keepalived можно временно понизить вес или перевести бэкенд в DOWN через health‑check. Для приложений с долгими соединениями (веб‑сокеты, стриминг) планируйте «мягкие» рестарты с достаточным временем дренажа.

Типичные проблемы и решения

  • Не работает DR: проверьте arp_ignore/arp_announce на RS, rp_filter, L2‑доставку, MTU, наличие VIP на loopback с маской /32.
  • Высокая нагрузка на LB в NAT: включите/проверьте offload‑ы, увеличьте лимиты conntrack, распределите IRQ, подумайте о переходе на DR.
  • Потери пакетов на пиках: увеличьте netdev_max_backlog, somaxconn, проверьте очереди NIC и RSS/RPS, пингуйте IRQ по CPU.
  • Неровномерный трафик при sticky: пересмотрите алгоритм (например, mh) и таймаут персистентности.
  • Флап VRRP: проверьте стабильность сети, advert_int, приоритеты, NTP/время, загрузку CPU (watchdog keepalived не должен голодать).

Методика измерения производительности

Чтобы получить репрезентативные цифры, тестируйте с нескольких клиентов (генераторов нагрузки) против LB, избегайте ситуации «один клиент — один узкий TCP‑поток». Для HTTP используйте утилиты наподобие wrk или hey с достаточным количеством соединений и потоков. Для TCP‑уровня подойдут tcpkali, hping3 в соответствующих режимах. Пингуйте CPU, IRQ, сетевые очереди, фиксируйте PPS и latency‑квантили. Сравнивайте NAT и DR на одинаковых профилях нагрузки.

Контрольная карта настроек

Минимальный набор, который почти всегда нужен:

  • Включить ip_forward и загрузить модули IPVS.
  • Настроить keepalived: VRRP + virtual_server с алгоритмом и проверками.
  • Для NAT — поднять nf_conntrack_max, следить за GC и таймаутами.
  • Для DR — VIP на loopback RS, arp_ignore=1, arp_announce=2, rp_filter=0.
  • Оптимизировать IRQ/RSS/RPS, проверить offload‑ы.
  • Подобрать алгоритм (wlc/wrr/sh/mh) и персистентность.
  • Наладить наблюдаемость: ipvsadm stats/rate, conntrack, логи keepalived.

Итоги

IPVS остаётся одним из самых эффективных способов L4‑балансировки. В связке с keepalived вы получаете простой, предсказуемый и очень быстрый кластер с автоматическим failover. Выбор между NAT и DR — это компромисс между простотой и максимальной пропускной способностью. Правильные sysctl, аккуратная работа с ARP и разумные health‑checks обеспечат стабильность под нагрузкой. Настройте наблюдаемость и отработайте дренаж — и у вас будет быстрый и надёжный L4‑фронт, который масштабируется вместе с приложением.

Поделиться статьей

Вам будет интересно

LVM snapshot и I/O: почему растёт задержка и как делать backup без сюрпризов OpenAI Статья написана AI (GPT 5)

LVM snapshot и I/O: почему растёт задержка и как делать backup без сюрпризов

LVM snapshot удобен для горячего backup, но почти всегда увеличивает нагрузку на диск. Объясняю, откуда берётся рост I/O latency, ...
PostgreSQL SSL/TLS: sslmode require и verify-full, root.crt, SNI и типовые ошибки проверки сертификата OpenAI Статья написана AI (GPT 5)

PostgreSQL SSL/TLS: sslmode require и verify-full, root.crt, SNI и типовые ошибки проверки сертификата

Пошагово настраиваем SSL/TLS в PostgreSQL и клиентах: разница между sslmode=require и verify-full, где хранится root.crt, как устр ...
DNS TTL: как работает время жизни записей, кэш резолверов и «распространение» изменений OpenAI Статья написана AI (GPT 5)

DNS TTL: как работает время жизни записей, кэш резолверов и «распространение» изменений

TTL в DNS — не «время распространения», а срок хранения ответа в кэше. Разберём, где живут кэши резолверов, ОС и приложений, почем ...