
Коротко о главномРазвернутьСвернуть
- После обновления Kubernetes старая настройка в манифесте может оказаться несовместимой с новой версией, из-за этого приложение не запустится.
- 37 эти сюрпризы связаны со static Pods, параметрами kubelet и подключением томов.
- Отдельно проверим доступность приложений и управляющего API.
Kubernetes 1.37 вышел 26 августа 2026 года. После обновления Kubernetes старая настройка в манифесте может оказаться несовместимой с новой версией, из-за этого приложение не запустится. В версии 1.37 эти сюрпризы связаны со static Pods, параметрами kubelet и подключением томов.
Отдельно проверим доступность приложений и управляющего API. Если обновление включает перезапуск etcd, выполняющиеся запросы к API server могут зависнуть на это время, даже после drain узла.
Команды проверки и изменения конфигурации разнесены по этапам: сначала собираем сведения, затем готовим приложения и только после этого обновляем компоненты.
Сначала расставим границы обновления
У Kubernetes несколько компонентов с собственными версиями. API server принимает запросы управления, kubelet запускает контейнеры на конкретном узле, а kubeadm помогает собирать и обновлять кластер. Поэтому перед работой нужно установить, какие версии сейчас используются и каким способом создано окружение.
Начните с команды, которая покажет версии клиента kubectl и сервера:
# Показываем версии kubectl и API server выбранного кластера.
kubectl versionВ выводе ищите Client Version и Server Version . Это ещё не инвентаризация всех узлов: версия сервера описывает ту часть системы, к которой обратился клиент. Версии kubelet на всех узлах покажет следующая команда:
# Показываем состояние узлов и установленные версии kubelet.
kubectl get nodesВ столбце VERSION указаны версии kubelet, в STATUS ожидается Ready . Сохраните этот вывод для сравнения после обновления.
Официальный гайд kubeadm рассчитан на переход 1.36.x → 1.37.x. Если кластер старше, подготовьте последовательность промежуточных обновлений. Для EKS, GKE, AKS и других управляемых сервисов понадобится процедура провайдера: команды обслуживания самостоятельно установленного control plane нельзя автоматически переносить в managed-окружение.
Во время перехода разные версии компонентов допустимы в определённых пределах. Например, kubelet не должен быть новее API server. Когда в отказоустойчивом кластере одновременно работают API server 1.36 и 1.37, обновлять kubelet до 1.37 ещё рано. Совместимость должна сохраняться с обоими серверами. Поэтому следуйте порядку действий: сначала управляющие компоненты, потом рабочие узлы.
Зафиксируйте исходное состояние в плане работ. Для каждого этапа укажите узел, целевую версию и проверку, после которой можно продолжать, особенно, если обновление выполняют несколько человек или оно занимает несколько окон обслуживания.
Какие static Pods перестанут запускаться
Обычный Pod создаётся через Kubernetes API. Static Pod запускается kubelet по локальному описанию на узле. Это позволяет поднимать компоненты, которые нужны для работы самого API server. В кластерах kubeadm таким способом запускаются компоненты control plane.
Static Pods изначально не предназначались для чтения объектов API, однако ошибка позволяла некоторым ссылкам на Secrets и ConfigMaps работать. В 1.37 это поведение окончательно запрещено : feature gate PreventStaticPodAPIReferences , позволявший отключить ограничение, удалён. Проблема возникает у Pod с такими ссылками, а не у любого Pod, использующего секрет.
Проверьте каталог, из которого kubelet читает static-манифесты. В конфигурации kubelet его задаёт staticPodPath ; для типового kubeadm-окружения в рассмотренных материалах используется /etc/kubernetes/manifests/ . Если у вас другой путь, проверять нужно именно его.
Особое внимание уделите полям configMapRef , secretRef , configMapKeyRef и secretKeyRef . Найденные ссылки требуют разбора: какой компонент читает значение, почему он запускается как static Pod и как предоставить ему конфигурацию до появления API server. Проверка должна охватывать и шаблоны, из которых вы создаёте новые узлы. В разборе devs group найдёте варианты исправления: предоставить компоненту локальный файл через hostPath или перенести подходящую нагрузку в DaemonSet. Выбор зависит от того, нужен ли компонент для запуска самого control plane.
В официальном руководстве есть ещё одна полезная деталь: kubelet читает файлы static-манифестов независимо от расширения. Если оставить рядом с рабочим файлом копию с окончанием .backup , она тоже может попасть в обработку. Поэтому резервные копии храните вне каталога static Pods. .
Какие параметры помешают запуску kubelet
В 1.37 обновлён встроенный cAdvisor, который собирает статистику контейнеров. Часть его старых флагов больше не принимается. Если они передаются kubelet при запуске, процесс завершается с ошибкой. Среди удалённых параметров есть --containerd , --boot-id-file , --machine-id-file , --global-housekeeping-interval и семейство --storage-driver-* . Из прежних флагов cAdvisor сохранён --housekeeping-interval .
Проверьте, как запускается служба: изучите systemd unit, файл /var/lib/kubelet/kubeadm-flags.env и /etc/default/kubelet . Набор мест зависит от установки: unit может подхватывать параметры из другого файла. Поэтому просмотр одного unit ещё не означает, что все аргументы найдены.
# Показываем unit kubelet и его дополнения.
systemctl cat kubeletВ выводе смотрите, откуда служба получает аргументы и переменные окружения. Сопоставьте найденные параметры с полным списком удалённых флагов в changelog. Название --containerd здесь относится к старому параметру cAdvisor; по нему нельзя делать вывод, что сам runtime containerd требуется удалить.
После изменения конфигурации проверьте перезапуск службы на тестовом узле. Исправление должно попасть и в систему, которая формирует конфигурацию следующих узлов, иначе при расширении кластера проблема вернётся. Это следует из различия между исправлением работающей машины и исправлением шаблона её создания.
Отдельно проверьте панели и правила оповещений, завязанные на cAdvisor. В 1.37 исчезают серии container_cpu_load_average_10s , container_cpu_load_d_average_10s и container_tasks_state . Составьте список зависимых проверок.
Что проверить в SELinux и томах
SELinux использует метки объектов и процессов для контроля доступа. Раньше при подготовке тома runtime мог рекурсивно менять метки файлов и каталогов. Если файлов много, этот обход занимает время. Оптимизированный механизм задаёт контекст при монтировании тома через -o context=<label> .
В Kubernetes 1.37 SELinuxMount включён по умолчанию. При этом механизм применяется при выполнении набора условий: нужен подходящий PVC, известная Kubernetes SELinux-метка и поддержка со стороны драйвера. CSI-драйвер объявляет такую поддержку полем spec.seLinuxMount: true . На узлах без SELinux эти изменения не действуют.
Риск появляется при совместном использовании тома на одном узле. Официальный разбор приводит два сценария: Pods с разными метками используют разные subPath одного тома; либо том разделяют на привилегированный и непривилегированный Pods. При новом способе монтирования один из конфликтующих Pods может остаться в ContainerCreating .
В Kubernetes 1.36 можно заранее проверить такие конфликты с помощью selinux-warning-controller , который работает внутри kube-controller-manager. По умолчанию он отключён. Для проверки включите его через параметр --controllers у kube-controller-manager; в документации приведён пример --controllers=*,selinux-warning-controller .
После включения контроллер сообщает о найденных конфликтах через события и метрику selinux_warning_controller_selinux_volume_conflict . Он проверяет и Pods на разных узлах, поскольку после пересоздания они могут оказаться на одном.
Для приложения, которому нужно прежнее поведение, есть настройка Recursive . Ниже кусок спецификации Pod, который сохраняет рекурсивное применение меток:
У Deployment или StatefulSet этот параметр должен находиться внутри спецификации Pod в шаблоне: spec.template.spec.securityContext . Проверьте итоговый манифест, который действительно получает кластер. Применять исключение ко всем приложениям заранее не нужно: сначала определите затронутые нагрузки и протестируйте выбранное поведение.
Что ещё изменилось в конфигурации
Раздел Urgent Upgrade Notes содержит несколько менее заметных изменений. Их удобно пройти отдельным списком до тестового обновления.
- Удалена версия scheduling.k8s.io/v1alpha2. Changelog требует убрать соответствующие объекты до обновления. Если команда использовала экспериментальные API планировщика, ей нужно разобрать эти объекты и способ их замены.
- Значение eventRecordQPS: 0 теперь означает отсутствие ограничения частоты событий. Чтобы сохранить ограничение, задайте ненулевое значение; в release notes приведён пример 50.
- Kubelet выводит эффективную конфигурацию при запуске. Администраторам предлагают проверить доступ к nodes/logs и ограничить его доверенными пользователями.
В первом случае недостаточно найти старую строку версии в репозитории и заменить её во всех файлах. В плане работ должны быть учтены существующие объекты. Во втором случае привычный ноль меняет поведение после обновления. В третьем нужно проверить права на диагностическую информацию.
Для каждого пункта запишите результат применительно к своему кластеру: используется ли настройка, кто за неё отвечает и что требуется изменить. Если экспериментальные API не включались, это тоже полезный результат проверки. Он объясняет, почему соответствующий шаг исключён из вашей процедуры, и позволяет повторить аудит позднее.
Нужно ли одновременно менять containerd и IPVS
Некоторые обзоры требуют перейти на containerd 2.x перед Kubernetes 1.37. В чейнджлоге удаление части настроек kubelet и связанного с ними резервного поведения перенесено с 1.37 на 1.38 для согласования с поддержкой containerd 1.7. Этот перенос не распространяется на перечисленные выше флаги cAdvisor: они уже удалены в 1.37 и мешают запуску kubelet, если остались в аргументах службы. Совместимость установленного runtime и срок его поддержки нужно проверять отдельно.
С IPVS ситуация тоже требует точной формулировки. В 1.37 этот режим kube-proxy продолжает работать. Официальный анонс указывает ожидаемое отключение по умолчанию в 1.40 и удаление в 1.43. Текущий режим можно посмотреть так:
# Читаем конфигурацию kube-proxy и находим выбранный режим.
kubectl -n kube-system get configmap kube-proxy -o jsonpath='{.data.config\.conf}' | grep 'mode:'Если видите mode: ipvs , добавьте миграцию в план инфраструктурных работ. Сам этот результат ещё не означает, что обновление на 1.37 нужно остановить.
Проверка cgroup v1 относится к совместимости узлов. Отказ kubelet запускаться с cgroup v1 по умолчанию действует с версии 1.35. В 1.37 сохраняется временное переопределение failCgroupV1: false , однако проект рекомендует переходить на cgroup v2.
Для вашей процедуры из этого следует простой подход: зафиксировать обязательные исправления отдельно от запланированных миграций. Если runtime или сеть тоже требуют изменений, выделите им собственные проверки. Тогда при неудачном тесте будет понятнее, какое именно изменение вызвало новое поведение.
Как подготовить тестовое обновление
Тест должен проверять те зависимости, которые есть в продакшене. В перечень для своего окружения включите сеть, подключение хранилищ, правила допуска запросов и мониторинг. Если приложение использует особые настройки безопасности или обновляется как StatefulSet, эти особенности тоже должны попасть в проверку.
Составьте короткий сценарий для каждого важного приложения: что должно запуститься после переноса, к каким данным оно обращается и как вы подтвердите работоспособность. Результат «Pod появился в списке» слишком узок для решения о доступности сервиса. Проверка должна доходить до операции, ради которой приложение запущено.
Отдельно продумайте поведение при выводе узла из работы. PodDisruptionBudget , или PDB, ограничивает допустимое число недоступных реплик при добровольных прерываниях, которые используют Eviction API. Обычный drain учитывает этот бюджет. При нехватке доступных реплик он может ждать, пока приложение восстановится.
Например, в документации разобран случай с тремя репликами и требованием сохранять две доступными. Одну реплику можно остановить для обслуживания узла: Kubernetes создаст ей замену, а две другие продолжат работать. Остановить следующую получится, когда новая реплика будет готова. Если для её запуска не хватает ресурсов, потребуется вернуть в работу обслуженный узел или добавить новый. Поэтому заранее проверьте, хватит ли на остальных узлах ресурсов для запуска Pods на время обновления.
Подготовьте резервные копии состояния приложений и процедуру восстановления. В официальном гайде kubeadm отдельно упомянуты данные уровня приложения, например, базы. В своём плане укажите место хранения копий, ответственного за восстановление и момент, после которого команда прекращает обновление и начинает разбор сбоя.
Если для подготовки нужна внешняя команда, на нашем сайте, Centicore Group есть услуги по развёртыванию ИТ-ландшафта, миграции ИТ-инфраструктуры и поддержке облачных сервисов. Перед обращением соберите сведения о текущем окружении и требованиях приложений: с ними будет проще обсудить объём работ.
В каком порядке обновлять кластер
Начните с первого узла control plane. По официальному гайду на нём обновляют kubeadm до выбранной версии 1.37.x, проверяют план и запускают обновление управляющих компонентов. Пакеты берут из репозитория соответствующей минорной версии.
# Проверяем установленную версию kubeadm.
kubeadm version
# Проверяем готовность к обновлению и доступные версии компонентов.
sudo kubeadm upgrade planИзучите предложенный план. Затем выполните команду обновления, заменив x конкретным номером патча:
# Обновляем первый control plane до выбранного патча 1.37.
sudo kubeadm upgrade apply v1.37.xНа остальных узлах control plane сначала обновите пакет kubeadm, затем выполните sudo kubeadm upgrade node . Повторять kubeadm upgrade plan на каждом узле не требуется. Обновляйте управляющие узлы последовательно. Отдельно проверьте инструкцию установленного сетевого плагина CNI и выполните необходимые шаги его обновления.
Обновление kubelet и kubectl нужно выполнить и на узлах control plane. Для каждого узла предусмотрены drain, установка пакетов, перезапуск kubelet и uncordon. Учитывайте совместимость версий: если kubelet может обращаться к нескольким API server, все они должны быть обновлены до 1.37 перед переходом этого kubelet на 1.37. После обслуживания управляющих узлов переходите к рабочим узлам.
Перед минорным обновлением kubelet узел нужно освободить от обычных рабочих Pods. Команда drain помечает его недоступным для стандартного планирования и запрашивает выселение нагрузок:
# Подставляем имя обслуживаемого узла и выселяем рабочие Pods.
kubectl drain --ignore-daemonsetsДождитесь успешного завершения. Если операция ждёт, сначала выясните причину. PDB может ограничивать выселение, а приложению может требоваться время на восстановление. --ignore-daemonsets позволяет продолжить при наличии Pods DaemonSet, но не удаляет их. Drain также не останавливает static Pods, поэтому управляющие компоненты требуют своей процедуры обслуживания.
После обновления управляющих узлов переходите к рабочим узлам под Linux. На каждом рабочем узле обновите пакет kubeadm, выполните kubeadm upgrade node , проведите drain, затем обновите пакеты kubelet и kubectl до выбранной версии. Команда upgrade node подготавливает локальную конфигурацию kubelet; установку нового пакета нужно выполнить отдельно.
После установки пакетов перезапустите службу:
# Перечитываем конфигурацию служб systemd.
sudo systemctl daemon-reload
# Запускаем kubelet с обновлённым пакетом и конфигурацией.
sudo systemctl restart kubeletКогда закончите проверки узла, разрешите планирование:
# Возвращаем проверенный узел в работу; подставляем его имя.
kubectl uncordonОбновляйте остальные рабочие узлы по очереди. Следите, чтобы на оставшихся узлах хватало ресурсов для работы приложений. В вашей инструкции должны быть записаны конкретные имена узлов и версии пакетов. Все значения в угловых скобках и x в примерах заменяются до запуска.
Что проверить перед следующим узлом
Сначала убедитесь, что kubelet работает и узел вернулся в Ready . Затем проверьте перенесённые приложения по сценарию, подготовленному до обновления. Сравните результат с исходным состоянием: появились ли новые ошибки, подключились ли тома, продолжают ли поступать данные мониторинга.
В отдельную проверку вынесите StatefulSet . В 1.37 функция MaxUnavailableStatefulSet включена по умолчанию. Поле spec.updateStrategy.rollingUpdate.maxUnavailable задаёт, сколько Pods может быть недоступно во время обновления StatefulSet. Значение maxUnavailable по умолчанию равно 1 . Проверяйте его вместе с spec.podManagementPolicy : документация описывает одновременное обновление нескольких Pods для политики Parallel и maxUnavailable больше 1 . При таком сочетании Pods могут становиться готовыми в разном порядке, что подходит не каждому приложению.
Просмотрите существующие стратегии обновления. Если поле уже было задано в манифесте, проверьте, какое поведение оно даёт при включённой функции. Для приложения, где нужен порядок восстановления экземпляров — отдельно тестируйте ускоренный rollout.
При этом PDB и стратегия StatefulSet регулируют разные операции. PDB учитывается при выселении через Eviction API; собственное rolling-обновление контроллера StatefulSet не ограничивается этим бюджетом. Поэтому нормальный drain и rollout приложения должны быть отдельными пунктами проверки.
Лучше заранее сформулировать условие продолжения обычным предложением: «следующий узел обновляем, когда перенесённые нагрузки восстановились и прошли свои проверки». За ним должны стоять конкретные результаты тестов. Если один Pod всё ещё ждёт том или приложение отвечает с ошибкой, переход к следующему узлу только усложнит поиск причины.
Что делать, если обновление остановилось
Разберите, на каком этапе произошёл сбой: при выполнении kubeadm, запуске kubelet или восстановлении приложения. Сохраните вывод команды и журналы проблемной службы. До выяснения причины оставьте остальные узлы на текущем этапе.
Для kubelet начните с проверки состояния и журнала:
# Проверяем состояние службы kubelet.
systemctl status kubelet
# Читаем журнал службы для разбора ошибки запуска.
journalctl -xeu kubeletЕсли проблема в старом аргументе запуска, вернитесь к проверке конфигурации службы. Если kubelet работает, а приложение застряло на подключении тома, продолжайте разбор на уровне Pod и хранения. Так результаты диагностики будут связаны с конкретным этапом обновления.
Официальный гайд допускает повторный запуск kubeadm upgrade , если операция оборвалась и автоматическое восстановление не завершилось. Процедура идемпотентна: повторное выполнение приводит компоненты к заявленному состоянию. Это механизм восстановления незавершённого обновления.
Kubeadm также создаёт каталоги резервных копий в /etc/kubernetes/tmp : kubeadm-backup-etcd-<date>-<time> и kubeadm-backup-manifests-<date>-<time> . Первая копия относится к локальному участнику etcd; при внешнем etcd соответствующий каталог будет пустым. Вторая содержит сохранённые static-манифесты. Используйте их по документированному сценарию для вашей конфигурации.
При обновлении StatefulSet со стратегией RollingUpdate и политикой OrderedReady возможна остановка: Pod с новой конфигурацией не переходит в Ready, и контроллер ждёт его восстановления. Известная проблема проявляется при восстановлении: даже после возврата рабочего шаблона контроллер может продолжать ждать готовности неисправного Pod. После возврата шаблона нужно удалить затронутые Pods с ошибочной конфигурацией, чтобы контроллер пересоздал их. Этот сценарий нужно заранее включить в тест восстановления приложения.
Когда можно переходить в прод
На начало сентября 2026 года последним патчем ветки остаётся 1.37.0. Релиз 1.37.1 запланирован на 15 сентября; дата окончания поддержки ветки указана как 28 октября 2027 года. Перед началом обновления ещё раз проверьте страницу релиза : запланированный патч может ещё не выйти.
Советуем дождаться 1.37.1 или 1.37.2, если нет конкретной причины переходить сразу. Официальная рекомендация Kubernetes — использовать актуальные патчи исходной и целевой минорных версий. Ожидание можно включить в график, продолжая проверку совместимости и подготовку окружения.
Решение о продакшене должно опираться на результаты теста. Команда знает, какие манифесты пришлось исправить, как приложения пережили выселение с узла и где лежат данные для восстановления. После первого обновлённого узла она может объяснить, почему продолжать допустимо.
Если проверка нашла конфликт меток или неподходящую конфигурацию службы, подготовка уже принесла результат: проблема найдена до окна обслуживания. Пофиксите её, повторите затронутый сценарий и внесите исправление в процедуру. Тогда следующее обновление начнётся с накопленных знаний о вашем кластере.


