Logo Craft Homelab Docs Контакты Telegram
Уход ingress-nginx: перевод маршрутизации Kubernetes на Gateway API Трендовые github проекты в нашем телеграм канале. Подпишись →
31 августа 2026 г.

Что делать с кластером, который держится на аннотациях nginx

Откройте любой production-кластер и посмотрите на Ingress-объекты. Скорее всего, в них найдётся набор вроде такого:

annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /$2
  nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
  nginx.ingress.kubernetes.io/use-regex: "true"
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-weight: "10"

Формально это Kubernetes Ingress. Фактически это конфигурация NGINX, которая по историческим причинам записана в аннотации Kubernetes. Пока сервисов пять, разница незаметна. Когда их триста и несколько кластеров, эти аннотации превращаются в слой знаний, который держат в голове два-три инженера.

Проект ingress-nginx завершил поддержку. Для многих команд это первый за годы повод остановиться и спросить: как маршрутизация трафика в кластере должна выглядеть ближайшие пять лет.

Ingress остаётся, заканчивается конкретный контроллер

Стоит разделить две вещи. Ресурс Kubernetes Ingress никуда не делся, NGINX тоже. Закрылась история одного контроллера. При этом основная сложность возникла раньше и не связана с поддержкой: Ingress начали применять для задач, под которые он изначально слишком простой.

Регулярные выражения в путях, нестандартный rewrite, канареечные развёртывания через веса, глобальные параметры в ConfigMap контроллера — всё это живёт поверх спецификации Ingress и зависит от реализации. Когда контроллер меняется, именно этот пласт требует ручной работы.

Gateway API как модель ответственности

Главная ценность Gateway API проявляется не в синтаксисе и не в новых возможностях роутинга. Он разделяет инфраструктуру и приложения на уровне API.

Платформенная команда отвечает за внешний балансировщик, TLS, сетевую безопасность и наблюдаемость. Она описывает Gateway и GatewayClass:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: platform-gateway
  namespace: infra-gateway
spec:
  gatewayClassName: envoy
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-tls
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: "true"

Команда приложения работает только со своим маршрутом и не трогает сетевую инфраструктуру:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: orders
  namespace: orders
spec:
  parentRefs:
    - name: platform-gateway
      namespace: infra-gateway
  hostnames:
    - shop.example.internal
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api/orders
      backendRefs:
        - name: orders-service
          port: 8080

Права на Gateway и HTTPRoute разводятся через RBAC и allowedRoutes. Разработчик самостоятельно управляет путями и бэкендами, но не может переопределить TLS или политику балансировщика. Для больших платформ это ближе к реальному распределению обязанностей, чем общий пул аннотаций.

Сценарий, который выглядит логичным и приводит к боли

«У нас 400 Ingress, пишем конвертер и переносим всё разом». Технически часть работы автоматизируется, и через пару дней выясняется, что 350 объектов — это простые host → path → service, а оставшиеся 50 содержат всю накопленную специфику: regex, кастомный rewrite, канарейки, зависимость от глобальной настройки в ConfigMap пятилетней давности.

Автоматическая конвертация YAML переносит форму, но не поведение. После неё начинается настоящая работа: проверить, что новый роутинг обрабатывает те же запросы так же, как старый. Сложные случаи разбираются поштучно, а не пакетом.

Миграция без миграции

Рабочий подход для инфраструктуры с десятками кластеров: не объявлять большой проект перевода. Старый ingress продолжает обслуживать существующие сервисы. Рядом разворачивается контроллер Gateway API.

Дальше меняется одно: внутренний Helm-чарт для новых сервисов перестаёт создавать kind: Ingress и начинает создавать HTTPRoute. Внутренняя документация описывает Gateway API как стандартный способ публикации. Платформенная команда строит вокруг новой модели шаблоны, проверки и наблюдаемость.

Через полгода большинство новых приложений уже не зависит от старого контроллера. Через год часть старых сервисов переписана или выведена из эксплуатации по своим причинам. Вместо миграционного проекта на 500 сервисов получается постепенное сокращение технического долга.

Начинать с аудита, а не с выбора контроллера

Частая ошибка — сразу спорить про реализацию: Envoy Gateway, Traefik, NGINX Gateway Fabric, Cilium. Выбор контроллера — не первый вопрос. Первый вопрос: что именно сейчас делает ваш ingress-nginx.

Список используемых nginx-аннотаций с частотой:

kubectl get ingress -A -o json \
  | jq -r '.items[].metadata.annotations // {} | keys[]' \
  | grep nginx.ingress.kubernetes.io | sort | uniq -c | sort -rn

Сервисы, где включены regex или канареечные развёртывания:

kubectl get ingress -A -o json \
  | jq -r '.items[] | select(
      (.metadata.annotations // {})["nginx.ingress.kubernetes.io/use-regex"] == "true"
      or (.metadata.annotations // {})["nginx.ingress.kubernetes.io/canary"] == "true"
    ) | .metadata.namespace + "/" + .metadata.name'

Отдельно стоит зафиксировать глобальные параметры из ConfigMap контроллера и правила, которые заданы вне самих Ingress. Обычно после такого аудита картина проясняется: основная масса маршрутов простая, а вся сложность сосредоточена в небольшом числе сервисов, и с ними работают точечно.

Не у всех задача требует Gateway API. Если нужно быстро заменить неподдерживаемый компонент с минимальными изменениями, разумно взять другой ingress-контроллер и не трогать архитектуру. Gateway API оправдан там, где кластер стал внутренней платформой для десятков команд и вопрос звучит так: как дать сотням разработчиков управлять маршрутизацией, не выдавая доступ к сетевой инфраструктуре.

Практический вывод

Ingress останется в обиходе надолго: он простой и покрывает большинство сценариев. Завершение поддержки одного контроллера стоит воспринимать как повод открыть свои Ingress-объекты и посмотреть на них свежим взглядом.

Минимальный первый шаг для платформы, завязанной на ingress-nginx: перестать создавать новые зависимости от старой модели. Существующие приложения работают дальше, production никто не ломает. Новые сервисы получают HTTPRoute и стандартный шаблон публикации. Дальше время работает на платформу — каждый новый сервис появляется в новой архитектуре, каждый старый мигрирует отдельно, и в какой-то момент ingress-nginx превращается из критического компонента в обычную legacy-зависимость.