Reference
Envoy LB Overview
Подробный обзор load balancing policy, outlier detection и locality-aware распределения трафика.
Балансировка трафика - это не только выбор алгоритма. Практическая архитектура включает точку принятия решения (L4/L7), политику health checks, правила graceful rollout и глобальную стратегию маршрутизации между регионами.
L4 vs L7: что выбрать
Про что это: про выбор уровня, на котором принимается решение о маршрутизации трафика: на transport-слое (L4) или на application-слое (L7).
Почему начинаем отсюда: это базовое архитектурное решение для всей остальной главы. От него зависят доступные правила, стоимость обработки запросов, observability и resilience-политики.
Для каких сценариев подходит: L4 чаще для stateful TCP-сервисов (DB/cache/broker), L7 - для HTTP/gRPC API и продуктовых сценариев с canary, header/path routing и policy control.
| Критерий | L4 | L7 |
|---|---|---|
| Уровень модели | L4 (TCP/UDP): маршрутизация по IP/port без анализа HTTP-данных. | L7 (HTTP/gRPC): маршрутизация по path/host/header/cookie. |
| Гибкость роутинга | Ниже: обычно hash/leastconn/round-robin без content-aware правил. | Выше: canary, A/B, sticky session, rate limiting, policy-based routing. |
| Производительность | Меньше CPU/latency overhead, хорошо для high-throughput TCP. | Больше логики и стоимость на запрос, зато точнее контроль трафика. |
| Типовые сценарии | БД, Redis, MQTT, бинарные протоколы, ultra-low-latency TCP path. | API Gateway, web-приложения, gRPC mesh, product traffic policies. |
Пример L4 (HAProxy, TCP)
Подходит для PostgreSQL/Redis и других stateful TCP-сервисов без HTTP-aware правил.
frontend ft_postgres
bind *:5432
mode tcp
default_backend bk_postgres
backend bk_postgres
mode tcp
balance leastconn
option tcp-check
default-server inter 2s fall 3 rise 2
server pg-1 10.0.1.11:5432 check
server pg-2 10.0.1.12:5432 checkПример L7 (Nginx, HTTP)
Подходит для API gateway, path-based routing и продвинутых policy на уровне запроса.
upstream api_pool {
least_conn;
server 10.0.2.11:8080 max_fails=3 fail_timeout=10s;
server 10.0.2.12:8080 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
location /api/ {
proxy_pass http://api_pool;
proxy_set_header X-Request-Id $request_id;
}
location /static/ {
proxy_pass http://static-service:8080;
}
}Health checks, grace period и connection draining
Про что это: про lifecycle backend-инстансов в балансировщике - когда их включать в пул, когда исключать и как безопасно выводить из ротации.
Зачем это нужно: даже идеальный алгоритм не спасет, если трафик продолжает идти на деградировавшие или еще не прогретые инстансы. Именно здесь снижаются 5xx/timeout всплески при deploy и failover.
Для каких сценариев подходит: autoscaling в K8s, rolling deploy, blue/green, long-lived соединения (WebSocket/gRPC streams), где резкий shutdown особенно болезнен.
Active health checks
Балансировщик сам опрашивает health endpoint/TCP handshake. Можно задать interval, timeout, rise/fall и исключать деградировавшие инстансы до hard-failure.
Passive health checks
Решение о деградации принимается по реальному трафику: 5xx, timeout, reset rate, high latency. Это полезно, когда endpoint формально жив, но по факту сервис уже не держит нагрузку.
Grace period / slow start
Новые поды сначала получают ограниченный процент трафика. Это снижает cold-start всплески и риск мгновенного выбивания из-за прогрева кэшей/JIT/pool-ов.
Connection draining
При выводе инстанса из пула прекращаем новые соединения, но даем завершить активные. Это снижает клиентские ошибки во время deploy/failover.
HAProxy: slow start + health policy
backend app
balance leastconn
option httpchk GET /healthz
http-check expect status 200
default-server inter 2s fall 3 rise 2 slowstart 30s
server app-1 10.0.3.11:8080 check
server app-2 10.0.3.12:8080 checkKubernetes: readiness + graceful shutdown
spec:
terminationGracePeriodSeconds: 40
containers:
- name: app
readinessProbe:
httpGet:
path: /readyz
port: 8080
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 20"]Global Server Load Balancing (GSLB)
Про что это: про балансировку между регионами и дата-центрами, а не только между инстансами внутри одного кластера.
Почему это важно: локальный LB не решает задачи global latency и regional outage. Без GSLB пользователи могут ходить в далекий регион или застревать на деградировавшей площадке.
Для каких сценариев подходит: multi-region продукты, глобальный B2C-трафик, требования по RTO/RPO, региональные compliance-ограничения и активный disaster recovery.
DNS-based GSLB
Авторитативный DNS выбирает регион по latency/geo/weight/health и возвращает ближайший endpoint.
Плюсы: Простая интеграция, хороший baseline для multi-region rollout.
Ограничения: Реакция ограничена TTL и DNS caching у клиентов/рекурсоров; может быть delayed failover.
Когда использовать: Web/API-трафик с приемлемым временем переключения в пределах секунд/десятков секунд.
Anycast
Один и тот же IP анонсируется из нескольких PoP/регионов; BGP направляет трафик в топологически ближайшую точку.
Плюсы: Быстрое глобальное распределение и высокая отказоустойчивость edge-сети.
Ограничения: Меньше L7-контроля на уровне DNS-ответа; нужна зрелая сеть, наблюдаемость и anti-flap практики.
Когда использовать: Edge/L4 ingress, DNS, DDoS-resilient front door, глобальные API с минимальным RTT.
Service mesh (Envoy, Istio) в Kubernetes
Про что это: про балансировку на уровне service-to-service трафика в микросервисной среде, где каждое внутреннее RPC - отдельное LB-решение.
Как этот блок связан с предыдущими: после L4/L7, health-policy и GSLB логично показать, как те же принципы масштабируются внутрь Kubernetes-кластера через sidecar-прокси и control plane.
Для каких сценариев подходит: десятки/сотни сервисов, единые traffic policy, canary/traffic splitting, mTLS и необходимость централизованно управлять retries, outlier detection и locality failover.
В mesh балансировка выполняется в sidecar-прокси (обычно Envoy). Istio control plane публикует endpoint-ы и policy, а dataplane применяет load balancing, retries, outlier detection и locality failover на каждый сервисный вызов.
Istio DestinationRule
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: payments
spec:
host: payments.default.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_REQUEST
outlierDetection:
consecutive5xxErrors: 5
interval: 5s
baseEjectionTime: 30sIstio locality failover
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: checkout-locality
spec:
host: checkout.default.svc.cluster.local
trafficPolicy:
localityLbSetting:
enabled: true
failover:
- from: us-east1
to: us-central1Рекомендации
- Начинайте с L7 для продуктового HTTP API, но оставляйте L4 путь для stateful TCP сервисов (DB/cache).
- Комбинируйте active и passive health checks: первый ловит hard-failure, второй - degraded performance.
- Используйте grace period + connection draining в каждом rollout, а не только в аварийных сценариях.
- Для глобальной схемы разделяйте роли: DNS GSLB для выбора региона, локальный LB/mesh - для балансировки внутри региона.
Частые ошибки
- Ограничиваться только round-robin без проверки профиля трафика, p99 и длины соединений.
- Считать readiness/liveness в Kubernetes полноценной заменой L7 passive health checks.
- Ставить длинный DNS TTL и ожидать быстрый failover в multi-region инцидентах.
- Игнорировать draining при деплое и получать всплеск 5xx из-за обрыва long-lived соединений.
