!Astro.props.image &&
← Назад к блогу

Kubernetes Gateway API: от нуля до героя

ingress-nginx сняли с поддержки, Ingress API заморожен. Разбираем его преемника на одном живом магазине: типизированные ресурсы, разделение между платформой и приложением, canary, TLS, ссылки между неймспейсами и меш.

Виктор Ведмич · 16 мин чтения

kubernetes gateway-api networking

В марте 2026 ingress-nginx сняли с поддержки. По оценке самого проекта Kubernetes, он работал примерно в половине cloud native-окружений. Новых релизов не будет, исправлений тоже, даже для уязвимостей. Вот что переводит Gateway API из разряда «надо бы как-нибудь посмотреть» в «разбираюсь прямо сейчас».

Значит, разбираемся. Статья выросла из моего доклада, в котором мы проходим путь от нуля до героя. Берём один интернет-магазин и начинаем с одного маршрута. Дальше наращиваем схему по одной идее за раз, пока в ней не появятся TLS, canary-выкатка, несколько команд и зависимость из чужого неймспейса. Примеры не привязаны к вендору и актуальны для Gateway API v1.5 (февраль 2026). Слайды встроены прямо в текст, анимированные можно прокликать самому. Реализацию на AWS разберём отдельным постом.

Сразу про название, его легко перепутать. Речь про Gateway API, сетевой стандарт Kubernetes. Это не «API gateway», то есть общий архитектурный компонент, и не Amazon API Gateway, сервис AWS. Разные вещи.

ingress-nginx сняли с поддержки. Ingress API заморожен

В докладе на «почему сейчас» у меня ровно один слайд, здесь тоже обойдусь одним разделом. Четыре факта:

  • ingress-nginx больше не поддерживают (март 2026). Репозитории закрыты на запись, патчей под будущие уязвимости не будет. Уже развёрнутые контроллеры продолжают работать, поэтому про них так легко забыть. Проверить, есть ли он у тебя: kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx.
  • Gateway API стал стандартом. Основные ресурсы получили версию v1 в октябре 2023, v1.5 вышел в феврале 2026. Это официальный преемник Ingress от SIG Network.
  • Реализаций много. GKE, AKS, Istio, Cilium, Envoy Gateway, NGINX Gateway Fabric и другие. По состоянию на 21 апреля 2026 полное соответствие v1.5 подтвердили семь реализаций.
  • API Ingress заморожен. Он в GA, удалять его из Kubernetes не планируют, но и менять больше не будут. Всё новое появляется в Gateway API. Если начинаешь сегодня, начинай отсюда.

На этом история закончилась. Дальше только «что» и «как».

Как запрос вообще доходит до пода?

Сначала, до всякого YAML, главная задача. У браузера есть адрес shop.example.com. Код приложения работает в поде с внутренним IP вроде 10.1.2.7. Когда под заменяют, например при выкатке или после вытеснения с ноды, новый под может получить другой IP. Прописать IP пода в DNS можно, но верным он останется недолго. Кто-то должен перекинуть мост через этот разрыв.

От браузера до пода: сервис закрывает внутреннюю половину пути, но внешний трафик до нужного сервиса всё ещё кто-то должен довести. Эту недостающую деталь и описывает Gateway API.

Половину задачи Kubernetes уже решил через сервис: стабильный виртуальный IP и DNS-имя перед группой подов. В нашем магазине сервисы типа ClusterIP, они доступны только внутри кластера. Сервисы типов NodePort и LoadBalancer умеют выставить наружу один сервис, но общей входной двери с хостами, путями и правилами маршрутизации не дают. Эту недостающую деталь и описывает Gateway API: типизированный способ задать точку входа и маршрутизацию, где у каждой части свой владелец. Раньше это место занимал Ingress. Gateway API отвечает на тот же вопрос, но устроен лучше.

Чем Ingress перестал устраивать

