Сегодня официально выпустили новую версию Kubernetes — 1.36.
Среди главных фич — новый API для kubelet'а, который работает непосредственно на узле, возможность задавать сигнал остановки контейнера прямо в манифесте без пересборки образа, защита контроллеров от работы с устаревшим кешем, шардирование watch-потока и его фильтрация на стороне API-сервера, групповое планирование подов с учётом топологии, а ещё механизм, позволяющий узнать, когда PVC использовался в последний раз.
Для подготовки статьи мы использовали информацию из блога Kubernetes, таблицы Kubernetes enhancements tracking, CHANGELOG-1.36, а также конкретные issues, pull requests и Kubernetes Enhancement Proposals (KEPs).

Мы разбили все изменения на следующие разделы:
Внутри каждого раздела упорядочили изменения по уровню их готовности к использованию. Всего в новом релизе 68 изменений. Из них:
Alpha — 25 новых функций;
Beta — 25 продолжают улучшаться;
Stable — 18 признаны стабильными.
Примечание
Мы сознательно не переводим названия фич на русский. Они в основном состоят из специальной терминологии, с которой инженеры чаще сталкиваются в оригинальной формулировке.
Узлы
Alpha-фичи
DRA: Device Attributes in Downward API
KEP-5304 добавляет стандартизированный механизм, при котором DRA-драйвер заполняет метаданные устройства, а фреймворк автоматически пробрасывает их внутрь контейнера, монтируя как JSON-файл по известному пути. Теперь не нужно придумывать кастомные контроллеры, которые бы делали то же самое, или напрямую обращаться к Kubernetes API из рабочих нагрузок, чтобы получить нужные сведения.
Чтобы в текущей версии DRA получить информацию о выделенных устройствах (например, узнать PCIe-адреса шины в случае GPU или UUID mediated-устройств), приходится:
читать статус ResourceClaim;
искать соответствующий ResourceSlice;
парсить атрибуты.
Это неудобно. В механизме, предложенном в KEP-5304, DRA-драйвер сам отдаёт метаданные устройства в PrepareResourceClaims, а kubelet записывает их в JSON и монтирует в контейнер по заданному пути. В итоге приложение внутри контейнера просто читает файл вроде /var/run/dra-device-attributes/{claimName}/{requestName}/{driverName}-metadata.json и получает все нужные атрибуты устройства.
KEP: New kubelet gRPC API with endpoint returning local pods information
Сейчас локальным компонентам узла (например, CNI-плагинам или агентам мониторинга) для получения статуса пода (готовность, IP-адрес, лейблы и т. д.), приходится отправлять запрос на API-сервер Kubernetes. Это создаёт ряд проблем:
Надёжность. Если узел теряет связь с управляющим слоем (control plane), то локальные компоненты не могут получить свежую информацию о подах, хотя эта информация есть у kubelet'а, который продолжает работать.
Масштабируемость. Большое количество запросов от агентов на каждом узле создаёт дополнительную нагрузку на API-сервер.
Задержки. Сетевой запрос к API-серверу всегда дольше, чем локальный вызов внутри узла.
Авторы предлагают создать новый gRPC API pods, который будет работать непосредственно на узле. Доступ к нему будет осуществляться через UNIX-сокет /var/lib/kubelet/pods/kubelet.sock (доступ будут иметь только привилегированные процессы). API будет возвращать самую свежую информацию о подах на узле, которая есть у kubelet'а, даже если она ещё не была отправлена на API-сервер. Кроме того, клиенты смогут запрашивать как полную спецификацию и статус пода (PodSpec и PodStatus), так и отдельные поля с помощью google.protobuf.FieldMask.
Новый API включает три основных метода:
ListPods— возвращает список всех подов на узле;GetPod— возвращает информацию о конкретном поде по его UID;WatchPods— отправляет обновления при изменении состояния подов.
CRI List Streaming
Когда kubelet’у нужно получить список контейнеров на узле (например, для сборки мусора), он отправляет CRI-запрос, например ListContainers. Проблема в том, что существующие RPC-вызовы работают в унарном режиме: клиент (kubelet в нашем случае) отправляет один запрос, а сервер (среда исполнения контейнеров) возвращает один ответ с полным списком всех запрошенных объектов. На очень загруженных узлах, где одновременно существуют тысячи контейнеров (например, при большом количестве короткоживущих CronJob'ов), этот список может превысить стандартный лимит gRPC в 16 МБ. Тесты показывают, что это происходит уже при ~11 000 контейнеров или ~14 000 подов.
Чтобы решить проблему без нарушения обратной совместимости, KEP предлагает ввести новые серверные потоковые RPC-вызовы (server-side streaming RPCs). В таком случае среда исполнения не собирает весь список в памяти, а открывает gRPC-поток и отправляет объекты по одному (StreamContainersResponse). Kubelet на своей стороне читает из этого потока сообщения до тех пор, пока поток не закроется (сервер вернёт io.EOF), а специальная функция-обёртка собирает все полученные поочерёдно объекты в один список в памяти, прежде чем передать его для дальнейшей обработки.
DRA: Resource Availability Visibility
Представьте, что вы разработчик и хотите увидеть, какие DRA-ресурсы свободны в кластере, чтобы разобраться, почему под не хочет планироваться из-за insufficient DRA resources. Или вы администратор и хотите понять, сколько GPU доступно в кластере, чтобы распланировать заказ дополнительных мощностей (capacity expansion) (см. пример ниже). Сейчас сделать это непросто по многим причинам:
ResourceSlices— это cluster-scoped-ресурсы, которые показывает общую ёмкость устройств в пуле;ResourceClaimsограничены неймспейсами и отслеживают конкретные выделенные ресурсы;пользователи с ограниченными правами не видят
ResourceClaimsза пределами своего неймспейса;невозможно посмотреть соотношение доступной и выделенной мощности на уровне API.
KEP вводит API ResourcePoolStatusRequest, работающий по шаблону CertificateSigningRequest (CSR):
Пользователь создаёт объект
ResourcePoolStatusRequest, указывая драйвер (обязательно) и опциональный фильтр пула.Контроллер в kube-controller-manager отслеживает появление новых запросов.
Контроллер вычисляет доступность пула и записывает результат в статус.
Пользователь считывает статус, чтобы узнать о доступности пула.
Для обновления пользователь удаляет и заново создаёт запрос.
Пример
Просмотр состояния пула DRA-устройств администратором.
Создайте запрос о статусе всех пулов GPU:
$ kubectl create -f - <<EOF apiVersion: resource.k8s.io/v1alpha1 kind: ResourcePoolStatusRequest metadata: name: check-gpus-$(date +%s) spec: driver: example.com/gpu EOF resourcepoolstatusrequest.resource.k8s.io/check-gpus-1707300000 created
Дождитесь завершения его работы:
$ kubectl wait --for=condition=Complete rpsr/check-gpus-1707300000 --timeout=30s resourcepoolstatusrequest.resource.k8s.io/check-gpus-1707300000 condition met
Просмотрите результаты:
$ kubectl get rpsr/check-gpus-1707300000 -o yaml apiVersion: resource.k8s.io/v1alpha1 kind: ResourcePoolStatusRequest metadata: name: check-gpus-1707300000 spec: driver: example.com/gpu status: observationTime: "2026-02-07T10:30:00Z" pools: - driver: example.com/gpu poolName: node-1 nodeName: node-1 totalDevices: 4 allocatedDevices: 3 availableDevices: 1 - driver: example.com/gpu poolName: node-2 nodeName: node-2 totalDevices: 4 allocatedDevices: 1 availableDevices: 3 conditions: - type: Complete status: "True" reason: CalculationComplete lastTransitionTime: "2026-02-07T10:30:00Z"
Удалите запрос:
$ kubectl delete rpsr/check-gpus-1707300000
Другие примеры см. в разделе User Stories.
Pod Level Resource Managers
KEP-2837 позволил задавать единый бюджет ресурсов (CPU, память) на весь под, а не только на каждый контейнер. Это удобно для подов с Guaranteed QoS, особенно в случае HPC-, AI/ML- и NFV-нагрузок. Но существующие менеджеры ресурсов работают только на уровне отдельных контейнеров и не умеют использовать pod.spec.resources как основу для принятия решений о NUMA-выравнивании (NUMA alignment decisions).
Теперь пользователь может выбрать одну из двух моделей управления ресурсами (обе поддерживают поды с QoS Guaranteed, которые могут содержать смесь контейнеров Guaranteed и non-Guaranteed):
Управление на уровне пода (Pod Scope)
Менеджер топологии закрепит за всем подом единый пул ресурсов с одного NUMA-узла, ориентируясь на pod.spec.resources. Затем менеджеры CPU и памяти выделят из этого пула эксклюзивные сегменты для контейнеров с конкретными Guaranteed-запросами, а оставшаяся часть пойдёт на общий пул для всех остальных контейнеров.
Управление на уровне контейнеров (Container Scope)
Ресурсы будут по-прежнему управляться на уровне отдельных контейнеров, то есть pod.spec.resources будут игнорироваться при принятии решений о размещении.
Зачем это нужно:
Первая модель идеально подходит для рабочих нагрузок, все контейнеры которых желательно размещать на одном NUMA-узле (например, в ML это может быть главный тренировочный контейнер и несколько сайдкаров для таких задач, как приём данных, ведение логов и мониторинг).
Вторая модель даёт возможность независимо управлять контейнерами с разными требованиями к ресурсам в рамках одного Guaranteed-пода. В этом случае Guaranteed-контейнер будет получать эксклюзивные, выровненные по NUMA ресурсы, а non-Guaranteed-контейнеры в том же поде будут работать в общем пуле узла. Раньше было невозможно, чтобы любой из контейнеров мог получить доступ к выровненным по NUMA ресурсам, все контейнеры в поде должны были иметь класс Guaranteed.
Container Stop Signals
Среды исполнения (runtime) контейнеров позволяют задавать STOPSIGNAL, который будет посылаться приложению перед завершением работы. Раньше, чтобы изменить стандартный сигнал SIGTERM, нужно было пересобирать образ контейнера, прописав нужный сигнал прямо в Dockerfile. Это особенно неудобно, когда используются готовые (pre-built) образы.
KEP позволяет указывать STOPSIGNAL прямо в настройках пода. Для этого в секции lifecycle контейнера в спецификации пода появится новое поле stopSignal:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 lifecycle: stopSignal: SIGUSR1
При остановке контейнера kubelet в первую очередь будет смотреть на это поле. Если оно задано, kubelet передаст указанный сигнал (SIGUSR1 в примере) через CRI (Container Runtime Interface) в среду исполнения контейнера, а та — процессу в контейнере.
Новый stopSignal в PodSpec имеет наивысший приоритет и переопределяет STOPSIGNAL, заданный в образе. STOPSIGNAL, который реально был использован, будет отображаться в статусе контейнера.
KEP выходит как альфа-2. В этом релизе добавили несколько метрик (kubelet_pod_stop_signals_count и kubelet_pod_termination_grace_period_exceeded_total), а также механизм кросс-валидации ContainerSpec.Lifecycle.StopSignal и spec.os.name, чтобы обеспечить соответствие STOPSIGNAL операционной системе узла (linux или windows).
Beta-фичи
Pod Level Resources Support With In Place Pod Vertical Scaling
KEP-5419 снимает ограничение на установку запросов и лимитов для вычислительных ресурсов (CPU и память) на уровне всего пода в дополнение к существующим настройкам на уровне контейнеров. Теперь можно менять pod.spec.resources работающего пода без его перезапуска. Кроме того, KEP расширяет объект PodStatus, включая в него аналог полей статуса контейнеров, но уже для всего пода. Это позволяет увидеть, какой объём ресурсов фактически зарезервирован для пода целиком.
DRA: Resource Claim Status with possible standardized network interface data
KEP добавляет новое поле Devices в ResourceClaim.Status. Теперь драйверы могут сообщать данные о состоянии для каждого устройства в заявке на ресурс (resource claim). Это повысит наблюдаемость и облегчит поиск и устранение проблем.
В API добавляется новая структура AllocatedDeviceStatus, которая содержит:
информацию о запросе ресурса;
данные о драйвере;
имя пула устройств;
имя конкретного устройства;
условия (conditions) работы устройства (например, Ready);
сетевую информацию (IP-адреса, MAC-адрес).
Подробности см. в обзоре Kubernetes 1.32.
Add condition for sandbox creation
Перед запуском контейнеров kubelet создаёт песочницу пода. Для этого он координирует работу нескольких компонентов: встроенных плагинов томов (ConfigMap, Secret, EmptyDir), плагинов CSI и среды исполнения контейнеров (включая CNI). После завершения этих задач песочница готова к работе. Новый KEP вводит условие PodReadyToStartContainers в статус пода для отслеживания статуса этой фазы.
Restart all containers on container exits
KEP-5532 развивает и дополняет функциональность, представленную в KEP-5307, распространяя механизм правил restartPolicy на уровень пода. Теперь можно инициировать перезапуск всех контейнеров в поде, а не только сбойного, основываясь на его коде завершения. Пример.
При перезапуске история статусов контейнеров полностью сохраняется, а счётчики перезапусков корректно инкрементируются как для отдельных контейнеров, так и для всего пода. Действие выполняется «по месту»: IP-адрес, sandbox и подключённые тома сохраняются, в то время как все init- и основные контейнеры запускаются с нуля. При этом, если для пода установлен restartPolicy: Never и один из init-контейнеров аварийно завершается после срабатывания RestartAllContainers, весь под будет помечен как Failed.
Node Declared Features (formerly Node Capabilities)
KEP вводит механизм декларируемых функций, благодаря которому узлы смогут сами сообщать о доступных экспериментальных (то есть закрытых переключателями функциональности) фичах в Kubernetes. Это поможет планировщику избежать проблем, связанных с «расползанием» версий (version skew), когда в старых версиях новые фичи могут быть недоступны.
В статусе узла появляется новое поле declaredFeatures, которое заполняет сам kubelet. Планировщик и admission-контроллеры используют его, чтобы запланировать под на узел, который его поддерживает. Подробнее см. в обзоре Kubernetes 1.35.
Add Resource Health Status to the Pod Status for Device Plugin and DRA
KEP вводит новое поле resourceHealth в секцию status спецификации пода. Оно будет содержать информацию о здоровье используемых подом ресурсов, принимая одно из следующих значений: Healthy, Unhealthy или Unknown. Подробнее — в обзоре Kubernetes 1.34.
Stable-фичи
Support User Namespaces in pods
KEP добавляет поддержку пользовательских неймспейсов в stateless-подах. Идея в том, чтобы запускать процессы в подах с другими ID пользователя и ID группы, а не только с унаследованными с хоста. В этом случае привилегированный процесс в поде будет непривилегированным на хосте. Если такой процесс «вырвется» за пределы контейнера, потенциальный вред будет минимизирован, поскольку на хосте его привилегии будут ограничены. Подробнее — в обзоре Kubernetes 1.27.
Support PSI based on cgroupv2
KEP реализует поддержку метрики PSI («давления»), которая показывает, как долго задачи ждут своей очереди для доступа к ресурсам. Если давление высокое, kubelet пометит узел как перегруженный. Планировщик увидит это и перестанет отправлять новые поды на этот узел, пока тот не «придёт в себя» Подробнее — в обзоре Kubernetes 1.33.
Fine grained Kubelet API authorization
KEP повышает гранулярность авторизации для API kubelet’а. Вместо единого разрешения nodes/proxy для всех операций вводятся специальные эндпоинты:
nodes/healthz— для проверки здоровья;nodes/pods— для просмотра подов;nodes/configz— для конфигурации.
Add ProcMount option
KEP добавляет поле procMount в секцию securityContext. Оно позволяет сделать директорию /proc контейнера Unmasked или смонтировать её как доступную для чтения/записи процессом контейнера. Подробнее — в обзоре Kubernetes 1.30.
VolumeSource: OCI Artifact and/or Image
KEP добавляет в Kubernetes новый VolumeSource, поддерживающий OCI-образы и/или OCI-артефакты. Теперь пользователи смогут упаковывать файлы и шарить их в контейнерах пода, не включая в основной образ. Это позволит снизить уязвимости и упростит создание образов. Подробнее — в обзоре Kubernetes 1.31.
Split L3 Cache Topology Awareness in CPU Manager
KEP-5109 развивает идеи, заложенные в KEP-4800 (см. обзор Kubernetes 1.32), добавляя метрики для отслеживания распределения блоков кеша Uncore (он же L3) и топологии процессоров с раздельным Uncore-кешем и монолитным Uncore-кешем для процессоров на базе x86 и ARM и др.
DRA: AdminAccess for ResourceClaims and ResourceClaimTemplates
KEP позволяет администраторам кластера помечать запрос в ResourceClaim или ResourceClaimTemplate флагом доступа администратора. Этот флаг разрешает привилегированный доступ к устройствам и позволяет выполнять административные задачи без ущерба для безопасности (см. обзор Kubernetes 1.33).
Хранилище
Alpha-фичи
Report last used time on a PVC
В кластерах Kubernetes со временем накапливаются PersistentVolumeClaim (PVC), которые больше не используются. Когда приложение удаляется, мигрируется или просто перестаёт работать, связанные с ним PVC часто «зависают» в кластере, продолжая потреблять место, и увеличивают расходы на хранилище.
Сейчас в Kubernetes нет никакого встроенного механизма, который бы показывал, когда PVC использовался в последний раз. KEP-5541 добавляет в статус PVC (PersistentVolumeClaimStatus) новое поле UnusedSince (тип *metav1.Time). Контроллер защиты PVC устанавливает его в:
текущий момент (
metav1.Now), когда последний под, который ссылался на PVC, удаляется или переходит в терминальное состояние;nil, когда новый под начинает ссылаться на этот PVC.
Beta-фичи
CSI Differential Snapshot for Block Volumes
KEP дополняет API CSI механизмом для отслеживания изменённых блоков (Changed Block Tracking, CBT). Это значительно повышает эффективность резервного копирования томов Kubernetes — CSI-драйвер теперь самостоятельно сообщает о том, какие блоки изменились с момента предыдущего снапшота.
Stable-фичи
Speed up recursive SELinux label change
На хостах с SELinux в принудительном режиме (enforcing mode) пользователи одного контейнера не могут получить доступ к другому контейнеру или к хосту. Это обеспечивается за счёт контекста, который уникален для каждого контейнера, и лейблов, которые назначаются каждому файлу в каждом томе.
Однако такая защита может усложнять жизнь пользователям, которые развёртывают кластеры на базе SELinux: при запуске нового контейнера запускается рекурсивное переназначение лейблов для всех файлов в томе, привязанном к поду. Если том большой, процесс переназначения может затянуться.
Новая функция позволяет пропустить этап переназначения лейблов и тем самым ускорить монтирование тома. Подробности — в обзоре Kubernetes 1.25.
Portworx file in-tree to CSI driver migration
KEP мигрирует встроенный в кодовую базу Kubernetes (in-tree) драйвер Portworx в самостоятельный CSI-драйвер. Драйвер вошёл как бета-фича в K8s 1.25, но был по умолчанию выключен. Начиная с Kubernetes 1.31, он был по умолчанию включён. И вот, наконец, он становится GA.
VolumeGroupSnapshot
KEP дополняет API Kubernetes, позволяя снимать согласованные снапшоты сразу с нескольких томов. Для этого вводятся новые CRD VolumeGroupSnapshot, VolumeGroupSnapshotContent и VolumeGroupSnapshotClass. Подробнее — в обзоре Kubernetes 1.27.
Mutable CSINode Allocatable Property
KEP делает поле CSINode.Spec.Drivers[*].Allocatable.Count изменяемым (mutable). Оно задаёт максимальное число томов CSI, которые можно подключить к узлу.
Также добавляются механизмы динамического обновления его значения: kubelet может периодически посылать запросы на эндпоинт NodeGetInfo CSI-драйвера (интервал задаётся в новом поле CSIDriver.Spec.NodeAllocatableUpdatePeriodSeconds) или немедленно реагировать на ошибки нехватки ресурсов (ResourceExhausted) при попытке подключения тома, обновляя значение в CSINode.
Remove gitRepo volume driver
CVE-2024-10220 показал, что тома gitRepo можно использовать для удалённого выполнения кода с root-правами. KEP устраняет вектор потенциальной RCE-атаки, который возник из-за того, что драйвер томов gitRepo давно не обновляется.
Пока не предполагается удалять gitVolumes из API Kubernetes — поды с томами gitRepo будут приниматься kube-apiserver’ом, но kubelet’ы, у которых переключатель функциональности GitRepoVolumeDriver установлен в false, не будут их запускать, выдавая соответствующую ошибку.
CSI driver opt-in for service account tokens via secrets field
KEP вводит новый, более безопасный способ передачи токенов сервисных аккаунтов драйверам CSI. В настоящее время такие токены передаются через поле volume_context в NodePublishVolumeRequest. Ключевая проблема состоит в том, что volume_context не предназначено для хранения конфиденциальной информации, что небезопасно (см., например, уязвимости CVE-2023-2878 и CVE-2024-3744, когда токены случайно попали в логи).
Новый механизм позволяет драйверам CSI явно запрашивать токены через специальное поле secrets, предназначенное для хранения конфиденциальных данных. Спецификация ресурса CSIDriver получает новое поле serviceAccountTokenInSecrets. Если оно установлено в false (поведение по умолчанию), токены продолжают отправляться через volume_context, что обеспечивает полную обратную совместимость с существующими драйверами. Если оно установлено в true, токены будут передаваться исключительно через поле secrets.
Сеть
Beta-фичи
Relaxed validation for Services names
Раньше к названиям сервисов в Kubernetes предъявлялись более строгие правила (RFC 1035), чем к большинству других ресурсов Kubernetes (RFC 1123). KEP-5311 ослабляет правила валидации для имён объектов типа Service и приводит их в соответствие с правилами для других ресурсов.
IP/CIDR validation improvements
KEP-4858 меняет механизм валидация IP-адресов и CIDR-строк в конфигурациях Kubernetes. Подробнее — в обзоре Kubernetes 1.33.
Stable-фичи
DRA: Extend PodResources to include resources from Dynamic Resource Allocation
KEP дополняет существующий сервис gRPC PodResources полем DynamicResource с информацией о классе DRA-ресурса, его ресурсных claim’ах и списке устройств CDI, распределённых драйвером DRA (см. обзор Kubernetes 1.27).
API
Alpha-фичи
Stale Controller Mitigation
Контроллеры Kubernetes (например, kube-controller-manager) работают в цикле согласования (reconciliation loop): постоянно сравнивают желаемое состояние кластера с фактическим и синхронизируют их.
Чтобы не перегружать API-сервер запросами, контроллеры используют локальную копию состояния кластера (cache). Этот кеш обновляется через подписку (watch) на изменения в API-сервере. Процесс «в конечном счёте согласованный» (eventually consistent), то есть рано или поздно изменения доходят до кеша контроллера. Проблема в том, что никто не знает, сколько времени это займёт — миллисекунды или минуты.
Особенно остро проблема стоит в больших и нагруженных кластерах. Контроллер может выполнить действие (например, создать под), а в следующую секунду получить запрос на согласование того же объекта. Но если кеш ещё не обновился, контроллер «не увидит» только что созданный под и может попытаться создать его снова — или выполнить другое некорректное действие.
KEP-5647 состоит из двух основных частей:
Изменения в informer'ах. Добавляется функция BookmarkFunc, единственная задача которой — информировать подписчиков (listeners) о том, что произошло обновление. Вкупе с остальными функциями (Add, Update и Delete) это позволяет контроллеру иметь представление о «свежести» своего кеша.
Логика в контроллерах. Чтобы контроллер мог использовать этот механизм, его логику необходимо модифицировать. После успешной операции записи (например, CREATE или UPDATE) в его памяти сохраняется resourceVersion измененного объекта. Перед началом следующего цикла согласования для этого объекта контроллер проверяет, «видел» ли его informer события с таким же или более новым resourceVersion?
Если да — кеш актуален, можно продолжать.
Если нет — кеш отстал, контроллер возвращает объект в очередь (
requeue) и повторяет попытку позже с экспоненциальной задержкой (exponential backoff), чтобы не создавать лишнюю нагрузку.
Graceful Leader Transition
В высокодоступных кластерах ключевые компоненты управляющей плоскости (kube-controller-manager, kube-scheduler) работают в нескольких репликах и выбирают лидера (leader election), чтобы избежать конфликтов.
Проблема старого механизма: при потере лидерства компонент немедленно завершал работу через os.Exit(). Kubelet видел остановку процесса и перезапускал его. Это приводило к избыточному потреблению ресурсов, а сам компонент не мог завершить работу корректно (graceful shutdown).
Решение: KEP-5366 вводит механизм передачи лидерства без полного перезапуска процесса. Реализация разделена на три этапа.
Первый предусматривает рефакторинг кода контроллеров, чтобы гарантировать корректное завершение работы их внутренних процессов (горутин). Это является необходимым условием, чтобы избежать утечек ресурсов при многократной смене ролей без перезапуска.
Второй этап — оптимизация процесса освобождения «аренды» (Lease) лидерства. Уходящий лидер теперь активно снимает блокировку, а не ждёт окончания периода TTL, тем самым ускоряя процесс выбора нового лидера. Эта фича контролируется флагом ControllerManagerReleaseLeaderElectionLockOnExit.
Наконец, третий этап (включается флагом GracefulLeaderTransition) меняет основную логику работы компонента. При потере лидерства он теперь не завершает работу по os.Exit(), а переходит в фолловеры и снова пытается стать лидером.
Server-side Sharded List and Watch
Контроллеры Kubernetes постоянно следят за состоянием ресурсов (подов, сервисов и т. д.) через механизмы LIST и WATCH. С ростом кластера возникает проблема масштабирования: обычно контроллеры масштабируются вертикально, потому что не умеют шардировать watch-поток.
Некоторые специализированные контроллеры (state-metrics) реализовали собственный горизонтальный шардинг на стороне клиента. Проблема в том, что в этом случае каждая реплика получает полный поток всех событий для отслеживаемого ресурса. Затем она выполняет десериализацию данных, отбрасывая те из них, которые не принадлежат к её шарду, то есть, по сути, выполняет ненужную работу. Это создаёт лишнюю нагрузку на сеть и впустую тратит ресурсы процессора.
KEP-5866 переносит логику фильтрации на API-сервер. Для этого вводится новый параметр shardSelector, который позволяет клиентам подписываться на конкретный шард данных. В параметре определяется диапазон хешей, которые нужны клиенту. Например, клиент может сделать запрос следующего вида:
GET /api/v1/pods?watch=true&shardSelector=shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')
В этом случае API-сервер с помощью быстрого алгоритма FNV-1a будет вычислять хеш для каждого объекта (пода) от его уникального идентификатора (metadata.uid). Если хеш попадает в указанный диапазон (в примере от 0x00… до 0x80…), то событие, связанное с этим объектом, будет отправляться клиенту. Таким образом, каждая реплика может подписаться на уникальный диапазон хешей и получать непересекающиеся наборы данных.
Manifest Based Admission Control Config
KEP-5793 решает старую проблему уязвимости Kubernetes при запуске. Обычно все правила проверки запросов, такие как admission-вебхуки (MutatingAdmissionWebhook и ValidatingAdmissionWebhook) и политики доступа, живут внутри самого кластера как обычные API-объекты. Из-за этого возникает опасное окно: когда сервер только стартует (или если отваливается etcd), запросы уже могут проходить, а защитные правила ещё не загрузились. Кроме того, любой пользователь с высокими правами может случайно или намеренно удалить эти admission-политики через сеть. KEP-5793 реализует механизм настройки политик безопасности на основе локальных манифестов, которые хранятся на диске управляющего сервера. Эти манифесты считываются и применяются до того, как начнут приниматься сетевые подключения.
Сервер API непрерывно следит за локальной директорией с манифестами. При изменении файла на диске Kubernetes сразу подхватывает изменения, валидирует их и применяет без перезагрузки компонентов. Если валидация завершается ошибкой, сервер отбрасывает новый манифест, записывает предупреждение в лог и откатывается к последней удачной конфигурации.
Beta-фичи
Move Storage Version Migrator in-tree
KEP облегчает выполнение миграций хранилищ, делая процесс более автоматизированным и простым. Для этого:
существующая логика контроллера SVM переносится в in-tree менеджера контроллеров Kubernetes;
существующие API SVM REST также переносятся в in-tree.
В бета-версии функция включена по умолчанию. Кроме того, добавлены обработка непредвиденных событий (например, прерванных миграций) и проверка поддержки Create/Update объектами API. Подробнее см. в обзоре Kubernetes 1.30.
KEP повторно выходит как beta. Из ключевых изменений — добавлен механизм удаления старых версий CRD по завершении миграции.
Перед началом миграции в поле status.storedVersions для CRD указываются текущая версия ресурса и любые старые версии, которые ещё могут использоваться. По завершении миграции это поле обновляется: в нём остаётся только новая версия, а предыдущие удаляются.
Перед запуском миграции контроллер устанавливает поле status.conditions CRD в Running. Он также фиксирует текущее поколение (generation) CRD в поле conditions.observedGeneration. После завершения миграции status.conditions устанавливается в Completed, а контроллер обновляет status.storedVersions, оставляя в нём только актуальную версию storage и удаляя старые. Но это случается только при условии, что generation у CRD в ходе миграции не менялся.
Удаление выполняется по принципу best-effort (без жёстких гарантий) — контроллер не будет трогать CRD, если его generation изменился. Это предотвращает удаление предыдущих версий CRD контроллером, если ресурс был изменён в процессе миграции, поскольку невозможно определить, были ли эти версии добавлены во время миграции.
Transition from SPDY to WebSockets
KEP переводит kubectl exec, kubectl attach и kubectl cp в части взаимодействия между kubectl и сервером API с протокола SPDY/3.1 на WebSockets. Подробнее — в обзоре Kubernetes 1.29.
Declarative Validation Of Kubernetes Native Types With validation-gen
KEP вводит механизм декларативной валидации для нативных API-типов Kubernetes, позволяя разработчикам определять правила проверки полей (например, минимальное значение, обязательность) с помощью специальных IDL-тегов прямо в файлах types.go (см. пример в обзоре Kubernetes 1.33). Новый инструмент validation-gen будет автоматически генерировать Go-код для валидации.
Stable-фичи
Mutating Admission Policies
KEP развивает идеи, заложенные в KEP-3488 (см. обзор K8s 1.26), и добавляет новый механизм для изменения (мутации) объектов перед их сохранением в etcd — Mutating Admission Policies, основанные на CEL (Common Expression Language). Они станут альтернативой Mutating Admission Webhooks, которые сейчас являются основным способом выполнения мутаций.
Remove gogo protobuf dependency for Kubernetes API types
KEP описывает процесс удаления зависимости от gogo/protobuf из кодовой базы Kubernetes и её замены на официальную библиотеку от Google — google.golang.org/protobuf.
Аутентификация и авторизация
Beta-фичи
Constrained Impersonation
Исторически механизм имперсонации в Kubernetes не обладал достаточной гранулярностью. Если пользователь или сервисный аккаунт получал право на имперсонацию другого пользователя (например, someUser), ему предоставлялись абсолютно все привилегии этого пользователя. Такой подход нарушал принцип наименьших привилегий и создавал серьёзные риски для безопасности.
KEP-5284 вводит концепцию так называемой ограниченной имперсонации (constrained impersonation), а также два новых префикса для действий (verbs):
impersonate:<mode>:— для имперсонации субъекта определённого типа (пользователя, сервисного аккаунта и т. д.);impersonate-on:<mode>:<verb>:— для выполнения конкретного действия над ресурсом.
Теперь для выполнения действия от имени другого пользователя субъект, выполняющий имперсонацию, должен обладать:
разрешением на ограниченную имперсонацию целевого пользователя (это разрешение действует в пределах всего кластера);
явным разрешением на выполнение конкретного действия, определяемого глаголом API (например, list). Оно может действовать как в пределах кластера, так и в пределах неймспейса.
Pod Certificates
KEP-4317 позволяет нативно доставлять сертификаты X.509 в рабочие нагрузки кластера. Проблема была в том, что, хотя API certificates.k8s.io и даёт гибкий способ запрашивать сертификаты, их доставкой и управлением внутри подов приходилось заниматься разработчикам и администраторам.
Теперь под может напрямую запросить сертификат у конкретного издателя, включив в запрос всю информацию о себе. Пример смотрите в обзоре Kubernetes 1.34.
Stable-фичи
API for external signing of Service Account tokens
Для аутентификации сервисных аккаунтов используются ключи. Сейчас за их хранение и управление ими отвечает Kubernetes. KEP 740 позволяет внешним специализированным системам, например HSMs и облачным KMS, делать то же самое. Подробнее — в обзоре Kubernetes 1.32.
CLI
Beta-фичи
Separate kubectl user preferences from cluster configs
KEP вводит новый опциональный конфигурационный файл kuberc для хранения пользовательских настроек kubectl, отделяя их от данных для подключения к кластерам, которые остаются в kubeconfig. Это позволяет избежать перезаписи настроек при смене kubeconfig. Теперь пользовательские настройки будут применяться независимо от значения флага --kubeconfig или переменной окружения $KUBECONFIG.
Планировщик
Alpha-фичи
Gang Scheduling Support in Kubernetes
Kubernetes широко применяется для AI-, ML- и HPC-задач, где требуется одновременный запуск множества процессов. Стандартный планировщик Kubernetes обрабатывает поды поочерёдно, последовательно распределяя их по узлам. Когда ресурсов мало, возникает риск, что не все воркеры, необходимые для выполнения задачи, будут запланированы. Например, если кластер может принять только пять из десяти требуемых воркеров, они займут узлы и будут блокировать ресурсы в ожидании остальных. Результат — взаимные блокировки и неэффективное использование ресурсов.
KEP решает эту проблему с помощью так называемого группового планирования (gang scheduling). Оно обеспечивает соблюдение принципа «Всё или ничего» (All-or-Nothing): группа подов (gang) планируется на узлы только в том случае, если ресурсы есть для всех её членов (или для минимально необходимого кворума, определяемого параметром minCount).
KEP повторно выходит как альфа. В этом релизе:
добавлен Workload Scheduling Cycle. Этот механизм планирует все поды из одной
PodGroupодним пакетом, а не по одиночке, как при традиционном подходе «под-за-подом»;добавлен переключатель функциональности
DelayedPreemptionдля активации соответствующего механизма, который позволит избежать лишних вытеснений;в Workload API добавлена декларативная валидация;
добавлены тесты производительности;
введены новые базовые типы
WorkloadиPodGroup, которые позволяют сообщить планировщику о том, что группа подов должна планироваться вместе, а также определить параметры группового планирования.
Workload-aware preemption
Как известно, планировщик в Kubernetes может инициировать вытеснение (preemption) — принудительное удаление одного или нескольких подов с низким приоритетом, — когда в кластере не хватает ресурсов для планирования пода с высоким приоритетом. Проблема текущего механизма в том, что он работает на уровне отдельных подов. Однако рабочие нагрузки, особенно в сфере AI/ML и высокопроизводительных вычислений (HPC), часто состоят из группы тесно связанных подов (например, для распределённого обучения модели). При вытеснении даже одного пода из такой группы вся группа перестаёт работать и впустую потребляет ресурсы, ожидая, пока вытесненный под вернётся в строй.
KEP-5710 вводит концепцию «информированного вытеснения» (workload-aware preemption). Теперь группы взаимосвязанных подов (PodGroup) будут рассматриваться как единое целое не только при планировании, но и при вытеснении. Вместо того чтобы вытеснять поды по одному, планировщик будет оценивать, можно ли освободить ресурсы для всей группы высокоприоритетных подов, вытеснив одну или несколько низкоприоритетных групп целиком.
В GangSchedulingPolicy вводится дополнительное поле DisruptionMode, которое определяет, допустимо ли вытеснять поды по отдельности (значение=Pod) или необходимо вытеснять всю группу целиком (значение=PodGroup). Кроме того, в PodGroupSpec добавляется поле PriorityClassName. Оно устанавливает приоритет для группы — именно он будет использоваться при принятии решений о планировании и вытеснении. Приоритет группы имеет преимущество над приоритетами отдельных подов в этой группе.
Этот KEP базируется на нововведениях, представленных в KEP-4671: Gang Scheduling support in Kubernetes (см. выше).
KEP-5732: Topology-aware workload scheduling
KEP развивает логику двух предыдущих предложений. Классический планировщик Kubernetes принимает решения о размещении для каждого пода индивидуально. Для групп взаимосвязанных подов это не всегда оптимально — для сокращения задержек разумно планировать их на один и тот же узел или на узлы, расположенные близко друг к другу.
KEP-5732 позволяет планировщику принимать решения с учётом топологии (topology-aware). Теперь для группы подов можно указать, что их следует разместить вместе в пределах определённого «топологического домена», связанного общим лейблом (например, topology.kubernetes.io/rack).
DRA: List Types for Attributes
KEP-5491 расширяет API Dynamic Resource Allocation для работы со сложными аппаратными топологиями. Раньше атрибуты устройств в ResourceSlice поддерживали только скалярные значения (строка, число, булево значение). Это не позволяло описывать устройства с множественными подключениями, например CPU, доступный через несколько шин PCIe.
Теперь драйверы могут передавать атрибуты в виде списков строк, чисел или версий. Изменилась и логика обработки запросов на ресурсы в ResourceClaim:
для
matchAttributeтеперь достаточно непустого пересечения списков значений вместо точного соответствия (то есть списки должны иметь хотя один общий элемент);для
distinctAttributeтеперь требуется попарная непересекаемость списков вместо уникальности каждого значения.
Пример
Предположим, что есть несколько драйверов DRA с атрибутом устройства resource.kubernetes.io/pcieRoot:
apiVersion: resource.k8s.io/v1 kind: ResourceSlice metadata: name: cpu spec: driver: "cpu.example.com" pool: name: "cpu" resourceSliceCount: 1 nodeName: node-1 devices: - name: "cpu-0" attributes: resource.kubernetes.io/pcieRoot: list: string: - pci0000:01 - pci0000:02 - name: "cpu-1" attributes: resource.kubernetes.io/pcieRoot: list: string: - pci0000:03 - pci0000:04 --- apiVersion: resource.k8s.io/v1 kind: ResourceSlice metadata: name: gpu spec: driver: "gpu.example.com" pool: name: "gpu" resourceSliceCount: 1 nodeName: node-1 devices: - name: "gpu-0" attributes: # Assume this driver is a bit old that keeps exposing string for the attribute resource.kubernetes.io/pcieRoot: string: pci0000:01 --- apiVersion: resource.k8s.io/v1 kind: ResourceSlice metadata: name: nic spec: driver: "nic.example.com" pool: name: "nic" resourceSliceCount: 1 nodeName: node-1 devices: - name: "nic-0" attributes: # Assume this driver is a bit old that keeps exposing string for the attribute resource.kubernetes.io/pcieRoot: string: pci0000:01
KEP-5491 позволяет задать ресурс ResourceClaim, который запрашивает CPU, GPU и NIC, выровненные по топологии PCIe:
apiVersion: resource.k8s.io/v1 kind: ResourceClaim spec: requests: - name: "gpu" exactly: deviceClassName: gpu.example.com count: 1 - name: "nic" exactly: deviceClassName: nic.example.com count: 1 - name: "cpu" exactly: deviceClassName: cpu.example.com count: 2 constraints: # "gpu-0", "nic-0" и "cpu-0" подходят, # поскольку у них есть общий атрибут # — "pci0000:01". # В этом случае набор значений обрабатывается так же, как раньше одиночные. - requests: ["gpu", "nic", "cpu"] matchAttribute: k8s.io/pcieRoot
DRA: ResourceClaim Support for Workloads
Механизм Dynamic Resource Allocation (DRA) позволяет работать со специфическими ресурсами, такими как GPU, FPGA или специализированное сетевое оборудование. Для доступа пода к такому ресурсу необходимо было создать соответствующую заявку (ResourceClaim). Проблема в том, что в случае, когда несколько подов использовали ресурс совместно, такие заявки создавались исключительно последовательно, а общее число подов было ограничено 256 (список в поле status.reservedFor объекта ResourceClaim).
KEP-5729 предлагает решение: ResourceClaim распространяется на уровень PodGroup. PodGroup — это логическое объединение подов, выполняющих общую задачу. Теперь можно создать одну заявку на ресурс для всей группы, и все поды внутри этой группы смогут его использовать. Кроме того, поды из одной PodGroup смогут ссылаться на ресурс не по прямому имени, а по имени, определённому внутри группы (PodGroupResourceClaim). В результате поды, создаваемые динамически, получат доступ к общему, автоматически созданному для их группы ресурсу, имя которого не было известно заранее.
DRA: Node Allocatable Resources (Native Resource Requests)
С появлением DRA в Kubernetes возникло два независимых механизма учёта ресурсов. Проблема в том, что оба механизма управляют одними и теми же базовыми ресурсами, что чревато двумя проблемами.
Двойное предложение. Доступная ёмкость узла по CPU/памяти хранится в двух разных местах:
в поле
Node.Status.Allocatablekubelet'а;в объектах
ResourceSliceдрайвера DRA.
Двойное потребление. Поды могут получить доступ к этим ресурсам двумя разными способами:
через запрос в спецификации пода (поля
spec.containers[].resources.requestsиpod.spec.initcontainers[].resources.requests) — его при поиске подходящего узла учитывает плагин планировщикаNodeResourcesFit;через заявку на ресурс в
ResourceClaim— её принимает во внимание плагин планировщикаDynamicResourcesпри выделении устройств.
KEP-5517 интегрирует DRA-ресурсы со стандартным механизмом отслеживания ресурсов планировщика, обеспечивая согласованный учёт ресурсов и предотвращая перегрузку узлов.
Пример
Некая рабочая ML-нагрузка запрашивает GPU через ResourceClaim. Конкретная модель GPU также требует определённого количества процессоров (CPU) и страниц HugePages, чтобы приложение могло работать с ускорителем. Раньше пользователь должен был знать об этих дополнительных запросах на CPU и HugePages и учитывать их в PodSpec. Теперь же устройство GPU можно настроить так, чтобы оно само объявляло эти зависимости. При размещении пода планировщик учтёт как потребности GPU в CPU и HugePages, так и обычные запросы из PodSpec.
WAS: Decouple PodGroup API
В Kubernetes для задач, требующих совместного запуска нескольких подов, используется механизм gang scheduling. Он гарантирует, что все поды из группы будут запланированы одновременно.
Проблема: изначально логика gang scheduling была тесно связана с конкретной реализацией API под названием PodGroup. Этот API был частью другого объекта, Workload, что создавало ряд проблем:
Другие проекты в экосистеме Kubernetes, которым тоже нужно групповое планирование (например, Kueue или JobSet), были вынуждены использовать именно этот конкретный PodGroup API. Они не могли использовать свои собственные объекты (CRD) для описания групп.
Обновление статуса одной небольшой группы подов требовало чтения и записи всего объекта Workload, что приводило к проблемам с производительностью и конкуренцией при большом количестве групп.
KEP-5832 отвязывает PodGroup от Workload. PodGroup становится самостоятельным объектом в Kubernetes, а Workload выполняет роль статического шаблона, который определяет общую политику и структуру для создания групп.
Контроллеры более высокого уровня (Job, JobSet, LeaderWorkerSet) теперь автоматически создают экземпляры PodGroup на основе шаблона из Workload, а затем и сами поды, которые ссылаются на этот PodGroup.
Спецификация подов включает прямое указание на имя PodGroup (spec.schedulingGroup.podGroupName), позволяя планировщику идентифицировать принадлежность пода к группе. Сам планировщик больше не следит за объектами Workload, а напрямую работает с потоком объектов PodGroup.
Beta-фичи
DRA: Device Binding Conditions
Стандартный планировщик Kubernetes предполагает, что все ресурсы на узле доступны в момент привязки пода. Однако это не всегда справедливо для таких устройств, как GPU с подключением через коммутируемую матрицу (fabric-attached), которым нужно динамическое присоединение по PCIe или CXL, и FPGA, требующих затратного по времени перепрограммирования перед использованием. Преждевременная привязка пода к узлу до того, как такое устройство будет полностью готово, приводит к сбоям при запуске пода и требует ручного вмешательства.
KEP решает эту проблему, позволяя планировщику откладывать финальную привязку пода (фаза PreBind) до тех пор, пока внешний контроллер не подтвердит готовность необходимого ресурса. Это делает процесс планирования более предсказуемым и надёжным (подробнее).
DRA: Partitionable Devices
С развитием DRA от «классического» до «структурированных параметров» возможность динамического разбиения устройств на партиции была утрачена. KEP возвращает эту возможность в рамки «структурированных параметров». Кроме того, он предоставляет примитивы для представления как полных устройств, так и их партиций более компактным способом, чем это возможно сегодня (подробнее).
DRA: device taints and tolerations
В DRA драйверы публикуют информацию об устройствах, которыми управляют, в ResourceSlice. Эта информация используется планировщиком при выборе устройств под нужды пользователей в ResourceClaim.
KEP позволяет драйверам DRA навешивать taints (ограничения) на устройства — в этом случае новые поды на них не будут планироваться. Кроме того, поды, которые уже работают на устройствах с taint, могут быть автоматически остановлены. Администраторы кластера могут навешивать taint’ы с помощью ResourceSlicePatch.
Также в ResourceClaim можно добавлять tolerations (допуски) для определённых taint’ов.
DRA: Handle extended resource requests via DRA Driver
KEP-5004 перебрасывает мост между привычными расширенными ресурсами (Extended Resources) и новым, более гибким фреймворком Dynamic Resource Allocation (DRA). Его главная цель — сделать переход на DRA плавным и безболезненным.
Администратор кластера теперь может указать в спецификации DeviceClass новое поле extendedResourceName, присвоив ему имя знакомого расширенного ресурса, например example.com/gpu. Так Kubernetes поймёт, что запросы на данный ресурс могут быть удовлетворены с помощью устройств, управляемых через DRA. Подробности см. в обзоре K8s 1.34.
Opportunistic batching
Новый механизм пакетирования (batching) нацелен на существенное сокращение затрат ресурсов на планирование подов в крупных кластерах или для больших задач (Jobs). По сути, планировщик теперь может повторно использовать принятые решения о планировании одного пода для других подов с такой же сигнатурой. Для этого авторы KEP вводят понятие «сигнатуры планирования пода» (Pod scheduling signature), которая представляет собой сводку требований пода для его размещения на узле. Подробнее — в обзоре Kubernetes 1.35.
DRA: Consumable Capacity
Ранее можно было совместно использовать устройства только в том случае, если несколько подов или контейнеров ссылались на один и тот же ResourceClaim, который уже выделил это устройство. KEP-5075 позволяет независимым запросам ResourceClaim претендовать на доли одного и того же устройства. Теперь никак не связанные поды (даже из разных неймспейсов) могут использовать ресурсы совместно.
Новый механизм позволяет устройству объявлять, что оно допускает множественное распределение. Для этого служит поле allowMultipleAllocations в разделе devices ResourceSlice. Кроме того, пользователи теперь могут запросить определённую «ёмкость» от такого делимого устройства с помощью нового поля CapacityRequests в ResourceClaim (пример).
Stable-фичи
DRA: Prioritized Alternatives in Device Requests
KEP-4381 «Динамическое распределение ресурсов с помощью структурированных параметров» (см. обзор Kubernetes 1.30) позволил запрашивать специфические типы ресурсов с помощью ResourceClaim. Однако текущая реализация API не позволяет пользователю задавать приоритеты, если потребностям рабочей нагрузки удовлетворяют несколько типов или конфигураций устройств.
KEP-4816 решает эту проблему: теперь можно указать несколько вариантов запросов на динамические ресурсы (например, разные типы GPU) в виде упорядоченного списка. Планировщик попытается удовлетворить эти запросы по очереди, начиная с самого предпочтительного. Подробнее — в обзоре Kubernetes 1.33.
Приложения
Alpha-фичи
WAS: Integrate Workload APIs with Job controller
Стандартный контроллер Job в Kubernetes запускает поды без гарантии одновременного старта. Для распределённых вычислений (AI/ML, MPI), где все узлы должны работать синхронно, это становится проблемой.
KEP-5547 дополняет контроллер Job. Теперь тот нативно поддерживает групповое планирование через API Workload и PodGroup. Когда создаётся задача, соответствующая определённым критериям (в альфа-версии это Job с parallelism > 1 completionMode: Indexed и parallelism = completions), контроллер автоматически:
создаёт объект
Workload, который описывает политику планирования для группы подов. В нём указываетсяgang.minCount, равное значениюparallelismиз Job;создаёт объект
PodGroupна основе шаблона изWorkload;при создании подов, относящихся к задаче, добавляет в их спецификацию поле
schedulingGroup.podGroupName, которое привязывает поды к соответствующейPodGroup.
Планировщик видит, что поды принадлежат к PodGroup, поэтому ждёт возможности разместить сразу все поды, указанные в minCount (минимальное необходимое количество для запуска рабочей нагрузки).
Beta-фичи
Mutable Container Resources when Job is suspended
Часто потребности в ресурсах для пакетных рабочих нагрузок (batch workloads) в Kubernetes неизвестны в момент их создания и зависят от доступной ёмкости кластера. KEP-5440 оптимизирует утилизацию ресурсов в кластере, предоставляя способ изменять запросы и лимиты ресурсов для приостановленных заданий. Так их можно запускать с конфигурациями, соответствующими реальным условиям в кластере. Подробнее — в обзоре Kubernetes 1.35.
Разное
Alpha-фичи
Support scaling to/from zero pods for object/external metrics
Ранее контроллер горизонтального масштабирования Horizontal Pod Autoscaler в Kubernetes не мог уменьшать число реплик приложения до нуля, поскольку решения о масштабировании принимались на основе метрик работающих подов, таких как загрузка CPU или потребление памяти.
KEP вводит поддержку внешних и объектных метрик. HPA теперь может ориентироваться на показатели извне, например на длину очереди сообщений. Когда задач нет, он может сократить число подов приложения до нуля (то есть полностью остановить его). Своё действие HPA сохраняет в специальном статусе ScaledToZero. Он нужен, чтобы случайно не запустить приложение в том случае, когда администратор отмасштабировал его в нуль вручную, установив replicas: 0. При появлении нового сигнала извне (например, сообщения в очереди) HPA инициирует запуск первой реплики.
Integrate CSI Volume attach limits with cluster autoscaler
KEP-5030 вносит изменения в Cluster Autoscaler (CAS) и планировщик Kubernetes. Теперь CAS учитывает лимиты томов при симуляции масштабирования. Он создаёт «шаблон» для нового узла, который включает информацию о лимитах. Эта информация получается либо от существующего узла в той же группе (если узлы уже есть), либо напрямую от облачного провайдера, если группа масштабируется с нуля.
В свою очередь, планировщик интерпретирует отсутствие информации от драйвера CSI на узле как нулевой лимит на подключение томов для этого драйвера. Это предотвращает размещение подов на узлах, которые ещё не готовы к работе с их томами.
KEP повторно выходит как альфа.
CCM: watch-based route controller reconciliation using informers
Контроллер маршрутов в Kubernetes по умолчанию выполняет сверку (reconciliation) каждые 10 секунд, проверяя все узлы и все маршруты у облачного провайдера, чтобы убедиться в их соответствии желаемому состоянию. Это создаёт постоянную и часто избыточную нагрузку на API облачного провайдера.
Авторы KEP предлагают перейти на модель, основанную на отслеживании событий (watch-based), где сверка запускается событиями, связанными с узлами: добавлением, удалением или обновлением таких полей, как status.addresses и spec.PodCIDRs. Подробнее — в обзоре Kubernetes 1.35.
Native Histogram Support for Kubernetes Metrics
Существующие гистограммы в Prometheus работают по принципу предопределённых бакетов (buckets), то есть разработчик должен заранее решить, какие диапазоны значений будут использоваться. Например, для времени выполнения запроса могут быть заданы следующие бакеты: до 10 мс, до 50 мс, до 100 мс, до 500 мс. Если запрос выполнился, например, за 49 мс, система просто увеличит счётчик для бакета «до 50 мс» (а также для всех последующих, так как они кумулятивные). У такого подхода есть два главных недостатка:
Неоднозначность. Неизвестно, как именно распределены значения внутри бакета. Что, если все запросы выполнились за 11 мс? Или, наоборот, за 49 мс? Эта информация теряется.
Избыточность. Система отправляет данные по всем заданным бакетам, даже если в них не попало ни одного значения. Всё это съедает ценные ресурсы и требует места для хранения на диске.
В Prometheus 2.40 появились так называемые Prometheus Native Histograms. Применённые в них экспоненциальные границы бакетов с автоподстройкой позволили устранить эти недостатки. KEP-5808 как раз и внедряет Prometheus Native Histograms в метрики компонентов Kubernetes.
Beta-фичи
Statusz for Kubernetes Components
KEP добавляет observability-эндпоинт /statusz в ключевые компоненты Kubernetes (kube-apiserver, kubelet, kube-controller-manager, kube-scheduler, kube-proxy). Он будет выводить важную информацию о состоянии компонента — версию, сведения о сборке, используемой версии Go, совместимости с API Kubernetes, полезные ссылки на другие важные эндпоинты (/healthz, /livez, /readyz и /metrics). Подробнее — в обзоре Kubernetes 1.32.
Flagz for Kubernetes Components
По аналогии с предыдущим KEP в ключевые компоненты Kubernetes добавляется эндпоинт /flagz. Он будет возвращать информацию о флагах, с которыми был запущен компонент. Изначально данные (имя флага и его значение) будут выдаваться в простом текстовом виде. В будущем может быть добавлена поддержка структурированных форматов. Доступ к /flagz будут иметь члены RBAC-роли system:monitoring.
Stable-фичи
Node log query
Администратору кластера Kubernetes приходится авторизовываться на узлах управляющего слоя или воркерах, чтобы просматривать логи API-сервера, kubelet’а и т. д., или «городить» свой клиент для чтения логов. Более простой и элегантный способ — разрешить ему использовать API kubelet’а или плагин kubectl для просмотра логов, подобно тому, как они используются для других взаимодействий с кластером. Учитывая конфиденциальный характер информации в логах на узлах, эта функция будет доступна только администраторам кластера.
Устаревшие или удалённые фичи
Прекращение поддержки Ingress NGINX
В целях обеспечения безопасности экосистемы SIG Network Kubernetes и Комитет по реагированию на угрозы безопасности прекратили поддержку Ingress NGINX 24 марта 2026 года.
Больше не выпускаются новые версии, не исправляются ошибки и не выпускаются патчи для устранения обнаруженных уязвимостей. Существующие развёртывания Ingress NGINX продолжат работать; чарты Helm и образы контейнеров также останутся доступными. Подробную информацию см. в блоге Kubernetes.
Удаление драйвера томов gitRepo
In-tree-драйвер давно не обновлялся и у него нет мейнтейнера, поэтому было принято решение удалить его, чтобы снизить риск RCE-атак вроде CVE-2024-10220. Рекомендуется перейти на полностью рабочие альтернативы для gitRepo, такие как git-sync и initContainer.
Депрекация поля Service.spec.externalIPs
Депрекация поля Service.spec.externalIPs с последующим удалением реализации для kube-proxy. Функция externalIPs уже давно считается угрозой безопасности и архитектурной проблемой, поскольку позволяет пользователям без привилегий запрашивать произвольные IP-адреса без надлежащей авторизации или проверки, что потенциально открывает возможности для атак «человек посередине» и других уязвимостей в системе безопасности.
P. S.
Читайте также в нашем блоге: