Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Envoy: прокси и управление трафиком в Kubernetes

Envoy в Kubernetes: listeners, clusters и xDS

Envoy: модель listeners и clusters, динамическая конфигурация xDS, ретраи и outlier detection, admin-эндпоинты и место Envoy в service mesh.

Прямой ответ

Envoy — прокси уровня L7, написанный на C++ и работающий как отдельный процесс. В Kubernetes он встречается в трёх ролях: как точка входа кластера (ingress), как sidecar рядом с приложением и как шлюз между сервисами. Ключевое отличие от классических прокси — конфигурация может обновляться динамически, без перезагрузки процесса.

Модель Envoy строится из четырёх понятий:

Понятие Назначение
Listener Точка приёма соединений: адрес, порт, фильтры
Route Правило сопоставления запроса с кластером (путь, заголовки, метод)
Cluster Логическая группа целевых сервисов с параметрами подключения
Endpoint Конкретный адрес внутри кластера

Запрос проходит путь: listener → набор фильтров → маршрут → кластер → эндпоинт. На каждом шаге применяются таймауты, повторные попытки и ограничения.

Конфигурация бывает статической (файл YAML, изменения требуют перезагрузки) и динамической через xDS — семейство API, по которому управляющий сервер передаёт конфигурацию:

API Что передаёт
LDS Listeners
RDS Routes
CDS Clusters
EDS Endpoints
SDS Секреты и сертификаты

Именно xDS делает Envoy основой service mesh: control plane (например, Istio) транслирует объекты Kubernetes в конфигурацию прокси и передаёт её по xDS без перезапуска. Принцип sidecar-развёртывания разобран в статье про sidecar, а работа Istio — в статье про service mesh.

Отказоустойчивость настраивается на уровне кластера:

clusters:
  - name: payments
    connect_timeout: 1s
    lb_policy: LEAST_REQUEST
    outlier_detection:
      consecutive_5xx: 5
      interval: 10s
      base_ejection_time: 30s
      max_ejection_percent: 50
    circuit_breakers:
      thresholds:
        - max_connections: 100
          max_pending_requests: 50
          max_requests: 100

outlier_detection исключает из балансировки эндпоинты, отвечающие ошибками, — это пассивная проверка здоровья. circuit_breakers ограничивают число одновременных соединений и запросов, не давая каскадному сбою распространиться; подробнее о паттернах — в статье про retry и circuit breaker.

Практика: эксплуатация Envoy в кластере

1. Admin-эндпоинт — главный инструмент диагностики. Envoy отдаёт своё состояние по HTTP:

kubectl port-forward <envoy-pod> 9901:9901
curl -s localhost:9901/ready
curl -s localhost:9901/clusters | head -20
curl -s localhost:9901/config_dump | jq '.configs[0]'
curl -s localhost:9901/stats | grep upstream_rq_5xx

/config_dump показывает фактическую применённую конфигурацию — единственный надёжный способ понять, что именно получил прокси. /clusters отображает состояние эндпоинтов, включая исключённые outlier detection.

2. Admin-эндпоинт не должен быть доступен снаружи. Он позволяет менять уровень логирования и сбрасывать статистику, а также раскрывает топологию. Ограничьте его сетевой политикой.

3. Статистика по умолчанию избыточна. Envoy генерирует метрики на каждый кластер, маршрут и код ответа. В кластере с сотнями сервисов это приводит к взрыву числа временных рядов, поэтому часть метрик отключают.

4. Ретраи настраивайте осторожно. Повторные попытки на уровне прокси умножаются на ретраи приложения и клиента. Правило: ретраи должны быть в одном месте, а не в трёх.

5. Таймауты обязательны. Без явного connect_timeout и таймаута маршрута зависший целевой сервис удерживает соединения прокси и исчерпывает его ресурсы.

6. Envoy против nginx. Nginx проще для классического обратного прокси с редкими изменениями конфигурации; Envoy сильнее там, где нужна динамическая конфигурация, детальная телеметрия и L7-политики. Сравнение подходов — в статье про nginx.