Сначала точно назовём, что в Ingress не так на уровне устройства. Gateway API закрывает каждый пункт самим устройством ресурсов, а не новой порцией настроек.

  1. Почти всё жило в аннотациях. Переписывание путей, таймауты, CORS, canary: всё нетипизированными строками. У ingress-nginx их набралось больше сотни. Для TLS в Ingress есть родное поле spec.tls, но почти всё, что сверх хоста, пути и TLS, уходило в аннотации. Ключ с опечаткой контроллер молча игнорирует, и узнаёшь об этом в три часа ночи.
  2. Один объект, один владелец. Чтобы добавить маршрут по пути, разработчик правил тот же объект, где лежат настройки TLS и поведение балансировщика. Разделить это между командами аккуратно не получалось.
  3. Привязка к вендору через аннотации. Ключ nginx.ingress.kubernetes.io/... ничего не значит для Traefik или HAProxy. Чтобы сменить контроллер, приходилось искать замену каждой аннотации и заново проверять каждый маршрут.
  4. На L7 спецификация умела мало. Хосты и пути в API были, а маршрутизации по заголовкам, весов трафика и матчинга по методу не было. Каждый контроллер прикручивал свою версию, чаще всего через, как нетрудно догадаться, новые аннотации.

Запомни эти четыре пункта. Дальше каждый из них решится.

Gateway API в одной фразе

Если запомнить только одну фразу, то эту. Gateway API берёт монолитный объект Ingress и разбивает его на типизированные ресурсы. У каждого свой владелец, и они цепляются друг к другу, описывая, как трафик проходит от края кластера до подов.

Из этого следует несколько свойств. Модель построена вокруг ролей: отдельные ресурсы позволяют раздать их разным командам, а закрепляет это разделение RBAC. Всё типизировано: API-сервер проверяет каждое поле по схеме, а контроллер пишет в статус, удалось ли применить настройки. Модель не зависит от вендора: фичи уровня Core ведут себя одинаково на любом контроллере, прошедшем conformance по нужному профилю. Какие фичи уровня Extended поддерживает твой, видно из его отчёта. И один API маршрутизации покрывает оба направления: вход извне (north-south) и сервис-меш (east-west). Теперь проверим эту фразу на деле и соберём ресурсы по одному.

Четыре ресурса

Сквозной пример: намеренно упрощённый магазин по мотивам Online Boutique от Google. В нём пять сервисов. Четыре (web, products, cart, orders) принадлежат команде магазина. Пятый, payments, живёт в неймспейсе другой команды. Запомни эту деталь: из-за неё дальше понадобятся ссылки между неймспейсами.

1. GatewayClass: шаблон

Ресурс уровня кластера: через controllerName он указывает, какой контроллер обслуживает шлюзы этого класса. Ближайшая аналогия: StorageClass. Диск сам не собираешь, а просишь диск класса fast-ssd, и дальше им занимается провизионер. Здесь так же. Класс отделяет конфигурацию маршрутизации от реализации, им управляет команда инфраструктуры. Команды приложений его не трогают.

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: prod
spec:
  # контроллер, который запрограммирует реальную инфраструктуру
  controllerName: example.net/gateway-controller

2. Gateway: точка входа

Главный герой модели. Когда создаёшь Gateway, контроллер поднимает или настраивает настоящий балансировщик либо прокси. У Gateway есть слушатели (порты, протоколы, настройки TLS), и один Gateway означает одну входную дверь в кластер. Здесь же проходит граница ответственности за инфраструктуру: слушатели ссылаются на TLS-сертификаты, а allowedRoutes решает, из каких неймспейсов можно цеплять маршруты. Это и есть рычаг управления в руках платформенной команды. Начнём с обычного HTTP, HTTPS добавим в разделе про продакшн.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shop-gateway
  namespace: infra
spec:
  gatewayClassName: prod
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Selector   # All | Same | Selector
          selector:
            matchLabels:
              gateway-access: "true"

3. HTTPRoute: правила

Здесь живут разработчики. HTTPRoute проверяет хост и путь запроса, отправляет его в нужный сервис и цепляется к Gateway через parentRefs. В нашем HTTP-примере из всего Gateway API разработчику приложения нужен только этот ресурс: типизированный, с проверкой по схеме, в собственном неймспейсе. Ему хватит прав RBAC на HTTPRoute в своём неймспейсе. Права на Gateway не нужны, доступ к закрытому ключу сертификата тем более. Обрати внимание: parentRefs указывает на Gateway в неймспейсе infra. Такую привязку из чужого неймспейса разрешает allowedRoutes самого Gateway, ReferenceGrant для неё не нужен.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web
  namespace: shop
spec:
  parentRefs:
    - name: shop-gateway
      namespace: infra
  hostnames: ["shop.example.com"]
  rules:
    - matches:
        - path: { type: PathPrefix, value: / }
      backendRefs:
        - name: web
          port: 8080

4. Сервис и поды: пункт назначения

