Миграция с ingress-nginx: выбор нового контроллера и переход к Gateway API

22 мая 2026

Ingress-nginx долгое время оставался стандартным ingress-контроллером для Kubernetes, но после объявления о завершении активной поддержки многим командам пришлось задуматься о миграции. В этой статье рассказываем, как мы в True Engineering выбирали новый ingress-контроллер, тестировали Traefik и постепенно готовим инфраструктуру к переходу на Gateway API без простоев и массового переписывания сервисов.

Почему тема смены ingress-контроллера стала актуальной

Большинство инженеров, работающих с Kubernetes, уже знают, что ingress-nginx уходит на пенсию. В официальном объявлении Kubernetes говорится, что поддержка ingress-nginx продолжится в режиме best-effort до марта 2026 года. После этого проект перестанет получать новые релизы, исправление ошибок и обновление безопасности.

Мы в True Engineering, как и многие команды в отрасли, долгое время использовали ingress-nginx в собственных и клиентских кластерах. Контроллер стабильно работает, хорошо изучен и закрывает базовые задачи маршрутизации трафика. При этом небольшой, но показательный опрос на Reddit показывает, что ingress-nginx до сих пор занимает почти половину рынка.

01 (3)

После появления официальной даты окончания поддержки ситуация резко изменилась. Вопрос уже не в том, нужно ли мигрировать, а в том, как сделать это безопасно и без серьезных изменений в инфраструктуре. Сейчас всем приходится отвечать на несколько вопросов:

  • куда мигрировать 
  • какие риски возникают при переходе 
  • сколько будет стоить миграция 
  • какие ограничения и несовместимости появятся

Ingress API vs Gateway API 

Параллельно в экосистеме Kubernetes развивается новый стандарт публикации сервисов — Gateway API. Постепенно он становится основным направлением развития вместо классического Ingress API.

Gateway API решает задачи, которые раньше приходилось закрывать сложными ingress-конфигурациями, аннотациями и дополнительными механизмами. Если говорить коротко, основная идея Gateway API — более четкое разделение ответственности и более гибкая маршрутизация. В классическом Ingress все обычно описывается в одном ingress-объекте: хост, правила маршрутизации, TLS, иногда дополнительные параметры через аннотации. По мере роста инфраструктуры такие конфигурации становятся все сложнее и хуже масштабируются.

В Gateway API архитектура сразу разделена на несколько логических уровней. Объект Gateway описывает точку входа в кластер для конкретного хоста, а Route-объекты отвечают за правила маршрутизации. Если провести аналогию с nginx:

• Gateway — уровень хоста

• Route — уровень location и маршрутизации внутри него

Такой подход позволяет разным командам независимо управлять своей частью конфигурации и упрощает сопровождение инфраструктуры.

02 (5)

Подробнее про различия API можно прочитать в официальной документации.

При этом переход на Gateway API требует определенных трудозатрат: нужно переписывать манифесты, обновлять Helm-чарты, менять CI/CD-пайплайны и тестировать маршрутизацию и TLS.

Поэтому мы решили разделить миграцию на несколько этапов. Сначала заменить ingress-контроллер на современное поддерживаемое решение с минимальными изменениями текущих сервисов, а затем постепенно переводить инфраструктуру на Gateway API по мере готовности процессов и инструментов.

Так мы снизим риски и не будем совмещать сразу несколько крупных изменений. Дополнительно важно учитывать текущее состояние экосистемы. Многие популярные Helm-чарты, включая Bitnami и другие широко используемые решения, до сих пор ориентированы на классический Ingress и только начинают добавлять поддержку Gateway API. Поэтому Ingress какое-то время останется частью production-инфраструктур, несмотря на развитие нового стандарта.

Наш контекст: инфраструктура и ограничения

Чтобы понять масштаб миграции, важно описать контекст нашей инфраструктуры.

Сейчас в эксплуатации находятся:

  • 5 собственных Kubernetes-кластеров 
  • более 500 ingress-ресурсов 
  • десятки клиентских кластеров в публичных облаках, on-premise инфраструктуре и в средах заказчиков. 

