Недавно мы перевели наш производственный кластер GKE с традиционного Ingress-контроллера на Kubernetes Gateway API — и, честно говоря, стоило сделать это раньше. Ниже — всё, что нужно знать: что такое Gateway API, почему мы решились на переход и как настроить его самостоятельно шаг за шагом.
Проблема Kubernetes Ingress (и почему его никогда не хватало по-настоящему)
Если вы достаточно долго эксплуатируете Kubernetes в production, вы наверняка хорошо знакомы с ресурсом Ingress. С 2015 года он считается де-факто стандартом маршрутизации внешнего HTTP/HTTPS-трафика в кластер. Простой, привычный, повсеместно поддерживаемый — он справлялся со своей задачей. Какое-то время.
Но по мере того как наши приложения усложнялись, начали проявляться трещины.
Каждый раз, когда требовалось что-то большее, чем базовая маршрутизация по хосту или пути — разделение трафика для канареечных релизов, маршрутизация по заголовкам, более гибкое управление TLS — мы утопали в кладбище вендорозависимых аннотаций. Хотите включить канареечные релизы в NGINX? Это nginx.ingress.kubernetes.io/canary: "true". Переходите на другой контроллер? Начинайте заново. Ничего из этого не было переносимым.
Ресурс Ingress задумывался намеренно минималистичным — тонкая абстракция над L7-маршрутизацией с ограниченными возможностями расширения. Он просто не был рассчитан на современный мир с несколькими командами, протоколами и окружениями.
Мы были не одиноки в этом. Запланированное устаревание поддерживаемого сообществом Ingress-NGINX Controller (ориентировочно в 2026 году) превращает дискуссию «Ingress против Gateway API» из теоретической в насущную операционную необходимость. Использование неподдерживаемого Ingress-контроллера создаёт непосредственные риски: незакрытые CVE, расхождение API с новыми версиями Kubernetes и ухудшение совместимости с развивающимися сетевыми примитивами.
Этого оказалось достаточно, чтобы действовать. Встречайте: Kubernetes Gateway API.
Что такое Kubernetes Gateway API?
В ноябре 2023 года вышел Kubernetes Gateway API v1.0 — значимая веха для проекта, который создавался четыре года. Результатом этой работы — признанной наиболее коллаборативным API в истории Kubernetes — стал стандартизированный способ управления сетевым трафиком, устраняющий ограничения традиционного Ingress в плане гибкости и расширяемости.
Gateway API достиг статуса v1.0 в конце 2023 года и с тех пор набирает популярность. Он спроектирован так, чтобы напрямую решать недостатки Ingress — предлагая более гибкий, расширяемый и мощный фреймворк.
Gateway API — это открытый стандарт для сетевого взаимодействия сервисов (service networking). Он развивает ресурс Ingress и улучшает его по нескольким направлениям: архитектура ориентирована на роли — API-ресурсы соответствуют организационным ролям оператора кластера, разработчика и поставщика инфраструктуры. Помимо этого, стандарт переносим: существует множество реализаций, что обеспечивает единообразие ключевых концепций и ресурсов в разных реализациях и средах.
Хронология говорит сама за себя:
2015 → Представлен Ingress (v1beta1)
2019 → Ingress становится GA (v1)
2020 → Начало проекта Gateway API
2023 → Gateway API v1.0 GA
2024 → Gateway API v1.1 с расширенными возможностями
2025 → Gateway API получает широкое распространение
2026 → Gateway API рекомендован для всех новых кластеров
Основные строительные блоки: GatewayClass, Gateway и HTTPRoute
Gateway API вводит модульную структуру с чёткими ролями — поставщик инфраструктуры, оператор кластера и разработчик приложения — и новые ресурсы: GatewayClass, Gateway и HTTPRoute.
Представьте это как чистое разделение ответственности между тремя персонами:
GatewayClass — в зоне ответственности поставщика инфраструктуры. Это ресурс уровня кластера, определяющий класс шлюзов и контроллер, который ими управляет. В GKE компания Google предоставляет готовые GatewayClass-ы, например gke-l7-global-external-managed и gke-l7-rilb. Вы выбираете класс, соответствующий вашим потребностям по трафику.
# GKE предоставляет их из коробки — создавать их не нужно
# Примеры доступных GatewayClass на GKE:
# gke-l7-global-external-managed → Внешний глобальный Application LB
# gke-l7-regional-external-managed → Внешний региональный Application LB
# gke-l7-rilb → Внутренний Application LB
Gateway — в зоне ответственности оператора кластера. Этот ресурс определяет, где и как балансировщик нагрузки принимает трафик — какие порты, протоколы и пространства имён разрешены.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
HTTPRoute — в зоне ответственности разработчика приложения. Здесь живут правила маршрутизации — сопоставление хостов и путей, разделение трафика, перезапись заголовков и многое другое.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
namespace: default
spec:
parentRefs:
- name: my-gateway
hostnames:
- "myapp.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: frontend-service
port: 80
Эта трёхуровневая модель меняет правила игры для крупных команд. Инженеры платформы управляют Gateway (а значит, и балансировщиком нагрузки), тогда как разработчики приложений самостоятельно управляют своими HTTPRoute — больше не нужно ждать, пока инфраструктурная команда внесёт каждое изменение маршрутизации.
Почему Gateway API превосходит Ingress: разбор по функциям
1. Никакого ада из аннотаций
В Ingress продвинутые функции требовали контроллерозависимых аннотаций. Нужны канареечные деплои с NGINX? Аннотации. Нужна ограничение частоты запросов в Traefik? Другие аннотации. Переходите на другой контроллер? Переписывайте всё заново.
Gateway API избавляет от этой перегрузки аннотациями — все эти возможности встроены непосредственно в спецификацию, делая конфигурации чище и переносимее.
2. Нативное разделение трафика для канареечных и сине-зелёных деплоев
Это была одна из наших главных болей с Ingress. В HTTPRoute разделение трафика является полноценным гражданином первого класса:
rules:
- backendRefs:
- name: app-v1
port: 80
weight: 90
- name: app-v2
port: 80
weight: 10
Это канареечное разделение 90/10. Без аннотаций. Без кастомных CRD. Просто чистый декларативный YAML.
3. Поддержка нескольких протоколов
В отличие от Ingress, Gateway API не привязан к протоколу и поддерживает HTTP, TCP, gRPC и другие. Ingress работал исключительно с HTTP/HTTPS. Если требовалась маршрутизация TCP или UDP, приходилось рассчитывать только на себя — используя нестандартные расширения контроллеров.
4. Разделение по ролям (дружественное к RBAC)
Ролевая архитектура позволяет операторам кластера определять, как общая инфраструктура может использоваться множеством независимых команд разработчиков. Это напрямую транслируется в более тонкий RBAC: дайте разработчикам права на создание HTTPRoute в их пространстве имён, но не Gateway. Команды безопасности это оценят.
5. Маршрутизация между пространствами имён
Gateway API нативно поддерживает маршрутизацию от одного Gateway через несколько пространств имён с помощью allowedRoutes. Никаких хаков, никаких обходных путей.
6. Встроенная поддержка east-west трафика
Он обрабатывает как north-south, так и east-west трафик — то есть управляет и внешним входящим трафиком, и межсервисным взаимодействием внутри кластера, снижая потребность в отдельной сервисной сетке для простых сценариев.
7. Переносимость между облачными провайдерами
Поскольку это стандарт CNCF с едиными базовыми ресурсами, конфигурации, написанные для GKE, в значительной мере работают и на EKS, AKS или в кластерах on-prem. Команда приобретает один универсальный набор навыков.
Настройка Gateway API на GKE: шаг за шагом
Перейдём к практике. Вот точная инструкция по включению и использованию Gateway API на кластере GKE.
Предварительные требования
-
Кластер GKE версии 1.24 или выше
-
Установленный и аутентифицированный
gcloudCLI -
kubectl, настроенный для работы с вашим кластером -
Кластер с VPC-native (alias IP) — обязательное условие для GKE Gateway
Шаг 1: Включите Gateway API на кластере GKE
Поддержка Gateway API поставляется вместе с GKE, но требует явного включения.
Для нового кластера:
gcloud container clusters create my-cluster \
--gateway-api=standard \
--region=us-central1 \
--enable-ip-alias \
--project=YOUR_PROJECT_ID
Для существующего кластера:
gcloud container clusters update my-cluster \
--gateway-api=standard \
--region=us-central1 \
--project=YOUR_PROJECT_ID
💡 Флаг
--gateway-api=standardвключает стандартный канал Gateway API, который включает CRD для HTTPRoute, Gateway и GatewayClass.
Шаг 2: Проверьте установку CRD и GatewayClass
# Убедитесь, что CRD Gateway API существуют
kubectl get crd | grep gateway
# Ожидаемый вывод включает:
# gateways.gateway.networking.k8s.io
# httproutes.gateway.networking.k8s.io
# gatewayclasses.gateway.networking.k8s.io
# Проверьте доступные GatewayClass, предоставленные GKE
kubectl get gatewayclass
Вы должны увидеть управляемые GKE GatewayClass-ы, например:
NAME CONTROLLER
gke-l7-global-external-managed networking.gke.io/gateway
gke-l7-regional-external-managed networking.gke.io/gateway
gke-l7-rilb networking.gke.io/gateway
gke-l7-regional-internal-managed networking.gke.io/gateway
Шаг 3: Разверните тестовое приложение
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: whereami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whereami
template:
metadata:
labels:
app: whereami
spec:
containers:
- name: whereami
image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.22
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whereami-svc
namespace: default
spec:
selector:
app: whereami
ports:
- port: 80
targetPort: 8080
type: ClusterIP
EOF
Шаг 4: Создайте ресурс Gateway
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: external-gateway
namespace: default
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
kubectl apply -f gateway.yaml
# Наблюдайте за получением IP-адреса Gateway (может занять 1-2 минуты)
kubectl get gateway external-gateway --watch
После подготовки в столбце ADDRESS появится IP-адрес. GKE автоматически создаёт Google Cloud Load Balancer за кулисами.
Шаг 5: Создайте HTTPRoute
# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whereami-route
namespace: default
spec:
parentRefs:
- name: external-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whereami-svc
port: 80
kubectl apply -f httproute.yaml
Шаг 6: Проверьте работу
# Проверьте статус Gateway
kubectl describe gateway external-gateway
# Ищите: Status > Conditions > Programmed: True
# Получите внешний IP
GATEWAY_IP=$(kubectl get gateway external-gateway \
-o jsonpath='{.status.addresses[0].value}')
# Протестируйте эндпоинт
curl http://$GATEWAY_IP/
Вы должны увидеть JSON-ответ от приложения whereami, подтверждающий прохождение трафика через Gateway.
Шаг 7 (бонус): Добавьте терминирование TLS
# Создайте TLS-секрет (замените на реальные сертификат и ключ)
kubectl create secret tls my-tls-secret \
--cert=path/to/cert.pem \
--key=path/to/key.pem
# Обновите Gateway, добавив HTTPS-листенер
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: external-gateway
namespace: default
spec:
gatewayClassName: gke-l7-global-external-managed
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: my-tls-secret
allowedRoutes:
namespaces:
from: Same
В GKE можно также использовать управляемые Google сертификаты с аннотацией networking.gke.io/managed-certificates на Gateway для автоматической выдачи сертификатов.
Ingress и Gateway API: краткое сравнение
| Функция | Ingress | Gateway API |
|---|---|---|
Разделение трафика |
Через аннотации (нестандартно) |
Нативное (веса в HTTPRoute) |
Поддержка протоколов |
Только HTTP/HTTPS |
HTTP, TCP, gRPC, TLS, UDP |
Разделение ролей |
Отсутствует — единый ресурс |
GatewayClass / Gateway / Route |
Канареечные деплои |
Зависит от контроллера |
Встроено |
Маршрутизация между namespace |
Ограничена / с костылями |
Нативная |
Переносимость |
Низкая (зависит от аннотаций) |
Высокая (стандарт CNCF) |
Маршрутизация по заголовкам |
Через аннотации |
Нативная |
East-west трафик |
Не поддерживается |
Поддерживается |
Гранулярность RBAC |
Грубая |
Тонкая, на уровне ресурса |
Наш опыт после миграции
Перевод наших производственных нагрузок GKE с Ingress на Gateway API не случился за одну ночь — около трёх недель мы работали параллельно с обоими решениями, постепенно перенося маршруты. Но результаты не заставили себя ждать:
-
Чистые манифесты. Наши YAML-файлы Ingress содержали десятки аннотаций
nginx.ingress.kubernetes.io/*. Файлы HTTPRoute понятны и читаемы для любого члена команды. -
Автономия разработчиков. Команды приложений теперь управляют своими HTTPRoute, не затрагивая Gateway. Количество тикетов к инфраструктурной команде заметно снизилось.
-
Надёжные канареечные деплои. Раньше мы с трудом собирали канареечные пайплайны из Argo Rollouts и аннотаций Ingress. Маршрутизация на основе весов в HTTPRoute существенно упростила этот процесс.
-
Интеграция с Google Cloud LB. GKE создаёт балансировщики нагрузки, реализующие конфигурацию из ресурса Gateway, — а значит, мы получаем полную мощь Cloud Load Balancing: Cloud Armor, CDN, IAP — всё это нативно связано с нашей конфигурацией маршрутизации.
Стоит ли мигрировать?
Если вы используете GKE и всё ещё работаете с Ingress-контроллером — ответ: да, и чем раньше, тем лучше. Успешная миграция предполагает аудит текущей конфигурации Ingress, конвертацию настроек и постепенное внедрение изменений.
Gateway API рекомендован для новых кластеров начиная с 2026 года. Сам Google позиционирует его как предпочтительный путь для HTTP(S)-трафика в GKE на перспективу.
Начните с малого. Возьмите один сервис, создайте HTTPRoute рядом с существующим Ingress, проверьте трафик — и расширяйте охват. Порог входа реален, но невысок, а выигрыш в гибкости, переносимости и опыте разработчиков того определённо стоит.