Хорошая новость: тут всё знакомо. Обычный сервис Kubernetes и его поды, ничего специфичного для Gateway API. В цепочке они важны вот почему: поды живут недолго, их заменяют, и IP меняются. А сервис остаётся на месте. Поэтому HTTPRoute ведёт на сервис и никогда на под напрямую. В backendRefs просто указан уже существующий сервис и его порт. Это мост из Gateway API в тот Kubernetes, который у тебя уже работает.

Кто за что отвечает

Вот главное во всей модели: та же цепочка, раскрашенная по зонам ответственности.

За GatewayClass отвечает поставщик инфраструктуры. За Gateway, его TLS и политику привязки отвечает оператор кластера. За HTTPRoute отвечает разработчик приложения, в своём неймспейсе и без прав на Gateway.

Вспомни беду Ingress: один объект, один владелец, разработчику приходится лезть в общий конфиг. Разделение на три роли и решает эту проблему. Сами ресурсы права не раздают, это делает RBAC. Зато теперь права удобно раздать по ресурсам: каждой команде только те, за которые она отвечает.

Собираем путь целиком

Теперь награда за терпение. GatewayClass, Gateway и HTTPRoute задают конфигурацию. По ней контроллер настраивает балансировщик или прокси, который и обрабатывает трафик. Сам запрос через объекты Kubernetes не проходит. Он попадает на балансировщик или прокси, который описывает Gateway, тот сверяет запрос с правилами HTTPRoute и отправляет его на здоровый под за сервисом:

Бирюзовым отмечена конфигурация платформы, янтарным слой приложения, фиолетовым рабочая нагрузка. Объекты описывают путь, а запрос несёт прокси. Каждая следующая фича будет вариацией ровно этой картинки.

Практика: маршрутизируем магазин

Пора деплоить. CRD Gateway API в Kubernetes не встроены, их ставят отдельно, и v1.5 работает на любом Kubernetes 1.30 и новее. Gateway API можно обновлять отдельно от кластера, если версия Kubernetes подходит под требования нового релиза. Нужен ещё контроллер, который поддерживает эту версию и нужные тебе фичи, поэтому при обновлении CRD сверяйся с его гайдом по совместимости.

Перед тем как применять примеры, поставь контроллер, создай неймспейсы infra и shop и разверни сервис web на порту 8080. Имена prod и example.net/gateway-controller условные, подставь GatewayClass своего контроллера.

# 1. Установить CRD Gateway API (Standard channel, GA-ресурсы)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/\
releases/download/v1.5.0/standard-install.yaml

# 2. Проверить, что CRD на месте
kubectl get crd | grep gateway.networking.k8s.io

# 3. Установить контроллер (NGINX Gateway Fabric, Istio, Cilium,
#    Envoy Gateway или облачный) и создать или выбрать его GatewayClass.
kubectl get gatewayclass
#   NAME   CONTROLLER                      ACCEPTED
#   prod   example.net/gateway-controller  True

CRD задают словарь, а контроллер следит за этими объектами и программирует настоящую инфраструктуру. Проверь, что у GatewayClass в выводе ACCEPTED: True. Это значит только, что контроллер принял класс. Дойдёт ли трафик, покажут следующие проверки.

Дальше платформенная команда ставит входную дверь. Пока с одним HTTP-слушателем и с селектором по лейблу, который решает, кто вправе цепляться:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shop-gateway
  namespace: infra
spec:
  gatewayClassName: prod
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: "true"

Затем неймспейс shop получает лейбл-ключ под этот замок, а команда магазина цепляет маршрут. Важная деталь: лейбл здесь и есть разрешение, поэтому ставит его администратор кластера, а не команда, которой нужен доступ. Если команды приложений сами правят лейблы своих неймспейсов, они сами себя и пропустят.

apiVersion: v1
kind: Namespace
metadata:
  name: shop
  labels:
    gateway-access: "true"      # ключ под замок Gateway
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: web
  namespace: shop
spec:
  parentRefs:
    - name: shop-gateway
      namespace: infra
  hostnames: ["shop.example.com"]
  rules:
    - backendRefs: [{ name: web, port: 8080 }]   # без matches: PathPrefix /, но только для hostnames

Теперь проверь каждый стык. Этот шаг обычно пропускают, а потом гадают, почему ничего не работает. Gateway API отдаёт подробный статус, чего Ingress никогда не умел:

# Запрограммирован ли Gateway, получил ли адрес?
kubectl get gateway shop-gateway -n infra
#   NAME           CLASS  ADDRESS         PROGRAMMED
#   shop-gateway   prod   203.0.113.10    True