Любые изменения сетевого слоя затрагивают сразу большое количество систем с разными требованиями и уровнем критичности.

Отдельно стоит отметить production-окружения с высокой нагрузкой, где публикация сервисов наружу — критичная часть инфраструктуры. В таких системах любые изменения нужно выполнять максимально аккуратно, без простоев и влияния на пользователей. Это автоматически ограничивает варианты миграции. Нельзя просто переключить контроллер одним релизом или массово переписать конфигурации. Необходим постепенный переход с тестированием и возможностью отката.

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

Например:

Механизмы аутентификации и интеграции с внешними сервисами

- auth-url
- auth-signin 
- auth-response-headers 

Управление протоколами и поведением backend-сервисов

- backend-protocol 
- x-forwarded-prefix
- x-forwarded-proto

Настройки CORS

- enable-cors 
- cors-allow-origin
- cors-allow-methods
- cors-allow-credentials 

Параметры буферизации и таймауты

- proxy-body-size 
- proxy-buffer-size
- proxy-buffers-number
- proxy-connect-timeout
- proxy-read-timeout
- proxy-send-timeout
- client-body-buffer-size


Маршрутизация и переписывания путей

- rewrite-target 

Пользовательские сниппеты конфигурации

- configuration-snippet 

- server-snippet 

Последние два пункта особенно чувствительны при миграции. Они позволяют внедрять произвольные nginx-настройки прямо в конфигурацию ingress и дают очень высокую гибкость. Одновременно это создает сильную зависимость от конкретной реализации контроллера. Такие конструкции практически невозможно перенести на другое решение без изменений, и именно они чаще всего становятся основной точкой сложности при миграции.

Требования к новому ingress / gateway решению

Когда стало понятно, что оставаться на ingress-nginx в долгосрочной перспективе не получится, следующим шагом стало определение требований к новому решению. Нам нужен был инструмент, который стабильно работает с классическим Ingress, поддерживает Gateway API, позволяет мигрировать постепенно и минимально затрагивает текущие сервисы.

– Одним из ключевых критериев была зрелость проекта. Мы смотрели не только на функциональность, но и на активность разработки, частоту обновлений, качество документации и размер сообщества. Это напрямую связано с операционными рисками: чем шире используется решение, тем выше вероятность, что возникающие проблемы уже известны и имеют готовые способы решения.

– Не менее важной были простота и предсказуемость миграции. У нас уже есть сотни ingress-ресурсов и большое количество автоматизации вокруг них: Helm-чарты, пайплайны и шаблоны конфигураций. Поэтому мы искали решение, которое позволит максимально сохранить существующие манифесты и текущее поведение сервисов.

– Отдельно оценивались сложность настройки, удобство эксплуатации, логирование, мониторинг и удобство диагностики. Для production-окружений также критичны производительность и стабильность под нагрузкой, поэтому мы дополнительно изучали результаты нагрузочного тестирования и рекомендации сообщества.

Конечный список требований выглядел так:

  • поддержка классического Ingress 
  • совместимость с существующими конфигурациями 
  • поддержка Gateway API 
  • активное развитие проекта 
  • минимальные изменения при миграции 
  • предсказуемое поведение 
  • высокая производительность 
  • возможность работы в облаках и on-premise инфраструктуре 

Кандидаты на замену ingress-nginx 

06 (3)Почему мы выбрали Traefik

Основными причинами выбора Traefik на замену ingress-nginx стали:

  1. Зрелость проекта и качественная документация
  2. Автоматическое обнаружение новых сервисов
  3. Высокая производительность и средняя сложность настройки
  4. Поддержка Gateway API

Но самым главным фактором для нас стало наличие специального провайдера Kubernetes Ingress NGINX.

Данный провайдер по заверению документации позволяет мигрировать с ingress-nginx с минимальными изменениями в объектах Ingress. Он следит за объектами Ingress в k8s, у которых установлен ingressClassName: nginx и преобразует их в конфигурацию traefik.

Очень много конфигурации для ingress-nginx контроллера задавалось через аннотации в Ingress-объектах. Kubernetes Ingress NGINX поддерживает часть этих аннотаций, что и позволяет мигрировать на новый контроллер с минимальными изменениями.

