Kubernetes 1.18: ловим API deprecation warnings через audit log
Kubernetes 1.18 вышел в марте с Topology Manager beta и Server-Side Apply beta. Проверяем кластеры клиентов на совместимость - audit log выдаёт неожиданные сюрпризы.
Kubernetes 1.18 (март 2020): Topology Manager beta, Server-Side Apply beta, API deprecation warnings в ответах, Ingress движется к GA
Kubernetes 1.18 вышел в конце марта, и мы запустили стандартный цикл проверки совместимости для кластеров клиентов в рамках managed-сопровождения. На этот раз зацепило на deprecation warnings в API - не на уровне «работает, но предупреждает», а в виде реальных находок в helm-чартах, которые продолжают слать запросы к уже уходящим группам ресурсов.
Что нового в 1.18
Краткий пробег по тому, что реально заметно в продакшне:
Topology Manager - beta. Управляет привязкой CPU и устройств к NUMA-топологии на узлах с несколькими NUMA-доменами. Для большинства наших кластеров это пока академический интерес - workload-ы общего назначения, не GPU-задачи. Но у одного клиента есть кластер с ML-нагрузками, там тема живая. Флаг --topology-manager-policy раньше был alpha, теперь beta - документация ещё сырая, но feature по крайней мере считается достаточно стабильной для включения.
Server-Side Apply - beta. Kubectl apply начинает делегировать применение манифестов на сторону API-сервера, который сам разруливает конфликты полей между несколькими контроллерами. Пока мы это не включаем принудительно - слишком много мест, где что-то могло бы неожиданно поменять поведение. Флаг присутствует, но применяем осторожно.
API deprecation warnings в ответах. Вот это интересно. Начиная с 1.18 API-сервер стал возвращать заголовок Warning в ответах на запросы к deprecated API-группам. Раньше это было тихое дело: приложение шлёт запрос к extensions/v1beta1, получает ответ, всё работает, никто не жалуется. Теперь в ответе прилетает предупреждение. Kubectl его уже показывает. Это меняет обнаруживаемость проблемы.
Ingress движется к GA. networking.k8s.io/v1 для Ingress приближается - API уже живёт в networking.k8s.io/v1beta1, и extensions/v1beta1 deprecated. До полного удаления далеко, но именно это и обнаружилось в аудите.
Как проверяли: audit log
Предупреждения в kubectl-ответах хорошо для разработчиков, но плохо для аудита уже работающих систем - там руками никто не смотрит. Мы пошли через audit log API-сервера.
У всех managed-кластеров у нас включён audit log с политикой минимум Metadata для core-ресурсов. Для проверки deprecation-обращений сделали запрос к логам за последние две недели - смотрели, какие apiVersion фигурируют в полях requestURI для ресурсов типа Ingress, Deployment, NetworkPolicy:
# Пример фильтра jq по audit log
cat audit.log | jq 'select(.requestURI | test("/apis/extensions/v1beta1/ingresses")) | {user: .user.username, ua: .userAgent, time: .requestReceivedTimestamp}'
Результат оказался поучительным.
Что нашли
Обращений к extensions/v1beta1 для Ingress оказалось больше, чем ожидали. Источники:
- Helm-чарты сторонних приложений. Три разных чарта - nginx-ingress community-версии старше 2020, cert-manager (не самая свежая копия), один кастомный чарт клиента для внутреннего сервиса. Все трое шлют
extensions/v1beta1при деплое. - Flux. Один кластер управляется через Flux v1. При reconcile Flux применяет манифесты из git, а в репозитории лежат Ingress-ы с
extensions/v1beta1. Flux добросовестно шлёт то, что видит в репо. - Prometheus Operator. Старая версия оператора при создании некоторых служебных Ingress-ов тоже использовала extensions-группу.
В случае Deployment-ов extensions/v1beta1 не нашли - это ещё при обновлении на 1.16 разбирали, и тогда почистили.
Как исправляли
Стратегия зависит от источника:
Сторонние helm-чарты - обновили до актуальных версий. nginx-ingress community 0.31.x уже использует networking.k8s.io/v1beta1. cert-manager 0.14 - аналогично. Обновление прошло без сюрпризов.
Кастомный чарт клиента - поменяли apiVersion в шаблоне и протестировали. Одна строка, пять минут, без регрессий.
Flux v1 репозиторий - сделали PR в репозиторий клиента с заменой apiVersion во всех Ingress-манифестах. Flux при следующем reconcile применил обновлённые версии.
Prometheus Operator - тут пришлось обновить оператор, потому что в старой версии apiVersion не конфигурируется - он зашит в Go-код. Обновились до 0.38, проблема ушла.
Работа простая, но её надо было заметить. Без audit log или новых Warning-заголовков от 1.18 - продолжало бы тихо работать до момента, когда extensions-группу уберут совсем.
Topology Manager: быстрый взгляд
Клиент с ML-кластером попросил посмотреть на Topology Manager. Включили --topology-manager-policy=best-effort на одном узле и запустили тестовую нагрузку с GPU-плагином.
Разница в поведении планировщика ощутима: когда политика none (по умолчанию), CPU и GPU могут попасть в разные NUMA-домены, и там возникают задержки на межшинный трафик. С best-effort планировщик делает попытку разместить ресурсы в одном NUMA-домене - если не получается, всё равно запускает, но с предпочтением.
Для продакшна пока не включили - нужно понять, как это взаимодействует с HPA и как ведёт себя при вытеснении подов. Документация beta-фичи описывает механику, но умалчивает об edge-кейсах. Это нормально для beta.
Где сейчас
Кластеры на 1.18 перевели dev и один staging. Производственные - следующий шаг, уже без неожиданностей с deprecation: источники обращений к устаревшим API-группам известны и исправлены. Audit log с фильтром на extensions-группу останется в мониторинге - на случай если что-то новое появится при следующем обновлении чартов.
Server-Side Apply пока наблюдаем со стороны. Topology Manager - на одном production-узле в режиме best-effort, под наблюдением.
- Kubernetes 1.17: переводим production на beta Volume Snapshots · 10 января 2020
- Обновляем AWX до версии 11: новый API, Collections и переписанные Inventories · 14 апреля 2020