История: как я потратил 6 часов на одну annotation
Это было летом 2024 года. Пятница, 18:30. У меня в production упал canary deployment.
Задача казалась простой: направить 10% трафика на новую версию API, остальное — на старую. Тестирование перед полным раскатом. Стандартная практика.
Реальность оказалась жестокой.
Я использовал Nginx Ingress. Нашёл в документации раздел про canary deployments через annotations. Скопировал пример:
# ❌ То, что я думал будет работать
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
rules:
- host: api.company.com
http:
paths:
- path: /v2
backend:
service:
name: api-v2
port:
number: 8080Применил. Проверил. 100% трафика идёт на новую версию.
"Странно, — подумал я, — наверное опечатка в weight". Поменял на 90. Перезапустил. Всё ещё 100% на v2.
Следующие 4 часа я:
- Перечитывал документацию 7 раз
- Гуглил "nginx ingress canary not working" (53 результата, ни один не помогал)
- Проверял версию Nginx Ingress Controller (оказалось, надо 0.22+, у меня 0.21)
- Обновлял контроллер (сломал ещё 2 Ingress-ресурса в процессе)
- Обнаружил, что для canary нужен отдельный Ingress ресурс с тем же host, но другим именем
- Понял, что я неправильно указал path matching (нужен regex, а не prefix)
В 23:00 я наконец заставил это работать. 47 строк YAML + 12 annotations. Половину смысла я не понимал.
А утром в понедельник: "Слушай, давайте ещё добавим JWT-авторизацию на этот endpoint?"
Я понял, что мне конец.
Триумф: 15 строк вместо 47, и всё понятно
Через месяц я узнал про Envoy Gateway. Скептически отнёсся: "Ещё один инструмент, который надо учить".
Но решил попробовать на dev-кластере.
Тот же canary deployment на Envoy Gateway:
# ✅ То, что работает с первого раза
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
spec:
parentRefs:
- name: my-gateway
hostnames:
- api.company.com
rules:
- matches:
- path:
type: PathPrefix
value: /v2
backendRefs:
- name: api-v1 # 90% трафика
port: 8080
weight: 90
- name: api-v2 # 10% трафика (canary)
port: 8080
weight: 1015 строк. Ноль annotations. Заработало с первого раза.
Я смотрел на этот YAML и не верил. Это было слишком просто.
Но самое магическое произошло дальше.
Через неделю Product Owner: "Добавь JWT-авторизацию".
С Nginx Ingress это означало бы: ещё 5 annotations, внешний auth service, настройка CORS, дебаггинг почему токены не проходят.
С Envoy Gateway:
# Добавил 12 строк — и JWT работает
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: jwt-policy
spec:
targetRef:
kind: HTTPRoute
name: api-route
jwt:
providers:
- name: auth0
issuer: https://company.auth0.com/
audiences:
- api://myapp
remoteJWKS:
uri: https://company.auth0.com/.well-known/jwks.jsonПрименил. Заработало. С первого раза.
Никаких магических строк в annotations. Никакого гугления "как правильно экранировать URL в YAML-строке". Всё типизировано, всё валидируется, всё понятно.
В тот момент я понял: я больше никогда не вернусь к Nginx Ingress annotations.
Что такое Envoy Gateway (без воды)
Envoy Gateway — это Kubernetes-native API Gateway, построенный на трёх китах:
1. Envoy Proxy — движок, который не тупит
Это высокопроизводительный proxy от Lyft, который используют Google, Uber, Netflix. Тот самый Envoy, на котором работает Istio.
Что умеет из коробки:
- HTTP/1.1, HTTP/2, HTTP/3, gRPC, WebSocket
- Load balancing с умными алгоритмами (consistent hashing, least request)
- Circuit breaking, retry, timeout — без плагинов
- Rate limiting, JWT validation — нативно
- Observability — метрики в Prometheus, трейсы в Jaeger, всё автоматически
Аналогия: Nginx — это Toyota Corolla. Надёжная, проверенная, но базовая. Envoy — это Tesla Model S. Современная, напичканная технологиями, но сложнее в освоении. Envoy Gateway — это Tesla с автопилотом. Вся мощь Envoy, но управление простое.
2. Gateway API — стандарт вместо хаоса
Представьте: Kubernetes выпустил новый официальный API для управления входящим трафиком. Не Ingress (ему уже 7 лет, и он устарел). Gateway API — это Ingress 2.0.
Ключевое отличие:
| Ingress (старый) | Gateway API (новый) |
|---|---|
| Строковые annotations (без проверок) | Типизированные поля (валидация на лету) |
| Каждый контроллер — свой синтаксис | Единый стандарт для всех |
| Переезд = переписывание annotations | Переезд = смена gatewayClassName |
| Advanced фичи = костыли | Advanced фичи = нативные CRD |
Простыми словами: Ingress — это как слать письма с инструкциями курьеру. "Если увидишь дом с красной крышей, передай посылку Ивану". Gateway API — это API с чётким контрактом. { "recipient": "Ivan", "address": { "color": "red" } }. Валидируется, не сломается.
3. Control Plane — оркестр вместо хаоса
Это мозг системы. Вы пишете декларативную конфигурацию (Gateway, HTTPRoute). Control Plane:
- Создаёт и управляет Envoy Proxy pods
- Транслирует ваши манифесты в конфигурацию Envoy (xDS протокол)
- Обновляет конфигурацию без рестарта proxy (hot reload)
- Интегрируется с cert-manager, external-dns, Prometheus
Вы описываете "что хотите". Он делает "как достичь".
Три кейса, когда Envoy Gateway спасёт вашу задницу
Кейс 1: Canary Deployment (уже рассказал, но повторю)
Без Envoy Gateway:
- 47 строк YAML
- 12 annotations
- 6 часов дебаггинга
- Документация противоречит реальности
- Один символ не в том месте — всё ломается
С Envoy Gateway:
- 15 строк YAML
- 0 annotations
- Работает с первого раза
- Если ошиблись — Kubernetes API выдаст ошибку до применения
Кейс 2: JWT + Rate Limiting за 5 минут
Задача: API должен проверять JWT токены и лимитировать 100 запросов в минуту на пользователя.
Nginx Ingress: Добавляете 3 annotations для JWT (если контроллер это поддерживает). Для rate limiting — разворачиваете Redis, настраиваете Lua-скрипт, молитесь чтобы заработало.
Envoy Gateway: Два манифеста. Всё из коробки.
# JWT — 12 строк
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: jwt-policy
spec:
targetRef:
kind: HTTPRoute
name: api-route
jwt:
providers:
- name: auth0
issuer: https://mycompany.auth0.com/
audiences:
- api://myapp
remoteJWKS:
uri: https://mycompany.auth0.com/.well-known/jwks.json
---
# Rate Limiting — 15 строк
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: rate-limit
spec:
targetRef:
kind: HTTPRoute
name: api-route
rateLimit:
type: Local
local:
rules:
- clientSelectors:
- headers:
- name: x-user-id
type: Distinct
limit:
requests: 100
unit: MinuteПрименили. Заработало.
Envoy Gateway:
- Проверяет JWT на каждом запросе
- Кеширует публичные ключи (JWKS) автоматически
- Лимитирует запросы в памяти (без Redis!)
- Экспортирует метрики (сколько отклонено, сколько прошло)
И всё это без единой строки кода на вашей стороне.
Кейс 3: gRPC с метриками и health checks
Проблема: У вас gRPC-сервис. Nginx Ingress поддерживает gRPC, но:
- Нет gRPC health checks (придётся писать костыль)
- Метрики — вручную
- Load balancing — базовый round-robin
Envoy Gateway понимает gRPC нативно:
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: user-service
spec:
parentRefs:
- name: my-gateway
hostnames:
- grpc.example.com
rules:
- matches:
- method:
service: myapp.v1.UserService
method: GetUser
backendRefs:
- name: user-service
port: 9090Бонусы из коробки:
- Метрики per gRPC method (latency
GetUser, error rateCreateUser) - gRPC health checks (настраиваются автоматически)
- Retry для failed запросов
- Circuit breaking при перегрузке
Envoy изначально создавался в Lyft для gRPC-сервисов. Это его родная стихия. Nginx добавил поддержку gRPC позже, как "дополнительную фичу".
Когда Envoy Gateway НЕ нужен (честно)
Я не евангелист. Envoy Gateway — мощный инструмент, но не для всех.
НЕ используйте Envoy Gateway, если:
❌ У вас монолит на 1-2 сервиса — Nginx Ingress проще и быстрее настроить
❌ Kubernetes < 1.25 — Gateway API v1 появился только в 1.25
❌ Команда не готова учить новое — переход требует переписывания всех Ingress в HTTPRoute
❌ Нужна полноценная Service Mesh — если вам нужен mTLS между всеми сервисами, возьмите Istio
❌ Критична максимальная простота — "один Ingress на весь кластер" проще, чем разбираться в Gateway/HTTPRoute/Policy
Используйте Envoy Gateway, если:
✅ Нужны advanced фичи — canary, A/B testing, JWT, rate limiting, circuit breaking
✅ Важна портируемость — сегодня Envoy Gateway, завтра Istio Gateway, манифесты одинаковые
✅ Устали от vendor lock-in — annotations каждого Ingress Controller уникальны
✅ Планируете расти — Envoy Gateway — хороший шаг перед полноценной Service Mesh
✅ Нужна observability — метрики, трейсы, логи из коробки
Архитектура: как это работает внутри
Envoy Gateway — это два слоя: Control Plane (мозг) и Data Plane (мускулы).
┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ │
│ │ Control Plane (envoy-gateway) │ │
│ │ │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ Gateway API Controller │ │ │
│ │ │ (watches Gateway, Route) │ │ │
│ │ └────────┬─────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ xDS Translator │ │ │
│ │ │ (Gateway API → Envoy cfg)│ │ │
│ │ └────────┬─────────────────┘ │ │
│ │ │ xDS (gRPC) │ │
│ └───────────┼─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Data Plane (envoy-proxy pods) │ │
│ │ │ │
│ │ ┌────────┐ ┌────────┐ │ │
│ │ │ Envoy │ │ Envoy │ ... │ │
│ │ │ Pod 1 │ │ Pod 2 │ │ │
│ │ └───┬────┘ └───┬────┘ │ │
│ │ │ │ │ │
│ └──────┼───────────┼──────────────┘ │
│ │ │ │
│ │ Ingress Traffic (HTTP/gRPC) │
│ ▼ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Backend Services (Pods) │ │
│ │ app-v1, app-v2, user-service │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
Control Plane (один pod в namespace envoy-gateway-system):
- Следит за вашими Gateway, HTTPRoute, GRPCRoute манифестами
- Транслирует их в конфигурацию Envoy (xDS протокол)
- Управляет lifecycle Envoy Proxy pods (создаёт, обновляет, удаляет)
Data Plane (N pods Envoy Proxy):
- Принимают трафик из интернета
- Применяют routing rules, rate limiting, JWT validation
- Проксируют на backend сервисы
- Экспортируют метрики, трейсы, логи
Ключевое отличие от Nginx Ingress:
Nginx Ingress:
User → Nginx Pod (читает Ingress YAML) → Service → Pods
Envoy Gateway:
User → Envoy Proxy Pods (получают config от Control Plane) → Service → Pods
↑
xDS config (gRPC)
↑
Control Plane (читает Gateway API YAML)
Преимущества:
- Data Plane масштабируется независимо (больше Envoy pods = больше throughput)
- Hot reload конфигурации без рестарта proxy
- Единый формат конфига (xDS) — можно заменить Envoy Gateway на другой контроллер
Практика: от нуля до canary за 15 минут
Хватит теории. Давайте руками.
Шаг 1: Установка (3 минуты)
Требования:
- Kubernetes 1.25+
- kubectl настроен
Устанавливаем через kubectl:
# Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
# Envoy Gateway
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/install.yaml
# Проверяем
kubectl get pods -n envoy-gateway-system
# Должен быть pod: envoy-gateway-xxxxx (STATUS: Running)После установки появится GatewayClass с именем envoy-gateway. Это шаблон, из
которого будут создаваться ваши Gateway.
Шаг 2: Деплоим тестовое приложение (2 минуты)
Создадим две версии echo-сервиса для демонстрации canary.
# Создаём файл echo-app.yaml
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-v1
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: echo
version: v1
template:
metadata:
labels:
app: echo
version: v1
spec:
containers:
- name: echo
image: hashicorp/http-echo:latest
args: ["-text=Hello from v1"]
ports:
- containerPort: 5678
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-v2
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: echo
version: v2
template:
metadata:
labels:
app: echo
version: v2
spec:
containers:
- name: echo
image: hashicorp/http-echo:latest
args: ["-text=Hello from v2 (canary!)"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: echo-v1
namespace: demo
spec:
selector:
app: echo
version: v1
ports:
- port: 80
targetPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: echo-v2
namespace: demo
spec:
selector:
app: echo
version: v2
ports:
- port: 80
targetPort: 5678
EOF
# Проверяем
kubectl get pods -n demo
# Должно быть 4 пода: echo-v1-xxx (2 шт), echo-v2-xxx (2 шт)Шаг 3: Создаём Gateway (2 минуты)
Gateway — это точка входа для трафика. Аналог LoadBalancer.
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: demo-gateway
namespace: demo
spec:
gatewayClassName: envoy-gateway
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
EOF
# Ждём, пока Gateway станет готовым
kubectl wait --for=condition=Programmed gateway/demo-gateway -n demo --timeout=300s
# Получаем IP/Hostname
export GATEWAY_IP=$(kubectl get gateway demo-gateway -n demo -o jsonpath='{.status.addresses[0].value}')
echo "Gateway IP: $GATEWAY_IP"В облачных K8s (GKE, EKS, AKS) Gateway получит LoadBalancer с внешним IP. В
локальных кластерах (minikube, kind) используйте kubectl port-forward для
доступа.
Шаг 4: Создаём HTTPRoute с canary (3 минуты)
Настроим распределение трафика 90% → v1, 10% → v2.
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: echo-route
namespace: demo
spec:
parentRefs:
- name: demo-gateway
hostnames:
- echo.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: echo-v1
port: 80
weight: 90 # 90% трафика на v1
- name: echo-v2
port: 80
weight: 10 # 10% трафика на v2 (canary)
EOF
# Проверяем статус
kubectl get httproute -n demo
# STATUS: AcceptedШаг 5: Тестируем (5 минут)
Делаем 20 запросов и смотрим распределение:
# Если у вас внешний IP:
for i in {1..20}; do
curl -H "Host: echo.example.com" http://$GATEWAY_IP/
done
# Если используете port-forward (локальный кластер):
kubectl port-forward -n demo svc/demo-gateway-envoy-gateway 8080:80 &
for i in {1..20}; do
curl -H "Host: echo.example.com" http://localhost:8080/
done
# Результат (примерно):
# Hello from v1 (18 раз из 20 ≈ 90%)
# Hello from v2 (canary!) (2 раза из 20 ≈ 10%)🎉 Поздравляю! Вы только что настроили canary deployment за 15 минут.
Никаких магических annotations. Никакого гугления. Всё работает.
Бонус: добавляем rate limiting за 2 минуты
Защитим наше API от DDoS. Лимит: 5 запросов в минуту на пользователя.
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: rate-limit
namespace: demo
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: echo-route
rateLimit:
type: Local
local:
rules:
- clientSelectors:
- headers:
- name: x-user-id
type: Distinct
limit:
requests: 5
unit: Minute
EOF
# Тестируем (делаем 10 запросов с одним user_id)
for i in {1..10}; do
curl -H "Host: echo.example.com" -H "x-user-id: user123" http://$GATEWAY_IP/
done
# Первые 5 запросов: HTTP 200 OK
# Следующие 5: HTTP 429 Too Many RequestsРаботает. Без Redis. Без внешних зависимостей.
Envoy хранит счётчики в памяти и синхронизирует между репликами.
Rate limiting работает из коробки. Для production можете переключиться на Global mode с Redis для синхронизации между несколькими Gateway pods.
Подводные камни (чтобы вы не наступили)
Подводный камень 1: Gateway API версии
Проблема: Gateway API активно развивается. Experimental фичи (SecurityPolicy, BackendTrafficPolicy) могут меняться.
Решение:
- Используйте стабильные v1 ресурсы (Gateway, HTTPRoute, GRPCRoute)
- Для experimental фичей проверяйте compatibility matrix
- Фиксируйте версию Envoy Gateway в production
Подводный камень 2: TLS сертификаты
Проблема: Вы настроили HTTPS, но сертификаты нужно обновлять вручную каждые 90 дней.
Решение: Используйте cert-manager для автоматического renewal:
# Установка cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# ClusterIssuer для Let's Encrypt
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: demo-gateway
namespace: demo
EOF
# Gateway с TLS
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: demo-gateway
namespace: demo
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
gatewayClassName: envoy-gateway
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls
EOFcert-manager автоматически создаст и будет обновлять сертификаты.
Подводный камень 3: Observability
Проблема: В production нужно видеть метрики (latency, error rate, throughput).
Решение: Envoy экспортирует метрики в Prometheus из коробки.
Ключевые метрики:
envoy_http_downstream_rq_total— общее количество запросовenvoy_http_downstream_rq_xx— запросы по статус-кодам (2xx, 4xx, 5xx)envoy_http_downstream_rq_time— latency (p50, p95, p99)envoy_cluster_upstream_rq_retry— количество retry
Готовый Grafana dashboard: Envoy Gateway Overview
Production Checklist (чтобы не проснуться ночью от алертов)
Перед запуском в production пройдитесь по чеклисту:
- High Availability: минимум 2 реплики Envoy Proxy pods
- Resource Limits: CPU/memory limits на Envoy pods (чтобы не пожрали весь кластер)
- TLS Termination: cert-manager настроен для HTTPS
- Rate Limiting: защита от DDoS и злоупотреблений
- Circuit Breaking: защита backend от каскадных падений
- Observability: метрики в Prometheus, алерты настроены
- Graceful Shutdown: preStop hooks для завершения активных соединений
- Security Policies: JWT validation, CORS, request validation
- Backup Configuration: все манифесты в Git
- Testing: integration тесты для критичных routes
Пример production Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: production
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
gatewayClassName: envoy-gateway
listeners:
# HTTP → HTTPS redirect
- name: http
protocol: HTTP
port: 80
hostname: "*.example.com"
# HTTPS с автоматическими сертификатами
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls
---
# Автоматический редирект на HTTPS
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-redirect
namespace: production
spec:
parentRefs:
- name: production-gateway
sectionName: http
hostnames:
- "*.example.com"
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301Миграция с Nginx Ingress (без боли)
Вопрос от читателя: "У меня в production 30 Ingress ресурсов. Как мигрировать?"
Ответ: Постепенно. Не в лоб.
Стратегия "параллельный запуск"
Фаза 1: Proof of Concept (неделя)
- Установите Envoy Gateway параллельно с Nginx Ingress
- Создайте Gateway с отдельным LoadBalancer IP
- Мигрируйте один некритичный сервис на HTTPRoute
- Тестируйте неделю — мониторьте метрики, error rate, latency
Фаза 2: Traffic Split (2 недели)
- Настройте DNS weighted routing: 10% → Envoy Gateway, 90% → Nginx Ingress
- Мониторьте: error rate, latency, throughput
- Постепенно увеличивайте вес Envoy Gateway (10% → 25% → 50% → 75% → 100%)
- Откатывайте на Nginx при проблемах (DNS switch за 5 минут)
Фаза 3: Full Migration (месяц)
- Мигрируйте все сервисы по одному
- Удалите Nginx Ingress после 2 недель без инцидентов
- Задокументируйте новые паттерны для команды
Транслируем Ingress → HTTPRoute
Было (Nginx Ingress):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
rules:
- host: api.example.com
http:
paths:
- path: /api(/|$)(.*)
backend:
service:
name: api-service
port:
number: 8080Стало (Envoy Gateway):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
spec:
parentRefs:
- name: production-gateway
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: api-service
port: 8080
---
# Rate limiting через отдельную политику
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: api-rate-limit
spec:
targetRef:
kind: HTTPRoute
name: api-route
rateLimit:
type: Local
local:
rules:
- limit:
requests: 100
unit: MinuteЧто изменилось:
- ✅ Annotations → типизированные поля
- ✅ Regex в path → явный PathPrefix
- ✅ Rate limiting → отдельная политика (переиспользуется)
- ✅ Валидация на уровне Kubernetes API
Это не про технологию. Это про свободу.
Когда я впервые настроил Envoy Gateway, я почувствовал облегчение.
Не восторг. Не эйфорию. Именно облегчение.
Облегчение от того, что больше не надо:
- Гуглить "как правильно написать regex в nginx annotation"
- Перечитывать документацию 7 раз, чтобы понять один параметр
- Молиться, чтобы после апдейта контроллера не сломались annotations
- Объяснять джуниору, почему "просто добавить canary" займёт 4 часа
Envoy Gateway — это не про "новую технологию".
Это про избавление от боли.
Боли, которую вы даже не замечали, потому что привыкли. Как привыкаешь к скрипу дверной петли — раздражает, но терпимо.
А потом смазываешь петлю. И понимаешь: боже, как же я раньше жил с этим скрипом?
Вот в чём сила Envoy Gateway:
Не в том, что он "быстрее" (хотя он быстрее). Не в том, что он "мощнее" (хотя он мощнее).
А в том, что он понятен.
Вы читаете HTTPRoute — и видите логику. Вы пишете SecurityPolicy — и она работает с первого раза. Вы добавляете RateLimit — и спите спокойно, зная что DDoS не убьёт ваш API.
Это свобода от магии.
Свобода от "а почему эта annotation не работает?". Свобода от "а где документация для этой версии контроллера?". Свобода от "а кто-нибудь вообще знает, как это настроить?".
Gateway API — это стандарт.
А стандарт означает:
- Документация одинаковая для всех контроллеров
- Валидация на уровне Kubernetes API
- Миграция между реализациями без переписывания манифестов
- Знания переносятся между проектами и компаниями
Вы не учите "Nginx Ingress annotations". Вы учите Kubernetes Gateway API.
И это знание работает с Envoy Gateway, Istio Gateway, Cilium Gateway, Kong Gateway.
Это инвестиция в будущее, а не привязка к vendor.
Начните сегодня
Я знаю, что вы думаете прямо сейчас.
"Звучит круто, но у меня нет времени разбираться с новым инструментом."
"В production Nginx Ingress. Работает. Зачем менять?"
"Когда-нибудь попробую. Добавлю в TODO."
Я вас прекрасно понимаю. Я думал так же.
Но вот что я понял после миграции:
Каждый день, который вы откладываете переход, вы:
- Тратите лишние часы на отладку annotations
- Ограничиваете себя возможностями старого API
- Увеличиваете техдолг, который потом будет мигрировать сложнее
Не нужно мигрировать весь production прямо сейчас.
Начните с одного шага:
Ваше задание на сегодня (30 минут)
- Поднимите локальный кластер (minikube или kind)
- Установите Envoy Gateway (3 команды kubectl)
- Повторите пример из статьи (canary deployment)
- Почувствуйте разницу
Не читайте дальше — откройте терминал прямо сейчас.
# 1. Локальный кластер (если нет)
minikube start
# или
kind create cluster
# 2. Установка Envoy Gateway
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/install.yaml
# 3. Скопируйте примеры из раздела "Практика" выше
# 4. Сделайте 20 curl запросов
# 5. Увидьте 90/10 распределение трафика
# Весь процесс: 15 минутПочему это важно сделать сегодня:
Через 30 минут вы почувствуете разницу. Не прочитаете. Не поверите на слово. А ощутите на своём опыте, каково это — когда всё работает с первого раза.
И тогда вы поймёте, что Envoy Gateway — это не hype. Это эволюция.
P.S. Если вы дочитали до конца — вы уже в топ-10% инженеров, которые не игнорируют новые технологии.
Но знание без действия — это просто развлечение.
Откройте терминал. Потратьте 30 минут. Почувствуйте разницу.
И завтра на стендапе скажите: "Вчера попробовал Envoy Gateway. Ребята, это меняет правила игры."
P.P.S. Самый честный тест вашего мастерства:
Если вы не можете объяснить своему PM, почему Envoy Gateway лучше Nginx Ingress на языке бизнес-выгод (а не технических деталей) — вы ещё не понимаете инструмент достаточно глубоко.
Вернитесь к разделу "Три кейса". Перескажите их своими словами.
Потому что в конечном счёте технологии не важны.
Важно то, какие проблемы они решают и сколько времени экономят вашей команде.
Envoy Gateway экономит мне 4-6 часов в неделю на настройку и отладку.
Посчитайте свои часы. И решите, стоит ли 30 минут на эксперимент.
Я верю, что стоит.
См. также:
- Kafka + FastAPI — если используете event-driven архитектуру
- Load Balancers — базовые концепции балансировки нагрузки
- Мониторинг Stack — как мониторить Envoy Gateway в production

