Особенности миграции с Ingress-NGINX перед его выводом из эксплуатации
Контекст: Завершение жизненного цикла Ingress-NGINX
В ноябре 2025 года консорциум Kubernetes официально анонсировал вывод из эксплуатации (retirement) популярного контроллера Ingress-NGINX, поддерживаемого сообществом, запланированный на март 2026 года. Важно различать этот проект и проприетарное решение NGINX Ingress от компании F5: несмотря на использование NGINX в качестве основы плоскости данных (dataplane), это два независимых продукта. В связи с прекращением поддержки сообществом инженерам необходимо спланировать миграцию инфраструктуры на современный стандарт Gateway API.
Gateway API представляет собой семейство сетевых ресурсов Kubernetes (Gateway, HTTPRoute и др.), развиваемое группой SIG Network. Переход на этот стандарт дает более гибкие механизмы маршрутизации, однако прямой перенос настроек «один в один» несет серьезные риски. Поведение Ingress-NGINX по умолчанию содержит множество неявных допущений и оптимизаций, отсутствие которых в спецификациях Gateway API может нарушить работу клиентских API и привести к недоступности сервисов (outages).
Пять скрытых ловушек в поведении Ingress-NGINX
При планировании перехода необходимо учесть пять ключевых различий в обработке сетевых путей:
1. Регистронезависимость и префиксное совпадение регулярных выражений
В Ingress-NGINX при включении аннотации nginx.ingress.kubernetes.io/use-regex: "true" правила с регулярными выражениями обрабатываются как регистронезависимые (case-insensitive) префиксные совпадения. Например, если в правиле указан путь:
- path: "/[A-Z]{3}"
pathType: ImplementationSpecific
Контроллер успешно перенаправит запрос вида /uuid на целевой бэкенд, несмотря на то, что в регулярном выражении указаны только заглавные буквы, а сам запрос содержит строчные и продолжается дальше трех символов.
В большинстве Envoy-реализаций Gateway API (например, в Istio, Envoy Gateway или Kgateway) фильтр RegularExpression по умолчанию выполняет строгое регистрозависимое совпадение по всей строке. Если перенести регулярное выражение без адаптации, клиенты, отправляющие запросы на /uuid, получат ответ 404 Not Found.
Для сохранения старого поведения регулярное выражение в HTTPRoute необходимо дополнить флагом регистронезависимости (?i) и явным указанием окончания строки .*:
matches:
- path:
type: RegularExpression
value: "(?i)/[a-z]{3}.*"
2. Распространение флага use-regex на уровне хоста
Если для определенного доменного имени (host) хотя бы в одном Ingress-манифесте включена аннотация use-regex: "true", Ingress-NGINX автоматически начинает обрабатывать все пути для этого хоста во всех манифестах как регулярные выражения. Это приводит к тому, что случайные опечатки в конфигурации начинают работать «корректно».
Например, если разработчик опечатался и указал точный путь /Header вместо /headers в соседнем манифесте с pathType: Exact, Ingress-NGINX все равно успешно направит запрос на /headers, так как интерпретирует /Header как префиксное регулярное выражение. В Gateway API такое неявное поведение отсутствует: точные (Exact) и префиксные (Prefix) правила никогда не превращаются в регулярные выражения. После миграции опечатка /Header перестанет пропускать запросы /headers, что приведет к сбою.
3. Неявный режим регулярных выражений при rewrite-target
Использование аннотации для перезаписи путей nginx.ingress.kubernetes.io/rewrite-target автоматически включает обработку путей хоста как регулярных выражений, даже если аннотация use-regex: "true" явно нигде не задана.
В Gateway API механизм перезаписи вынесен в стандартные фильтры маршрута и не влияет на тип сопоставления путей остальных правил. При переносе таких конфигураций необходимо явно переводить сопоставления путей в регулярные выражения или исправлять опечатки в исходных адресах.
4. Автоматическое перенаправление при отсутствии слэша
Если в правиле Ingress-NGINX указан точный или префиксный путь со слэшем на конце (например, /my-path/), но клиент отправляет запрос без него (/my-path), контроллер не вернет ошибку. Вместо этого он автоматически выполнит перенаправление 301 Moved Permanently на адрес с замыкающим слэшем:
HTTP/1.1 301 Moved Permanently
Location: http://example.com/my-path/
Конформные реализации Gateway API не выполняют скрытых перенаправлений. Запрос /my-path к правилу /my-path/ вернет 404 Not Found. Если клиенты завязаны на этот редирект, его нужно настроить вручную с помощью фильтра requestRedirect:
rules:
- matches:
- path:
type: Exact
value: "/my-path"
filters:
- type: RequestRedirect
requestRedirect:
statusCode: 301
path:
type: ReplaceFullPath
replaceFullPath: /my-path/
- matches:
- path:
type: Exact
value: "/my-path/"
backendRefs:
- name: my-backend
port: 8000
5. Нормализация URL перед сопоставлением
Перед тем как проверить запрос по правилам маршрутизации, Ingress-NGINX нормализует путь согласно спецификации RFC 3986 (секция 6.2). Он удаляет точки (/./), разрешает относительные переходы (/abc/../uuid превращается в /uuid) и схлопывает идущие подряд слэши (////uuid -> /uuid).
Большинство контроллеров Gateway API также выполняют нормализацию путей из коробки (в частности, это делают Istio и Envoy-based решения), однако детальное поведение может отличаться. Если бэкенд ожидает на вход исключительно нормализованные пути от прокси, этот момент необходимо проверить в документации выбранного решения.
Официальный пошаговый процесс перехода на Gateway API
Для безопасного перевода трафика на новые спецификации рекомендуется следовать системной процедуре:
Шаг 1: Подготовка инструментов и аудит конфигурации
Установите официальную CLI-утилиту автоматической трансляции ingress2gateway, разрабатываемую группой Kubernetes SIG Network. Соберите полный список активных Ingress-правил и выделите конфигурации, содержащие аннотации use-regex и rewrite-target.
Шаг 2: Предварительная генерация ресурсов
Запустите утилиту для автоматического экспорта ресурсов Ingress в манифесты Gateway API. Помните, что утилита не может учесть все скрытые особенности и не гарантирует эквивалентность поведения. Полученные файлы Gateway и HTTPRoute должны быть тщательно проанализированы вручную.
Шаг 3: Ручная адаптация правил
Замените неявные регулярные выражения в сгенерированных манифестах на явные правила RegularExpression с флагами регистронезависимости (?i). Настройте явные редиректы RequestRedirect для путей, где критично наличие замыкающего слэша. Перенесите правила перезаписи путей в фильтры URLRewrite:
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplaceFullPath
replaceFullPath: /uuid
Шаг 4: Тестирование и верификация в тестовом окружении
Разверните новый Gateway API контроллер параллельно с текущим Ingress-NGINX. Настройте тестовые DNS-записи или отправляйте curl-запросы напрямую на IP-адрес нового шлюза, подменяя заголовок Host.
Выполните обязательный набор проверок:
- Запросы к точным совпадениям с сохранением и изменением регистра букв (проверка
200 OKпротив404 Not Found). - Запросы без замыкающего слэша (сравнение заголовка
Locationи кода ответа301). - Запросы со сложной структурой путей, содержащие точки и избыточные слэши (проверка логики нормализации).
- Тестирование под нагрузкой для выявления различий в поведении буферизации заголовков и таймаутов проксирования.