# Чисто ли прицепился маршрут?
kubectl get httproute web -n shop -o jsonpath=\
'{range .status.parents[*].conditions[*]}{.type}={.status}{"\n"}{end}'
#   Accepted=True
#   ResolvedRefs=True

# Послать настоящий запрос через входную дверь
ADDR=$(kubectl get gateway shop-gateway -n infra \
  -o jsonpath='{.status.addresses[0].value}')
curl -H "Host: shop.example.com" "http://$ADDR/"

Три проверки, три стыка: инфраструктура, привязка, трафик. Чтобы расширить магазин, команда добавляет новые HTTPRoute (/products на products, /cart на cart) в своём неймспейсе. Если слушатель уже пускает этот неймспейс, Gateway никто не трогает и тикет платформенной команде никто не пишет. Gateway остаётся общей инфраструктурой, а маршрутами команды управляют сами.

HTTPRoute во всю силу

Путь только начало. Матчинг по пути бывает трёх видов. Exact совпадает ровно с одним путём, удобно для health-эндпоинтов. PathPrefix сравнивает целые сегменты пути: /products подходит для /products/42, но не для /products-old. На нём построишь большинство маршрутов. RegularExpression мощный, но его поддержка и синтаксис зависят от контроллера, поэтому сначала почитай документацию своего контроллера и прогони свои выражения на тестовых запросах. На нём часто спотыкаются при переезде с nginx.

Дальше идут условия, которых в Ingress не было, и для каждого в HTTPRoute есть типизированное поле. По заголовку: трафик с x-version: beta уходит на новую сборку. По параметру запроса: ?debug=true ведёт на отладочный бэкенд. По методу: POST /orders идёт в сервис записи, GET /orders в сервис чтения. В одном элементе matches можно задать сразу путь, заголовок и метод, и тогда должны выполниться все три условия. Между отдельными элементами действует «или».

Любимая фича зала: разделение трафика (traffic splitting), canary-выкатка прямо в маршруте:

cart-v1 с весом 90, cart-v2 с весом 10. Прокси распределяет запросы на L7 по весам, независимо от числа реплик. Доли задают два элемента в backendRefs.
rules:
  - backendRefs:
      - name: cart-v1
        port: 8080
        weight: 90
      - name: cart-v2
        port: 8080
        weight: 10

Чтобы выкатывать дальше, сдвигаешь веса: 90/10, потом 50/50, потом 0/100, и на каждом шаге смотришь на метрики. Что-то пошло не так? Возвращаешь веса назад. Для ручной canary-выкатки хватает весов в HTTPRoute, без Argo Rollouts и Flagger. Эти инструменты пригодятся, когда захочешь автоматизировать анализ метрик и сами шаги выкатки, но базовый механизм уже встроен.

Наконец, фильтры обрабатывают запрос по дороге, и это тоже типизированные поля, а не аннотации. RequestHeaderModifier добавляет, перезаписывает или убирает заголовки запроса. RequestRedirect отдаёт редирект с кодом из поля statusCode, например 301 или 302. URLRewrite может переписать путь перед отправкой: снаружи адрес остаётся /products, а сервис видит /. RequestMirror отправляет копию трафика на второй бэкенд. Часть фильтров относится к Extended, поэтому проверь, какие из них поддерживает твой контроллер.

Продакшн: TLS, несколько команд, ссылки между неймспейсами

Магазин уже маршрутизирует трафик, но продакшну нужно больше. Сначала TLS. И обрати внимание, где он живёт: на слушателе Gateway, у платформенной команды, а не в маршруте разработчика. Сначала создай в infra секрет shop-tls с сертификатом для shop.example.com. Потом замени HTTP-слушатель на HTTPS-слушатель ниже (если HTTP оставляешь, настрой редирект на HTTPS). Селектор в allowedRoutes остаётся тем же, иначе слушатель пустит маршруты только из неймспейса самого Gateway:

listeners:
  - name: https
    port: 443
    protocol: HTTPS
    hostname: shop.example.com
    tls:
      mode: Terminate            # TLS клиента завершается на шлюзе
      certificateRefs:
        - kind: Secret
          name: shop-tls         # у платформы, в неймспейсе infra
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            gateway-access: "true"

