Шокирующее решение: Ingress NGINX будет закрыт – 7 шагов к безопасной миграции

13 ноября 2025 г.

Вступление

В мире облачных технологий мало что вызывает такой резонанс, как объявление о прекращении поддержки популярного компонента. Ingress NGINX – один из самых распространённых контроллеров входящего трафика в кластерах Kubernetes – официально объявил о «best‑effort» поддержке до марта 2026 года, а после этой даты никаких новых релизов, исправлений ошибок и патчей безопасности не будет. Для тысяч компаний, построивших свои CI/CD‑конвейеры и продакшн‑окружения именно на этом решении, новость стала настоящим тревожным звонком.

В статье мы разберём, что именно объявлено, почему это происходит, какие риски несёт дальнейшее использование устаревшего контроллера и как правильно спланировать миграцию на более современные решения, такие как Gateway API. В конце вступления – короткое японское хокку, отражающее суть перемен.

Старый путь гаснет,
Новый свет в облаке зовёт,
Вперёд – без страха.

Пересказ Reddit‑поста своими словами

Официальный блог Kubernetes (ссылка здесь) сообщает, что поддержка Ingress NGINX будет продолжаться лишь до марта 2026 года. После этой даты проект полностью «отпразднует» свою жизнь: не будет новых релизов, исправлений багов и, что особенно критично, обновлений, закрывающих обнаруженные уязвимости.

Отдельно упоминается, что разработка Ingate (проект, который планировался как более зрелая замена Ingress NGINX) так и не достигла стадии готовности и тоже будет закрыта.

Комитеты SIG Network и Security Response настоятельно советуют всем пользователям Ingress NGINX немедленно начать миграцию на Gateway API или любой другой Ingress‑контроллер, способный обеспечить безопасность и поддержку в дальнейшем.

В Reddit‑сообществе реакция была быстрой и эмоциональной. Пользователи отмечали, что:

  • «Было хорошее время, пора изучать Gateway API» – nevotheless;
  • «Не путать с nginx‑ingress, верно?» – adlerspj;
  • «Да, закрывается именно community‑версия, а не официально поддерживаемый nginx‑ingress» – Key‑Half1655;
  • «Это совсем не вводит в заблуждение» – GarboMcStevens (ирония);
  • «Вчерашняя гибкость превратилась в непосильный технический долг» – sysacc.

Суть проблемы, хакерский подход и основные тенденции

Технический долг – это не просто модное слово, а реальная угроза. Ingress NGINX был создан в 2016 году, когда Kubernetes только набирал обороты. За годы он стал де‑факто стандартом, но одновременно превратился в монолитный код, который трудно адаптировать к новым требованиям (мульти‑протокол, сервис‑мэш, динамические правила безопасности).

Хакерский подход к такой ситуации выглядит так:

  1. Аудит текущих зависимостей. Выяснить, какие кластеры используют Ingress NGINX, какие версии, какие кастомные патчи.
  2. Оценка уязвимостей. С помощью инструментов вроде Trivy или kube‑audit проверить, какие известные CVE уже находятся в эксплуатации.
  3. План миграции. Выбрать целевой контроллер (Gateway API, Traefik, Contour и т.д.) и построить путь перехода без простоя.
  4. Автоматизация. Написать скрипты, которые проверяют совместимость манифестов и автоматически переключают трафик.
  5. Мониторинг. После миграции настроить наблюдение за latency, ошибками 5xx и метриками безопасности.

Тенденции, которые усиливаются в связи с этим событием:

  • Рост интереса к Gateway API как к нативному, расширяемому и более безопасному способу управления входящим трафиком.
  • Увеличение доли мульти‑кластера и мульти‑облака, где единый контроллер должен поддерживать разные провайдеры.
  • Повышенное внимание к комплаенсу (PCI‑DSS, GDPR) – отсутствие патчей безопасности делает Ingress NGINX неприемлемым.

Детальный разбор проблемы с разных сторон

Техническая сторона

Ingress NGINX построен на базе NGINX Plus/OSS и использует ConfigMap‑ы, аннотации и CRD‑ы для настройки. За годы в проекте накопилось множество «хака», которые решали конкретные задачи, но усложняли кодовую базу. Примером является поддержка custom‑snippets, которые позволяют вставлять произвольные директивы NGINX, но делают автоматическую проверку конфигурации почти невозможной.

С точки зрения безопасности, отсутствие патчей после 2026 года означает, что любой найденный в NGINX или в самом контроллере уязвимый код будет оставаться открытым. По данным CVE‑Database, за последние 12 мес. в NGINX было зарегистрировано более 30 уязвимостей средней и высокой тяжести.

