Kubernetes 1.19 RC: обновляем кластеры с 1.17 и переписываем аннотации nginx-ingress
Kubernetes 1.19 release candidate: Ingress выходит в GA с новой схемой, Storage Capacity Tracking в alpha. Тестируем upgrade с 1.17 и разбираемся с kubectl-convert.
Kubernetes 1.19 release candidate: Ingress переходит в GA в networking.k8s.io/v1, Storage Capacity Tracking появляется в alpha
Вышел release candidate Kubernetes 1.19, и мы наконец запустили то, что планировали ещё в июне: обновление тестового кластера с 1.17 прямо до 1.19-rc. Два minor-версии за один шаг - не самое распространённое решение, зато один клиент именно в такой ситуации: кластер давно не трогали, замораживали по бизнес-причинам, и теперь хочется сразу попасть на актуальную версию.
В рамках managed-сопровождения мы обычно не прыгаем через версию без веского повода. Но RC - хороший момент отработать сценарий на тестовом окружении, пока производственный кластер ждёт GA. Разбираемся, что сломалось и что пришлось переписать.
Ingress GA: схема изменилась серьёзнее, чем казалось
В июньском посте мы разобрали, что Ingress в networking.k8s.io/v1 меняет структуру манифеста - spec.backend становится spec.defaultBackend, портовые поля реструктурируются. Это всё верно. Но на практике оказалось, что у нас ещё три отдельные точки боли сверху.
Первое - аннотации nginx-ingress. Несколько аннотаций, которые мы использовали, зафиксированы в старых именах или изменили семантику при переходе на новый community-чарт 3.x. В частности:
nginx.ingress.kubernetes.io/rewrite-target- сама аннотация осталась, но её поведение при использовании capture-групп изменилось в chart 3.x по сравнению с тем, что было в 0.x. У нас были Ingress-ы с/$1в rewrite-target и регулярками в path - пришлось явно прописатьnginx.ingress.kubernetes.io/use-regex: "true"там, где раньше это работало неявно.nginx.ingress.kubernetes.io/ssl-passthroughв сочетании с новой схемой backend - при переходе наspec.defaultBackendодин из ресурсов перестал корректно маршрутизировать HTTPS до разбора манифеста вручную.- Аннотация
kubernetes.io/ingress.classв v1 формально заменяется наspec.ingressClassName. Старая аннотация в 1.19 ещё работает, но контроллер nginx-ingress 3.x смотрит сначала наingressClassName. Где у нас было несколько контроллеров - возникла путаница с тем, кто берёт какой ресурс.
Итого: переписали аннотации в семи Ingress-манифестах. Не катастрофа, но и не «просто поменяй apiVersion».
Второе - прямой прыжок с 1.17. Kubernetes официально поддерживает upgrade на одну minor-версию за раз. С 1.17 до 1.19 - два шага. kubeadm на это прямо указывает и не даёт пропустить. Мы прошли через 1.18 на промежуточном узле, потом до 1.19-rc - это занимает немного больше времени, но ничего принципиально сложного, если знаешь об этом заранее.
Третье - etcd. При прыжке через версию схема etcd не меняется напрямую, но миграция API-ресурсов в etcd происходит при первом обращении к новому apiVersion. Пара ресурсов, которые давно не трогали, после обновления API-сервера «оказались» в старом формате и потребовали явного re-apply манифестов. Не критично, но лучше иметь это в чек-листе.
kubectl-convert: проверяем deprecation предупреждения
Параллельно попробовали плагин kubectl-convert - он конвертирует манифесты между версиями API. Инструмент есть в kubectl начиная с 1.17 как отдельный плагин, устанавливается через krew.
Использование простое:
kubectl-convert -f ingress-old.yaml --output-version networking.k8s.io/v1
Выдаёт манифест в новом apiVersion с пересчитанной схемой. Полезно для единичных файлов - быстро видишь, что именно изменится в структуре. На папку с манифестами тоже работает через -f ./directory.
Что не умеет: конвертировать аннотации. Структура YAML - да, apiVersion - да, но аннотации nginx.ingress.kubernetes.io/* плагин не трогает - это не его зона ответственности. Поэтому для nginx-специфичных вещей kubectl-convert - только первый шаг, дальше руками.
Также плагин хорошо работает как детектор: если скормить ему манифест с extensions/v1beta1, он честно скажет, что этот apiVersion deprecated и покажет целевую группу. Полезно для аудита репозиториев, где нет доступа к audit log кластера - например, при работе с легаси-репозиториями клиента.
Storage Capacity Tracking: alpha, смотрим
Storage Capacity Tracking в 1.19 появляется как alpha-фича с feature gate StorageCapacityTracking. Суть: CSI-драйвер может публиковать информацию о доступной ёмкости хранилища, и планировщик начинает это учитывать при размещении подов с PVC.
На тестовом кластере включили, посмотрели на поведение с ceph-csi. Объект CSIStorageCapacity появляется в namespace драйвера - там видно, сколько места доступно в каждой storage pool. Планировщик при alpha-статусе использует эти данные, но без гарантий точности: данные могут быть немного устаревшими, и сам feature gate явно помечен нестабильным.
В продакшн это не идёт. Но проблема, которую это решает - поды зависают в Pending, потому что планировщик не знает о нехватке места, и нода выбирается «вслепую» - вполне реальная. Особенно при динамическом provisioning'е больших томов.
Где сейчас
Тестовый кластер на 1.19-rc работает третий день. Проблем с запущенными workload-ами нет, nginx-ingress после переписанных аннотаций ведёт себя нормально. Матрица совместимости, которую готовили в июне, в целом оказалась верной - неожиданностей по helm-чартам не было, только аннотации nginx-ingress потребовали ручного разбора.
Производственный кластер планируем обновить после выхода GA - по текущим срокам август. До этого прогоним staging по той же схеме: сначала 1.18, потом 1.19, с промежуточной проверкой audit log на каждом шаге.
Чек-лист для тех, кто тоже смотрит на этот переход с 1.17:
- kubectl-convert - прогнать все Ingress-манифесты, зафиксировать изменения схемы.
- Аннотации nginx-ingress - проверить отдельно, особенно rewrite-target с regex и ssl-passthrough.
ingressClassNamevs аннотация - если несколько контроллеров, разобраться заранее кто что берёт.- Промежуточная остановка на 1.18 - kubeadm в любом случае заставит, лучше знать об этом до начала.
- Storage Capacity Tracking - не трогать в продакшне, alpha есть alpha.