mode: Terminate значит, что TLS-соединение клиента завершается на шлюзе. Соединение от шлюза до бэкенда настраивается отдельно: в нашем примере это обычный HTTP, а TLS до бэкенда включает BackendTLSPolicy, если её поддерживает контроллер. certificateRefs указывает на Secret shop-tls в неймспейсе infra. Разработчики магазина, которые пишут HTTPRoute, не трогают закрытый ключ и не занимаются ротацией. Одна команда отвечает за криптографию, другая за маршрутизацию. Если TLS должен завершаться на бэкенде, понадобится слушатель с protocol: TLS и mode: Passthrough плюс TLSRoute.

Раз Gateway служит общей входной дверью, к нему независимо цепляются сразу несколько команд. Свои маршруты у команды магазина, у маркетинга /promo и /campaigns из своего неймспейса, у поддержки /help и /status. Маршрут должен пройти проверку allowedRoutes и подходить под hostname слушателя, а запросы через HTTPS-слушатель обслуживаются с его настройками TLS. Общая точка входа, а маршруты у каждой команды свои: здесь это просто естественная форма API.

Но всё это доверенные команды магазина. Сервис payments, о котором мы договорились помнить с самого начала, живёт в неймспейсе другой команды, и HTTPRoute магазина должен сослаться на него как на бэкенд. Для такой ссылки нужно явное разрешение:

Ссылка из маршрута магазина на payments в чужом неймспейсе по умолчанию запрещена (RefNotPermitted). Команда payments, владелец цели, заводит ReferenceGrant и даёт согласие. Разрешение выдаёт владелец, а не тот, кто просит.

Главное свойство: команда магазина не может выдать себе доступ к payments сама. Согласие даёт команда payments, создавая ReferenceGrant в своём неймспейсе, и при раздельных правах RBAC никто другой создать его там не сможет. Это настоящее двустороннее рукопожатие, ровно то, что нужно, когда речь о деньгах. Только держи в голове границы: ReferenceGrant разрешает ссылку из маршрута, и всё. Аутентификацию платёжных запросов и сетевые политики он не заменяет. В канале Standard ReferenceGrant с v0.6.0, а в v1.5 он получил версию API v1 со всеми гарантиями GA.

За пределами HTTP и внутрь меша

У HTTPRoute есть родственники. GRPCRoute (GA) обслуживает gRPC с матчингом по сервису и методу. TLSRoute в v1.5 перешёл в Standard и получил версию v1: он маршрутизирует TLS-соединения по SNI, а слушатель может работать в режиме Passthrough или Terminate. Если в старых докладах его называли экспериментальным, это уже не так. TCPRoute и UDPRoute в v1.5 оставались экспериментальными. Для продакшна важны два канала: Standard гарантирует совместимость, а экспериментальные ресурсы и поля могут поменяться несовместимо.

А есть ещё целое второе направление трафика. GAMMA (Gateway API for Mesh Management and Administration) распространяет тот же API на трафик между сервисами внутри кластера:

Трафик извне (north-south, бирюзовый) входит через Gateway. Трафик внутри кластера (east-west, янтарный) обслуживает расширение GAMMA: в parentRefs у HTTPRoute указан сервис, а не Gateway. Одна эта замена превращает тот же API маршрутизации в API для меша.

Весь фокус в этой одной замене: в parentRefs у HTTPRoute указан сервис, а не Gateway. Для профиля Mesh это сервис типа ClusterIP с kind: Service и group: "". Если меш реализует GAMMA, для внутренних вызовов получаешь маршрутизацию по заголовкам и canary-выкатки по весам в той же форме HTTPRoute, которую уже знаешь. GAMMA реализуют Istio, Linkerd и меш Cilium, а какие фичи поддерживает твоя версия, проверь отдельно. Один API на оба направления.

Весь магазин, все концепции сразу

Вот весь магазин на одном экране. Янтарный shop-gateway на 443 с TLS. Неймспейс магазина с четырьмя HTTPRoute, включая canary 90/10 для cart. И сервис payments в неймспейсе другой команды: маршрут магазина может на него сослаться только потому, что это разрешает ReferenceGrant.

GatewayClass за Gateway, ресурсы по зонам ответственности, матчинг по пути, разделение трафика, TLS на краю, несколько команд на одном Gateway и ссылка в чужой неймспейс по разрешению ReferenceGrant. Начали с одного сервиса web, пришли к этой схеме.