Бизнес‑сторона

Для компаний, использующих Ingress NGINX в продакшн, риски включают:

  • Потеря соответствия требованиям регуляторов (отсутствие патчей = нарушение PCI‑DSS).
  • Увеличение расходов на поддержку устаревшего кода (необходимость нанимать специалистов, умеющих «ломать» старый контроллер).
  • Угроза репутации в случае утечки данных из‑за известной уязвимости.

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

Экосистема Kubernetes

Отказ от Ingress NGINX открывает пространство для конкурентов. Уже сейчас в CNCF Survey 2024 более 30 % опрошенных компаний используют альтернативные контроллеры (Traefik, Contour, Istio‑Ingress). Появление официального Gateway API в версии 1.0 (2023) делает его естественным кандидатом для замены.

Практические примеры и кейсы

Рассмотрим два типовых сценария миграции.

Кейс 1: Большой e‑commerce с 150 млн запросов в сутки

Компания использует Ingress NGINX 0.48 с кастомными lua‑скриптами для A/B‑тестов. План миграции:

  1. Создать отдельный namespace gateway-migration и развернуть Istio‑gateway (реализация Gateway API).
  2. Экспортировать текущие правила из ConfigMap в YAML‑манифесты Gateway и HTTPRoute.
  3. Настроить Canary‑деплоймент с помощью VirtualService – 5 % трафика направляется в новый шлюз.
  4. Постепенно увеличить долю трафика, проверяя метрики latency и error‑rate.
  5. После полной миграции удалить Ingress NGINX и очистить связанные ConfigMap‑ы.

Кейс 2: Стартап с микросервисами в GKE

Команда использует Ingress NGINX 1.2, но в манифестах почти нет кастомных аннотаций. Миграция проходит в два дня:

  • Включить Gateway API в кластере (kubectl enable gateway-api).
  • Сгенерировать Gateway и HTTPRoute из существующего Ingress с помощью скрипта ingress2gateway.
  • Обновить CI‑pipeline, заменив kubectl apply -f ingress.yaml на kubectl apply -f gateway.yaml.
  • Провести smoke‑тесты и задеплоить в продакшн.

Экспертные мнения из комментариев

It was a good run. Time to read up on gateway api i guess. — nevotheless

Автор подчёркивает, что Ingress NGINX был надёжным решением, но пришло время изучать новые возможности Gateway API.

Not to be confused with nginx‑ingress, right? — adlerspj

Важный момент: закрывается именно community‑версия, а официально поддерживаемый nginx‑ingress от компании NGINX остаётся в живых.

Correct, the one being retired is the community version not the nginx maintained ingress controller — Key‑Half1655

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

well that's not confusing at all — GarboMcStevens

Ироничный комментарий, указывающий на потенциальную путаницу в названиях.

Yesterday’s flexibility has become today’s insurmountable technical debt — sysacc

Ключевая мысль: гибкость, достигнутая за годы, превратилась в тяжёлый технический долг, который теперь невозможно «вытащить» без полной перестройки.

Возможные решения и рекомендации

Для минимизации рисков рекомендуется следовать пошаговому плану:

  1. Инвентаризация. Составьте список всех кластеров, где задействован Ingress NGINX, укажите версии и кастомные настройки.
  2. Оценка риска. Проведите сканирование уязвимостей (Trivy, Anchore) и определите, какие сервисы находятся под угрозой.
  3. Выбор альтернативы. Рассмотрите варианты:
    • Gateway API (рекомендовано SIG Network)
    • Traefik Ingress
    • Contour (Envoy‑based)
    • Официальный nginx‑ingress от NGINX
  4. Пилотный проект. Выберите небольшое приложение, мигрируйте его полностью, отследите метрики.
  5. Автоматизация. Напишите скрипты, которые конвертируют Ingress‑манифесты в Gateway‑манифесты (пример ниже).
  6. Canary‑деплоймент. Перенаправляйте часть трафика на новый контроллер, наблюдайте за ошибками.
  7. Полный переход. После подтверждения стабильности удалите Ingress NGINX и связанные ресурсы.

Не забывайте про обратную совместимость: некоторые функции Ingress NGINX (например, auth‑basic) могут потребовать дополнительных CRD‑ов в Gateway API.

Заключение с прогнозом развития