В документации Traefik есть отдельная статья, как провести миграцию с минимальным даунтаймом. 

Сам Traefik мы устанавливали из официального Helm-чарта.

Чтобы включить Kubernetes Ingress NGINX provider, достаточно добавить настройки в values-файл и установить Traefik:

03 (6)

helm upgrade --install traefik traefik/traefik --version=39.0.5 \

  --namespace traefik --create-namespace \

  -f values-<env>.yaml \

  --atomic --wait --debug --timeout=600s

Какие проблемы возникли

Миграция через Kubernetes Ingress NGINX provider действительно работает, но в основном для относительно простых ingress-конфигураций без специфичных ingress-nginx-аннотаций.

04 (3)

Дело в том, что на текущий момент provider поддерживает только часть аннотаций ingress-nginx. Полный список поддерживаемых и неподдерживаемых аннотаций есть в документации.

В наших конфигурациях особенно не хватало поддержки следующих аннотаций: 

nginx.ingress.kubernetes.io/rewrite-target

nginx.ingress.kubernetes.io/upstream-vhost

nginx.ingress.kubernetes.io/configuration-snippet

nginx.ingress.kubernetes.io/permanent-redirect

nginx.ingress.kubernetes.io/proxy-connect-timeout

nginx.ingress.kubernetes.io/x-forwarded-prefix

Список поддерживаемых аннотаций постепенно расширяется. Например, во время подготовки статьи уже появилась базовая поддержка rewrite-target, но до стабильного релиза изменения пока не дошли.

В GitHub-репозитории Traefik также открыто большое количество запросов на поддержку дополнительных ingress-nginx-аннотаций.

05 (3)

В некоторых случаях можно дождаться реализации нужной функции. Но если времени на ожидание нет, конфигурации приходится адаптировать вручную.

Как мы реализовали rewrite-target

Для части сервисов нам требовалось обрезать префиксы запросов: (/api и /microservice-a, /microservice-b)

Для этого мы создали middleware в Traefik:, реализующий функционал изменения пути в запросе: 

    apiVersion: traefik.io/v1alpha1
    kind: Middleware
    metadata:
       name: app-strip-prefixes
       namespace: test-ns
    spec:
       stripPrefixRegex:
          regex:
             - "/microservice-[a-z0-9\\-]+"
            - "/api"

После этого добавили аннотации Traefik в Ingress-объект: 

annotations:   
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.middlewares: test-ns-app-strip-prefixes@kubernetescrd

и заменили ingressClassName: traefik.

После этого Ingress-объект начинает отслеживаться другим провайдером (Ingress Kubernetes). При этом аннотации ingress-nginx контроллера можно оставить, чтобы при необходимости быстро переключаться между контроллерами через изменение ingressClassName.

Переход на Gateway API

Если все равно нужно переписывать некоторые настройки Ingress-объектов, то почему бы сразу не переходить на GatewayAPI? Traefik вполне может работать одновременно и c IngressAPI и c GatewayAPI. 

Вот пример манифеста объектов GatewayAPI. Нам также понадобится middleware app-strip-prefixes. —- apiVersion: 

—-
 apiVersion: traefik.io/v1alpha1
 kind: Middleware
   metadata:
        name: app-strip-prefixes
        namespace: test-ns
  spec:
        stripPrefixRegex:
     regex:
              - "/microservice-[a-z0-9\\-]+"
              - "/api"

---
 apiVersion: gateway.networking.k8s.io/v1
 kind: Gateway
 metadata:
   name: infra-gateway
   namespace: test-ns
 spec:
   gatewayClassName: traefik
   listeners:
   - allowedRoutes:
       namespaces:
          from: Same
     name: websecure
     port: 8443
     protocol: HTTPS

    hostname: infra.example.com
     tls:
       certificateRefs:
       - group: ""
         kind: Secret
         name: wildcard-example.com
         namespace: test-ns
       mode: Terminate