Заметь главное: ядро за всё это время не поменялось. Всю историю вытянули GatewayClass, Gateway, HTTPRoute, сервис и поды. Для TLS добавилась ссылка на Secret, для payments появился ReferenceGrant, но каждый из них делает одну узкую работу. Всё остальное мы просто собрали из тех же кубиков. За это я и люблю Gateway API: новые сценарии собираются из знакомых ресурсов.

Эксплуатация в 2026

Чтобы эксплуатировать его уверенно, нужно знать три вещи. Первое: что сейчас актуально. v1.5 вышел 27 февраля 2026 и стал крупнейшим релизом, его общая тема: перевод экспериментальных фич в Standard. Самое заметное в нём: ListenerSet. Слушатели можно описывать отдельно и подмешивать в Gateway. Так платформенная команда может отдавать отдельные слушатели командам приложений, а общий Gateway может принять больше 64 слушателей. Только Gateway должен разрешить это явно через allowedListeners: по умолчанию он не принимает ни одного ListenerSet. TLSRoute и ReferenceGrant получили версию v1. Фильтр CORS для HTTPRoute вошёл в канал Standard: если контроллер его поддерживает, аннотации для CORS больше не нужны.

Обновление, октябрь 2026: 30 июня 2026 вышел Gateway API v1.6. TCPRoute и UDPRoute перешли в канал Standard, а экспериментальные ресурсы переехали в отдельную группу API gateway.networking.x-k8s.io. Всё, что описано в статье, по-прежнему работает.

Второе, и это самая полезная модель в голове: спецификация не равна реализации. Сам API не привязан к вендору и версионируется. Работу делает контроллер. Фичи уровня Core обязательны во всех профилях, по которым контроллер заявил conformance. Фичи уровня Extended необязательны, а матчинг пути через RegularExpression по определению отдан на откуп контроллеру. А теперь страшная тайна: поле может лежать в канале Standard, быть в статусе GA, а твой контроллер его всё равно не поддерживает. Просто это Extended-фича. Неподдерживаемый фильтр, например, может уронить весь маршрут в Accepted=False. Не угадывай: сверяйся с отчётом о conformance для своей версии контроллера, а поведение, которое зависит от контроллера, проверяй по его документации и тестами. Одна эта привычка снимает большую часть вопросов «почему мой маршрут не работает».

Третье: грабли, на которые наступают при реальных миграциях.

  • Проверяй поведение путей, а не только синтаксис. Prefix в Ingress и PathPrefix в Gateway API оба сравнивают целые сегменты. Поэтому простые префиксы, как правило, переезжают как есть. А вот регулярные выражения и аннотации ingress-nginx, которые меняли обработку путей, так просто не переедут. Их разбирай по одной.
  • Разберись, какого разрешения не хватает. Привязку маршрута к Gateway в другом неймспейсе регулирует allowedRoutes. Ссылке на бэкенд в другом неймспейсе нужен ReferenceGrant. Без него маршрут покажет ResolvedRefs=False с причиной RefNotPermitted, а запросы к этому бэкенду получат HTTP 500.
  • Смотри нужные условия статуса. У HTTPRoute это Accepted и ResolvedRefs для каждого родителя, у Gateway это Programmed. Когда что-то не так, сообщение в условии обычно прямо говорит, в чём дело.
  • Не каждая аннотация переносится один в один. Для части трюков из nginx config-snippet, например ограничения частоты запросов или своих Lua-скриптов, в Gateway API нет стандартных полей. Проверь, что умеют политики твоего контроллера, а где аналога нет, закладывай время на переделку.

От нуля до героя

Начали с одного сервиса web. В конце у магазина общая HTTPS-дверь, маршруты, которыми команды управляют сами, canary-выкатка по весам и явно разрешённая ссылка на payments. И всё на одной и той же горстке кубиков.

С чего начать на практике: подбери совместимые версии Kubernetes (1.30 или новее), Gateway API и контроллера с пройденным conformance. Открой первый сервис ровно так, как мы сделали с web, проверь условия статуса и пошли настоящий запрос. Когда запрос дойдёт до приложения, добавляй остальные маршруты.

Что почитать дальше

  • Слайды: Kubernetes Gateway API: от нуля до героя. Вся дека, на которой построена статья. Анимированные схемы удобно прокликать в режиме презентации.
  • Дальше: дека про реализацию на AWS. В ней эта вендор-нейтральная основа ложится на конкретику: контроллеры балансировщиков, ACM для сертификатов и VPC Lattice для меша.

Открыть поиск

Esc
↑ ↓ навигация ↵ открыть