Отказ от Ingress NGINX – это сигнал о том, что экосистема Kubernetes движется к более модульному и стандартизированному управлению входящим трафиком. В ближайшие 2‑3 года мы увидим:

  • Широкое принятие Gateway API как единого интерфейса для всех Ingress‑контроллеров.
  • Увеличение количества «мульти‑протокольных» шлюзов (HTTP/2, gRPC, TCP, UDP) в одном манифесте.
  • Рост инвестиций в инструменты миграции (конвертеры, CI‑шаблоны).
  • Снижение доли «старых» контроллеров до менее чем 5 % к 2028 году.

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

Практический пример кода на Python

Ниже представлен скрипт, который автоматически конвертирует Ingress‑манифест в базовый Gateway API‑манифест. Скрипт читает YAML‑файл, извлекает правила host‑path и формирует Gateway и HTTPRoute. Это упрощённый пример, но он демонстрирует подход к автоматизации миграции.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Конвертер Ingress → Gateway API.
Скрипт читает файл ingress.yaml и выводит два файла:
gateway.yaml и httproute.yaml.
Требуется установленный PyYAML (pip install pyyaml).
"""

import yaml
import sys
from pathlib import Path

def load_yaml(file_path: Path) -> dict:
    """Загружает YAML‑файл и возвращает словарь."""
    with file_path.open('r', encoding='utf-8') as f:
        return yaml.safe_load(f)

def save_yaml(data: dict, file_path: Path):
    """Сохраняет словарь в YAML‑файл."""
    with file_path.open('w', encoding='utf-8') as f:
        yaml.dump(data, f, default_flow_style=False, sort_keys=False)

def ingress_to_gateway(ingress: dict) -> (dict, dict):
    """
    Преобразует объект Ingress в объекты Gateway и HTTPRoute.
    Поддерживает только простые правила host + path.
    """
    metadata = ingress.get('metadata', {})
    spec = ingress.get('spec', {})
    name = metadata.get('name', 'converted')
    namespace = metadata.get('namespace', 'default')

    # ------------------- Gateway -------------------
    gateway = {
        'apiVersion': 'gateway.networking.k8s.io/v1beta1',
        'kind': 'Gateway',
        'metadata': {
            'name': f'{name}-gateway',
            'namespace': namespace
        },
        'spec': {
            'gatewayClassName': 'istio',  # пример, может быть любой установленный класс
            'listeners': [
                {
                    'protocol': 'HTTP',
                    'port': 80,
                    'name': 'http',
                }
            ]
        }
    }

    # ------------------- HTTPRoute -------------------
    routes = []
    for rule in spec.get('rules', []):
        host = rule.get('host')
        http = rule.get('http', {})
        for path_obj in http.get('paths', []):
            path = path_obj.get('path', '/')
            backend = path_obj.get('backend', {})
            service_name = backend.get('service', {}).get('name')
            service_port = backend.get('service', {}).get('port', {}).get('number')

            route = {
                'matches': [
                    {
                        'path': {
                            'type': 'Exact',
                            'value': path
                        },
                        'headers': [
                            {
                                'type': 'Exact',
                                'name': 'host',
                                'value': host
                            }
                        ] if host else []
                    }
                ],
                'forwardTo': [
                    {
                        'serviceName': service_name,
                        'port': service_port
                    }
                ]
            }
            routes.append(route)

    httproute = {
        'apiVersion': 'gateway.networking.k8s.io/v1beta1',
        'kind': 'HTTPRoute',
        'metadata': {
            'name': f'{name}-httproute',
            'namespace': namespace
        },
        'spec': {
            'parentRefs': [
                {
                    'name': gateway['metadata']['name']
                }
            ],
            'rules': routes
        }
    }

    return gateway, httproute

def main():
    if len(sys.argv) != 2:
        print('Usage: python3 ingress2gateway.py ')
        sys.exit(1)

    ingress_path = Path(sys.argv[1])
    ingress = load_yaml(ingress_path)

    gateway_obj, httproute_obj = ingress_to_gateway(ingress)

    # Сохраняем результаты рядом с исходным файлом
    save_yaml(gateway_obj, ingress_path.parent / 'gateway.yaml')
    save_yaml(httproute_obj, ingress_path.parent / 'httproute.yaml')
    print('Конвертация завершена: gateway.yaml, httproute.yaml созданы.')

if __name__ == '__main__':
    main()

Скрипт предназначен для быстрого прототипа. В реальном проекте потребуется добавить поддержку TLS, более сложных правил (регулярные выражения, rewrite‑правила) и проверку совместимости с выбранным GatewayClass.


Оригинал
PREVIOUS ARTICLE