Прямой ответ
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 с тысячами правил.
Рекомендации:
- Используйте готовый контроллер вместо ручной настройки. Envoy Gateway, Contour и шлюзы на базе Istio транслируют объекты Kubernetes в xDS; ручное ведение конфигурации оправдано только для нестандартных случаев.
- Проверяйте фактическую конфигурацию после изменений. Расхождение между манифестом и применённой конфигурацией — частая причина «не работает, хотя настроено».
- Настраивайте outlier detection для всех внешних зависимостей. Исключение сбойного эндпоинта за секунды дешевле, чем обработка ошибок в каждом клиенте.
- Ограничьте число маршрутов на listener. Производительность Envoy снижается при тысячах правил; разделение по listener упрощает и диагностику.
- Логи доступа включайте выборочно. Полный лог каждого запроса в нагруженном кластере создаёт объём, сопоставимый с трафиком.
Практический сценарий: часть запросов возвращала 503 без причины в приложении
Контекст: через Envoy ingress примерно 5 % запросов к сервису оплаты завершались кодом 503. В логах приложения ошибок не было.
- Диагностика через admin.
curl localhost:9901/stats | grep paymentsпоказал ростupstream_rq_5xxи счётчикoutlier_detection.ejections_active, равный двум. - Проверка эндпоинтов.
/clustersпоказал, что два эндпоинта из шести исключены из балансировки из-за последовательных ошибок соединения. - Причина. Два пода сервиса находились в состоянии
Running, но не принимали соединения: процесс завершился, а контейнер не был перезапущен, поскольку проба готовности проверяла не тот порт. - Уточнение.
outlier_detectionсconsecutive_5xx: 5исключал эндпоинты, ноmax_ejection_percent: 50допускал исключение до половины — нагрузка легла на оставшиеся четыре пода, что увеличило их задержку. - Действия. (а) Исправили пробу готовности на фактический порт и путь; (б) добавили
liveness-пробу, чтобы зависший процесс перезапускался; (в) снизилиmax_ejection_percentдо 30 %, чтобы исключение не создавало лавинообразную нагрузку; (г) добавили алерт наejections_active > 0, поскольку до этого исключение эндпоинтов происходило незаметно; (д) включили лог доступа с кодом ответа и идентификатором запроса для входящего трафика. - Результат. 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) — ссылки в шапке.