7. Обновление конфигурации не прерывает соединения. Динамическое применение xDS не требует перезапуска, поэтому изменения маршрутов применяются на лету. Это принципиально для ingress с тысячами правил.

Рекомендации:

  1. Используйте готовый контроллер вместо ручной настройки. Envoy Gateway, Contour и шлюзы на базе Istio транслируют объекты Kubernetes в xDS; ручное ведение конфигурации оправдано только для нестандартных случаев.
  2. Проверяйте фактическую конфигурацию после изменений. Расхождение между манифестом и применённой конфигурацией — частая причина «не работает, хотя настроено».
  3. Настраивайте outlier detection для всех внешних зависимостей. Исключение сбойного эндпоинта за секунды дешевле, чем обработка ошибок в каждом клиенте.
  4. Ограничьте число маршрутов на listener. Производительность Envoy снижается при тысячах правил; разделение по listener упрощает и диагностику.
  5. Логи доступа включайте выборочно. Полный лог каждого запроса в нагруженном кластере создаёт объём, сопоставимый с трафиком.

Практический сценарий: часть запросов возвращала 503 без причины в приложении

Контекст: через Envoy ingress примерно 5 % запросов к сервису оплаты завершались кодом 503. В логах приложения ошибок не было.

  1. Диагностика через admin. curl localhost:9901/stats | grep payments показал рост upstream_rq_5xx и счётчик outlier_detection.ejections_active, равный двум.
  2. Проверка эндпоинтов. /clusters показал, что два эндпоинта из шести исключены из балансировки из-за последовательных ошибок соединения.
  3. Причина. Два пода сервиса находились в состоянии Running, но не принимали соединения: процесс завершился, а контейнер не был перезапущен, поскольку проба готовности проверяла не тот порт.
  4. Уточнение. outlier_detection с consecutive_5xx: 5 исключал эндпоинты, но max_ejection_percent: 50 допускал исключение до половины — нагрузка легла на оставшиеся четыре пода, что увеличило их задержку.
  5. Действия. (а) Исправили пробу готовности на фактический порт и путь; (б) добавили liveness-пробу, чтобы зависший процесс перезапускался; (в) снизили max_ejection_percent до 30 %, чтобы исключение не создавало лавинообразную нагрузку; (г) добавили алерт на ejections_active > 0, поскольку до этого исключение эндпоинтов происходило незаметно; (д) включили лог доступа с кодом ответа и идентификатором запроса для входящего трафика.
  6. Результат. 503 исчезли; проблема с подом теперь обнаруживается алертом на исключение эндпоинтов, а не жалобами пользователей.

Вывод: 503 от прокси часто означает проблему ниже по стеку — недоступный эндпоинт, а не ошибку маршрутизации. Admin-эндпоинт Envoy показывает состояние балансировки напрямую, и это быстрее, чем поиск по логам приложения.

FAQ

Нужен ли Envoy, если уже есть ingress на nginx? Не обязательно. Envoy оправдан, когда нужны динамическая конфигурация, детальная телеметрия или L7-политики вроде повторных попыток по коду ответа. Для простого терминации TLS и маршрутизации по путям достаточно nginx.

Как Envoy получает конфигурацию в Kubernetes? Через control plane, который следит за объектами кластера и передаёт конфигурацию по xDS. Сам Envoy не читает Kubernetes API — это задача управляющего компонента.

Что такое SDS и зачем он нужен? Secret Discovery Service передаёт сертификаты и ключи без перезапуска прокси и без записи на диск. Это позволяет обновлять TLS-сертификаты на лету.

Можно ли запустить Envoy без service mesh? Да. Envoy работает как самостоятельный прокси со статической конфигурацией — в качестве ingress-контроллера, шлюза или отладочного компонента. Mesh добавляет автоматическое управление конфигурацией и mTLS.

Источники: Envoy docs (what is Envoy, xDS protocol, admin interface) — ссылки в шапке.