—-
 apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
   name: app-a-route
   namespace: test-ns
 spec:
   hostnames:
   - infra.example.com
   parentRefs:
   - group: gateway.networking.k8s.io
     kind: Gateway
     name: infra-gateway
     namespace: test-ns
     sectionName: websecure
   rules:
   - backendRefs:
     - group: ""
       kind: Service
       name: app-a-svc
       namespace: test-ns
       port: 80
       weight: 1
     filters:
     - extensionRef:
         group: traefik.io
         kind: Middleware
         name: app-strip-prefixes
       type: ExtensionRef
     matches:
     - path:
         type: PathPrefix
         value: /microservice-a

При этом в рамках одного хоста infra.example.com часть путей (Location) может продолжать работать с обычными Ingress-объектами, а часть уже использовать Gateway API.

Многие задачи, которые пока не решены через аннотации, в Traefik можно реализовать через middleware.

Со списком поддерживаемых middlewares можно ознакомиться тут. А тут список поддерживаемых аннотаций самого Traefik.

План миграции

После анализа вариантов и проверки гипотез мы сформировали следующий подход:

  • устанавливаем Traefik рядом с ingress-nginx 
  • ingress-объекты с поддерживаемыми аннотациями оставляем без изменений 
  • сложные ingress-конфигурации сразу переводим на Gateway API 
  • постепенно отказываемся от Ingress API 

Главный принцип миграции — постепенный переход с возможностью отката на любом этапе. Поскольку в одном Kubernetes-кластере могут одновременно работать несколько ingress-контроллеров, а также могут одновременно существовать Ingress и Gateway объекты, новый контроллер можно установить параллельно со старым и постепенно переносить нагрузку.

В итоге план миграции выглядит так:

  • Инвентаризация ingress-ресурсов, используемых аннотаций и сложных конфигураций. Это позволяет заранее понять объем изменений и определить конфигурации, которые потребуют переписывания. 
  • Установка нового контроллера в k8s-кластер рядом со старым 
  • Тестирование на пилотном сервисе различных сценариев: Ingress API, Gateway API, TLS, маршрутизации и интеграций с backend-системами. 
  • Переключение «простых» ingress на Traefik. Нужно перенести те сервисы, в ingress которых нет неподдерживаемых аннотаций. Для переключения трафика достаточно изменить DNS-запись или backend балансировщика. 
  • Постепенный перевод «сложных» сервисов с неподдерживаемыми ingress-аннотациями на Gateway API.

Такой подход позволяет контролировать процесс перехода и минимизировать риски в production-инфраструктуре.

Сейчас мы находимся на завершающем этапе тестирования и переключаем первые сервисы. Инвентаризация и установка нового контроллера занимают немного времени. Основные трудозатраты связаны с тестированием сценариев и переписыванием сложных ingress-конфигураций с учетом всех деталей реализации.

Выводы

Если у вас простая конфигурация и используются типовые ingress-конфигурации, переход на Traefik может пройти почти незаметно. В таких случаях достаточно использовать провайдер совместимости Kubernetes Ingress NGINX, и большинство манифестов продолжат работать без изменений или с минимальными правками. После этого можно постепенно переходить на Gateway API.

Если же инфраструктура активно использует сможные механизмы - например, rewrite, кастомные сниппеты и нетиповые настройки прокси, то избежать изменений не получится. В таком случае нет большого смысла дважды переписывать конфигурации: сначала под Traefik + Ingress API, а потом под Gateway API. Логичнее сразу переходить на Gateway API как на основное направление развития экосистемы Kubernetes. Переход на Gateway API — это уже вопрос времени и ресурсов. Поэтому перед миграцией важно провести аудит конфигураций, оценить риски, спланировать этапы перехода и заранее заложить необходимые ресурсы.

Если вам нужна помощь команды, которая уже прошла этот путь — обращайтесь к нам!

UPD: пока статья готовилась к публикации вышел «долгожданный» релиз traefik v3.7.0, в котором добавилась поддержка гораздо большего числа аннотаций ingress-nginx, включая rewrite-target. Также обновился и helm-чарт traefik до версии 4.0.0. Мы уже протестировали новую версию на нескольких кластерах и теперь миграция практически не требует никаких изменений со стороны объектов Ingress

Недавние публикации