Обновление контроллера Ingress NGINX в production-кластере Kubernetes без потери трафика - задача, решаемая настройкой стратегии rolling update и предварительной миграцией Ingress-ресурсов с устаревших API-версий. Этот материал содержит проверенную на практике последовательность действий: от аудита текущей конфигурации до отката в случае сбоя. Вы получите готовые команды для Helm, примеры манифестов и чек-лист пост-обновленческой проверки.
Основной инструмент для безопасного обновления - Helm. Он позволяет управлять версиями релизов, выполнять симуляцию изменений через --dry-run и быстро возвращаться к предыдущей стабильной ревизии командой helm rollback. Ручное применение манифестов также работоспособно, но требует большего контроля и резервного копирования текущих ресурсов. Вне зависимости от выбранного пути, критически важно предварительно перевести все Ingress-ресурсы на API-версию networking.k8s.io/v1 - это устраняет основную причину несовместимости при переходе на новые версии контроллера.
Перед началом работ убедитесь, что у вас есть актуальный бэкап конфигурации и доступ к кластеру с правами на управление ресурсами в namespace ingress-nginx. Если вы ранее выполняли миграцию между мажорными версиями Helm-чарта, например, с 4.x на 5.x, многие из описанных здесь шагов вам уже знакомы. Для более широкого контекста по стратегиям деплоя в Kubernetes изучите наше руководство по Rolling, Blue-Green и Canary обновлениям.
Подготовка к обновлению: аудит конфигурации и совместимость
Пропуск подготовительного этапа - самая частая причина неудачных обновлений. Контроллер Ingress NGINX развивается активно, и разработчики периодически изменяют структуру конфигурации, аннотации и поддерживаемые API-версии. Перед тем как выполнять helm upgrade, необходимо собрать информацию о текущем состоянии системы.
Проверка текущей версии Ingress NGINX и API-ресурсов
Начните с определения установленной версии контроллера. Если вы используете Helm, выполните:
helm list -n ingress-nginx
Вывод покажет имя релиза, версию чарта и версию приложения. Запомните эти значения - они понадобятся при откате. Дополнительно проверьте образ, запущенный в поде контроллера:
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o jsonpath='{.items[0].spec.containers[0].image}'
Теперь проверьте, какие API-версии используют ваши Ingress-ресурсы. Это критически важный шаг. Выполните команду для всех namespace:
kubectl get ingress -A -o yaml | grep "apiVersion:" | sort | uniq -c
Если в выводе присутствует networking.k8s.io/v1beta1, необходимо выполнить миграцию до обновления контроллера. Начиная с Kubernetes 1.22, эта версия API удалена, и современные версии Ingress NGINX (начиная с чарта 4.x) требуют строго networking.k8s.io/v1.
Миграция Ingress-ресурсов с networking.k8s.io/v1beta1 на v1
Структура Ingress-ресурса претерпела существенные изменения. Основные отличия v1 от v1beta1:
- pathType - обязательное поле в v1. Принимает значения
Prefix,ExactилиImplementationSpecific. - serviceBackend - изменён формат описания бэкенда. В v1 используется
service.nameиservice.port.number(илиservice.port.name). - ingressClassName - замена аннотации
kubernetes.io/ingress.class. В v1 это поле в spec.
Пример манифеста до миграции (v1beta1):
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example.com
http:
paths:
- path: /app
backend:
serviceName: app-service
servicePort: 80
Тот же ресурс после миграции на v1:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /app
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
Для автоматической конвертации можно использовать встроенную команду kubectl convert (доступна, если в кластере присутствует нужный API):
kubectl convert -f old-ingress.yaml --output-version networking.k8s.io/v1
После автоматической конвертации обязательно проверьте результат вручную. Утилита не всегда корректно определяет pathType и может оставить артефакты старого формата. Примените обновлённые манифесты командой kubectl apply и убедитесь, что трафик продолжает обслуживаться корректно.
Дополнительно сверьтесь с changelog целевой версии Ingress NGINX. Разработчики документируют все критические изменения, включая удаление аннотаций и переименование параметров ConfigMap. Если вы пропустили несколько мажорных версий, изучите наше руководство по миграции с Helm chart 4.x на 5.x - там разобраны типовые проблемы совместимости.
Стратегии обновления: Helm upgrade и ручное применение манифестов
Выбор метода обновления зависит от того, как был установлен контроллер, и от принятых в вашей команде практик управления инфраструктурой. Helm рекомендуется для production-сред: он обеспечивает версионирование, простой откат и воспроизводимость конфигурации. Ручные манифесты дают полный контроль над каждым ресурсом, но повышают риск человеческой ошибки.
Обновление через Helm с настройкой rolling update
Стратегия rolling update позволяет заменить поды контроллера последовательно, без единовременного отключения всех экземпляров. Это достигается параметрами maxUnavailable и maxSurge. Значение maxUnavailable=0 гарантирует, что в процессе обновления ни один под не будет удалён до тех пор, пока новый не запустится и не пройдёт readiness-пробу.
Перед обновлением обновите локальный кэш репозиториев:
helm repo update
Базовая команда для обновления без даунтайма:
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--set controller.strategy.rollingUpdate.maxUnavailable=0 \
--set controller.strategy.rollingUpdate.maxSurge=1
Если вы управляете конфигурацией через values.yaml, скачайте текущий файл, внесите изменения и укажите его при обновлении:
helm get values ingress-nginx -n ingress-nginx -o yaml > current-values.yaml
# Внесите необходимые правки в current-values.yaml
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--values current-values.yaml
Параметр maxSurge=1 разрешает создание одного дополнительного пода сверх желаемого количества в момент обновления. Это ускоряет процесс, но требует наличия свободных ресурсов на узлах. В условиях жёстких ресурсных ограничений установите maxSurge=0.
Ручное обновление с применением манифестов
Этот метод подходит для сред, где Helm не используется, или когда требуется детальная инспекция каждого YAML-файла перед применением. Скачайте статический манифест нужной версии из официального репозитория Ingress NGINX на GitHub:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v<VERSION>/deploy/static/provider/cloud/deploy.yaml
Перед применением обязательно создайте резервную копию текущих ресурсов:
kubectl get deployment ingress-nginx-controller -n ingress-nginx -o yaml > backup-deployment.yaml
kubectl get configmap ingress-nginx-controller -n ingress-nginx -o yaml > backup-configmap.yaml
Примените новый манифест:
kubectl apply -f deploy.yaml
Ручной метод не предоставляет встроенного механизма отката. Возврат к предыдущему состоянию потребует повторного применения сохранённых бэкапов, что увеличивает время восстановления. Для минимизации рисков в production-средах мы рекомендуем использовать Helm. Подробнее о стратегиях деплоя и отката читайте в нашем разборе реальных инцидентов при обновлениях.
Выполнение обновления: пошаговый процесс
Процесс обновления разбит на две фазы: симуляцию и непосредственное применение. Симуляция позволяет увидеть, какие именно изменения Helm внесёт в кластер, не затрагивая работающие ресурсы.
Симуляция обновления с помощью --dry-run
Выполните команду обновления с флагами --dry-run и --debug:
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--values current-values.yaml \
--dry-run --debug
Анализируйте вывод. Обратите внимание на следующие сигналы:
- Изменения в Deployment: обновление образа, изменение стратегии обновления, переменных окружения.
- Изменения в ConfigMap: добавление или удаление параметров конфигурации nginx.
- Изменения в Service: модификация портов или аннотаций.
- Предупреждения о конфликтах ресурсов или невозможности применить изменения.
Если вывод содержит неожиданные изменения, вернитесь к values.yaml и скорректируйте параметры. Не применяйте обновление, пока вывод --dry-run не станет полностью предсказуемым.
Применение обновления и контроль развертывания
После успешной симуляции выполните команду без --dry-run:
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--values current-values.yaml
Немедленно начните отслеживать статус развёртывания:
kubectl rollout status deployment/ingress-nginx-controller -n ingress-nginx
Эта команда будет сообщать о прогрессе и завершится успехом или ошибкой. Параллельно в другом терминале наблюдайте за подами:
kubectl get pods -n ingress-nginx -w
Вы увидите, как старые поды переходят в состояние Terminating, а новые - в Running. Проверьте логи нового пода на предмет ошибок:
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller --tail=50
Критические ошибки на этом этапе - сигнал к немедленному откату. Не ждите, пока проблема затронет весь трафик.
Действия после обновления: проверка и мониторинг
Успешное завершение kubectl rollout status не гарантирует корректную обработку трафика. Необходимо провести серию проверок, чтобы убедиться в стабильной работе контроллера.
Выполните тестовый HTTP-запрос к одному из сервисов, маршрутизируемых через Ingress. Подставьте реальный хост и IP-адрес вашего балансировщика:
curl -H 'Host: example.com' http://<INGRESS_IP>/app
Проверьте, что ответ содержит ожидаемые данные и код состояния 200. Протестируйте несколько различных путей и хостов, чтобы охватить все правила маршрутизации.
Проверьте статус подов и убедитесь, что все экземпляры контроллера находятся в состоянии Ready:
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
Если у вас настроен сбор метрик в Prometheus, проверьте ключевые показатели:
nginx_ingress_controller_requests- общее количество запросов. Убедитесь, что счётчик растёт.nginx_ingress_controller_nginx_process_connections- активные соединения. Отсутствие аномальных всплесков или падений.nginx_ingress_controller_ingress_upstream_latency_seconds- задержка до бэкендов. Значения должны оставаться в пределах нормы.
Для базового мониторинга без Prometheus достаточно периодически проверять логи контроллера и статус подов в течение первых 15-30 минут после обновления. Это временное окно, в течение которого проявляется большинство скрытых проблем.
Откат обновления: быстрое восстановление при сбоях
Если проверки выявили проблемы - ошибки маршрутизации, 5xx ответы, падения подов - выполните откат. Helm хранит историю релизов, и возврат к предыдущей ревизии выполняется одной командой.
Просмотрите историю релиза, чтобы найти номер стабильной ревизии:
helm history ingress-nginx -n ingress-nginx
Вывод покажет список ревизий с номерами, статусами и временем создания. Найдите последнюю ревизию со статусом deployed до обновления. Выполните откат:
helm rollback ingress-nginx <REVISION_NUMBER> -n ingress-nginx
Если номер ревизии не указан, Helm откатится на предыдущую. После выполнения команды отследите статус развёртывания:
kubectl rollout status deployment/ingress-nginx-controller -n ingress-nginx
В случае ручного обновления откат выполняется применением сохранённых ранее бэкапов:
kubectl apply -f backup-deployment.yaml
kubectl apply -f backup-configmap.yaml
Предупреждение: откат Helm не всегда корректно обрабатывает изменения в CRD (Custom Resource Definitions). Если обновление включало модификацию CRD, может потребоваться ручное вмешательство. Перед обновлением мажорных версий всегда изучайте раздел "Upgrade Notes" в официальной документации Ingress NGINX.
После успешного отката повторите проверки из предыдущего раздела, чтобы убедиться в полном восстановлении трафика. Для углублённого понимания процесса обновления компонентов Kubernetes изучите наше руководство по обновлению кластера через kubeadm.