Kubernetes 1.27: обзор нововведений
Этой ночью вышла новая версия Kubernetes — 1.27. Среди главных изменений — переход на собственный полноценный реестр registry.k8s.io, обновление запросов и лимитов пода «на месте» — т.е. без необходимости перезапускать под или его контейнеры — и ряд усовершенствований в области безопасности (stable-статус фичи seccomp by default, in-process-валидация запросов к API-серверу и др.).
Для подготовки статьи использовалась информация из таблицы Kubernetes enhancements tracking, CHANGELOG-1.27, обзора Sysdig, а также конкретные Issues, Pull Requests и Kubernetes Enhancement Proposals (KEPs).
Всего в новом релизе 60 изменений. Из них:
18 новых функций (alpha);
29 продолжают улучшаться (beta);
13 признаны стабильными (stable).
Примечание
Мы сознательно не переводим названия фич на русский. Они в основном состоят из специальной терминологии, с которой инженеры чаще встречаются в оригинальной формулировке.
KEP от «Фланта»: Auth API to get self user attributes
#3325
KEP от «Фланта» перешел в beta-стадию. Он добавляет в группу authentication.k8s.io новый эндпоинт API — SelfSubjectReview
. С помощью команды kubectl auth whoami
можно обратиться к этому эндпоинту и посмотреть атрибуты текущего пользователя после завершения процесса аутентификации. Подробнее о KEP«е — в обзоре нововведений Kubernetes 1.26.
Узлы
Alpha-фичи
Kubelet limit of Parallel Image Pulls
#3673; KEP
KEP добавляет в kubelet ограничение на число параллельно скачиваемых образов на уровне узла.
Извлечение образов в Kubernetes ограничивается параметрами QPS и burst. Их недостаток в том, что лимитируется только число запросов, отправляемых в среду исполнения, при этом число загрузок «в процессе» не учитывается. Другими словами, даже при минимальном значении QPS параллельно может скачиваться множество образов, если процесс загрузки по тем или иным причинам занимает продолжительное время (см., например, Issue #112044). В результате число параллельно запрашиваемых образов оказывается ничем не ограничено.
KEP добавляет параметр maxParallelImagePulling
в конфигурацию kubelet«а. Он ограничивает максимальное количество параллельно запрашиваемых образов. Любой запрос, превышающий заданный лимит, будет блокироваться до тех пор, пока не завершится скачивание одного из образов «в процессе». Подробнее о логике работы механизма можно узнать из предложения по улучшению.
In-Place Update of Pod Resources
#1287; KEP
KEP позволяет обновлять запросы и лимиты пода «на месте» — т.е. без необходимости перезапускать под или его контейнеры. Идея состоит в том, чтобы сделать PodSpec изменяемой (mutable) в отношении определенных ресурсов. PodStatus также будет доработан — он сможет предоставлять информацию о ресурсах, выделенных для пода, а также фактических ресурсах, потребляемых подом и его контейнерами. KEP базируется на предложении по вертикальному масштабированию в реальном времени и «на месте» и концепции вертикального масштабирования ресурсов в Kubernetes.
Также планируется дополнить API Container Runtime Interface функциями, необходимыми для управления конфигурацией ресурсов CPU и памяти контейнера в среде исполнения.
В настоящее время изменения, связанные с ресурсами пода, требуют пересоздания последнего из-за неизменяемости (immutable) PodSpec. В то время как перезапуски подов обычно не страшны, в ряде случаев (например, если число подов невелико или рабочие нагрузки являются stateful) перезапуск нежелателен и приводит к снижению доступности. Решить эту проблему позволяет прямое изменение ресурсной конфигурации пода без необходимости пересоздавать под или контейнеры в нем.
Кроме того, вертикальное масштабирование пода «на месте» полагается на Container Runtime Interface при обновлении запросов/лимитов на CPU и память для контейнера (-ов) пода. В нынешнем виде API CRI имеет ряд недостатков, которые необходимо устранить:
UpdateContainerResources принимает параметр, описывающий ресурсы контейнера, предназначенные для обновления, для Linux-контейнеров. Это грозит проблемами для Windows-контейнеров и контейнеров, требующих сред исполнения, не базирующихся на Linux.
Не существует механизма CRI, позволяющего kubelet«у из среды исполнения контейнера запрашивать и обнаруживать лимиты CPU и памяти, заданные для контейнера.
Ожидаемое поведение среды исполнения, которая обрабатывает API CRI UpdateContainerResources, слабо определено и плохо документировано.
В рамках KEP«а спецификацию PodSpec предлагается сделать изменяемой в части ресурсов контейнеров. Первоначально правки в спецификацию будут вноситься путем ее обновления; в бета-версии для этих целей планируется создать новый подресурс /resize
. В дальнейшем его можно будет применять к другим ресурсам, работающим с шаблонами подов, таким как Deployment«ы, ReplicaSet«ы, Job«ы и StatefulSet«ы. Это позволит открывать контроллерам вроде VPA частичный RBAC-доступ, не давая полного доступа на запись к спецификациям подов. Кроме того, в разделе PodSpec.Containers появится ResizePolicy со следующими значениями:
RestartNotRequired
— значение по умолчанию; K8s попытается изменить размер контейнера без его перезапуска, если это возможно.Restart
— для применения новых значений ресурсов требуется перезапуск. Примечание:RestartNotRequired
не гарантирует, что контейнер не будет перезапущен. Среда исполнения может остановить контейнер для обновления спецификации ресурсов, если это потребуется.
Подробности реализации доступны в разделе Proposal KEP«а.
Support memory qos with cgroups v2
#2570; KEP
cgroups v1 в Kubernetes поддерживает только ограничение ресурсов CPU с помощью cpu_shares
/ cpu_set
/ cpu_quota
/ cpu_period
. Управление ресурсами памяти не поддерживается. Авторы KEP«а предлагают воспользоваться возможностями контроллера памяти в cgroups v2 для обеспечения QoS и гарантирования запросов/лимитов памяти подов/контейнеров.
Dynamic resource allocation #3063
#3063; KEP
Kubernetes все чаще используется в качестве решения для управления новыми рабочими нагрузками (пакетная обработка) и в новых средах (граничные вычисления). Таким рабочим нагрузкам нужны не только оперативная память и процессор, но и доступ к специализированному оборудованию. Усовершенствование инфраструктуры центров обработки данных позволяет устанавливать ускорители вне конкретных узлов и подключаться к ним динамически по мере необходимости.
KEP реализует API, позволяющий описывать новые типы ресурсов, необходимые поду. Поддерживаются:
Ресурсы, подключаемые по сети. Существующий API плагинов устройств ограничен аппаратным обеспечением на узле.
Совместное использование ресурсов несколькими контейнерами или подами. Существующий API диспетчера устройств вообще не поддерживает совместное использование. Его можно дополнить, после чего станет возможен обмен ресурсами между контейнерами в одном поде, но для обмена ресурсами между подами потребуется совершенно новый API, подобный тому, который представлен в данном KEP«е.
Ресурсы, инициализация которых в разных подах обходится слишком дорого (на данный момент оптимизировать этот процесс невозможно).
Кастомные параметры, описывающие требования к ресурсам и их инициализацию. Параметры не всегда бывают линейными и счетными. В текущей реализации API пода для работы с такими параметрами используются аннотации, а для доступа к ним из драйвера CSI или плагина устройства приходится выдумывать различные «костыли».
Новое оборудование будет поддерживаться дополнениями от его производителей. Больше не нужно будет вносить правки в сам Kubernetes.
KEP не заменяет другие способы запроса традиционных ресурсов (память/CPU, тома, расширенные ресурсы). Планировщик будет координировать работу дополнений, «владеющих» ресурсами (драйвер CSI, драйвер ресурсов), и ресурсами, которыми «владеет» и выделяет планировщик (память/CPU, расширенные ресурсы).
Идея в том, чтобы отдать все операции, специфичные для ресурса, на откуп драйверу, управляющему этим ресурсом. Сюда входят операции на уровне управляющего слоя (отслеживание того, где в кластере доступны ресурсы, помощь в принятии решений о планировании подов, выделение ресурсов по запросу), а также на уровне узла (подготовка запуска контейнеров). Такой драйвер может быть реализован на произвольном языке программирования — главное, чтобы он поддерживал протокол распределения ресурсов и интерфейсы gRPC, определенные в данном KEP«е. Его развертывание не будет зависеть от изменения конфигурации базовых компонентов Kubernetes, таких как планировщик.
Новые объекты API будут определять параметры запроса на ресурс (ResourceClaim
в API) и отслеживать его состояние. Спецификация пода будет соответствующим образом дополнена. под будет назначаться только на тот узел, на котором есть нужные ресурсы и они зарезервированы для его запросов. Это предотвратит ситуацию, когда под планируется на узел и «застревает» на нем в ожидании доступных ресурсов.
Support User Namespaces in stateless pods
#127; KEP
KEP добавляет поддержку пользовательских пространств имен в stateless-подах.
Из документации к user_namespaces (7):
«Пользовательские пространства имен изолируют связанные с безопасностью идентификаторы и атрибуты, в частности, идентификаторы пользователей и групп, корневую директорию, ключи и возможности. Идентификаторы пользователя и группы процесса могут быть разными внутри и вне пространства имен пользователя. Процесс может иметь обычный непривилегированный ID пользователя вне пользовательского пространства имен и в то же время ID = 0 внутри пространства имен; другими словами, у процесса будут полные привилегии внутри пользовательского пространства имен и ограниченные — вне его».
Идея в том, чтобы запускать процессы в подах с другими ID пользователя и группы, нежели на хосте. В этом случае привилегированный процесс в поде будет непривилегированным на хосте. В случае, если такой процесс «вырвется» за пределы контейнера, потенциальный вред будет минимизирован, поскольку на хосте его привилегии будут ограничены.
KEP полностью или частично устраняет ряд CVE (их список — в разделе Motivation). В спецификации пода появляется параметр pod.spec.hostUsers: *bool
. Если он не определен или true, используется пространство имен хоста (текущее поведение). Если false, для пода создается новое пользовательское пространство имен. По умолчанию параметр не задан.
Extend PodResources to include resources from Dynamic Resource Allocation (DRA)
#3695; KEP
Предлагается дополнить API PodResources и включить в него ресурсы, распределяемые механизмом динамического распределения ресурсов (DRA). Кроме того, предлагается расширить API, чтобы сделать его более дружественным для использования мета-плагинами CNI. Этот KEP развивает идеи в 2043-pod-resource-concrete-assignments и 2403-pod-resources-allocatable-resources.
Новый API PodResources позволит агентам мониторинга узлов собирать информацию о ресурсах, выделяемых DRA. Мета-плагины CNI, такие как multus и DANM, полагаются на API PodResources при добавления ресурсов, выделяемых плагинами устройств, в качестве аргументов CNI. Данный KEP позволит этим CNI-плагинам ссылаться на ресурсы, выделяемые DRA. Дальнейшее расширение API облегчит мета-плагинам CNI доступ к ресурсам, выделенным конкретному поду — им не придется фильтровать ресурсы для всех подов на узле.
Авторы предлагают дополнить существующий сервис gRPC PodResources kubelet«а, включив повторяющееся поле DynamicResource
в сообщение ContainerResources
. Новое поле будет содержать информацию о классе DRA-ресурса, его ресурсных claim«ах и списке устройств CDI, распределенных драйвером DRA. Кроме того, к существующему сервису gRPC добавится метод Get()
, с помощью которого можно будет опрашивать конкретные поды на предмет выделенных им ресурсов.
Beta-фичи
Kubelet Evented PLEG for Better Performance
#3386
Улучшение модернизирует подход, предложенный в KEP«е Kubelet: Pod Lifecycle Event Generator (PLEG) и меняет механизм работы CRI.
Теперь kubelet получает актуальные данные о состоянии пода по модели List/Watch. В частности, прослушивает потоковые события сервера gRPC из CRI, которые необходимы для генерации событий жизненного цикла пода — то есть не опрашивает среду исполнения. В результате снижается необязательное использование ресурсов CPU kubelet«ом и нагрузка на CRI. Подробнее — в обзоре новинок Kubernetes 1.26.
Stable-фичи
Add downward API support for hugepages
#2053
Нисходящий (downward) API позволяет контейнерам получать информацию о себе или кластере без использования клиента Kubernetes или сервера API. Данный KEP открывает контейнерам доступ к информации о hugepages. В спецификацию API добавляются параметры requests.hugepages-
и limits.hugepages-
, с которыми можно работать так же, как с аналогичными параметрами для CPU, памяти и эфемерного хранилища.
Kubelet option to enable seccomp by default
#2413
Seccomp by default: эта важная и долгожданная фича наконец переходит в статус stable. Она повышает безопасность «ванильного» Kubernetes, автоматически включая фильтрацию системных вызовов при запуске любых контейнеров (в предыдущих версиях K8s это нужно делать вручную).
Seccomp — режим, при котором все неразрешенные системные вызовы блокируются. Это помогает избегать атак на узел или целый кластер через контейнер, а также повышает устойчивость K8s к zero day-уязвимостям. Подробнее об алгоритме работы новой фичи мы писали в этой новости.
Node Topology Manager
#693
Менеджер топологии узла (Node Topology Manager) унифицирует подход к тонкой настройке распределения аппаратных ресурсов для различных компонентов в Kubernetes. Впервые он был представлен в далекой v1.16, и вот, наконец, переходит в стабильный статус. Подробнее о нем можно почитать в нашем обзоре нововведений Kubernetes 1.16.
Add gRPC probe to Pod.Spec.Container.{Liveness, Readiness, Startup}Probe
#2727
Liveness, Readiness и Startup probes — три разных типа проверки состояния пода. Сейчас они работают по протоколам HTTP (S) и TCP. Новая фича добавляет поддержку gRPC — открытого фреймворка для удаленного вызова процедур, который часто используется в микросервисной архитектуре.
Возможность использовать встроенный gRPC среди прочего избавляет от необходимости использовать сторонние инструменты для проверки состояния контейнеров вроде grpc_health_probe (1). Подробнее — в обзоре Kubernetes 1.23.
Add configurable grace period to probes
#2238
Liveness-проверки используют параметр terminationGracePeriodSeconds
как при обычном прекращении работы, так и при сбоях. Если значение параметра велико и проверка неудачна, kubelet будет ждать указанное (длительное) время, прежде чем перезапустить рабочую нагрузку.
Авторы KEP«а предлагают добавить в API новое поле, probe.terminationGracePeriodSeconds
. Оно будет определять период ожидания для liveness- и startup-проверок, переопределяя terminationGracePeriodSeconds
, но игнорироваться для readiness-проверок.
Приложения
Beta-фичи
PodHealthyPolicy for PodDisruptionBudget
#3017
KEP добавляет поле podHealthyPolicy
. С его помощью можно указать, что поды «здоровы» и, следовательно, подпадают под ограничения Pod Disruption Budget, либо их следует рассматривать как уже отключенные, и поэтому они могут быть проигнорированы PDB. Новые статусы для подов: status.currentHealthy
, status.desiredHealthy
и spec.unhealthyPodEvictionPolicy
.
Elastic Indexed Jobs
#3715
Индексированные Job«ы появились в Kubernetes 1.21, чтобы облегчить планирование высокопараллелизуемых заданий.
Однако после создания изменить количество (spec.completions
) или допустимое число параллельных Job«ов (spec.parallelism
) невозможно. Это довольно проблематично для некоторых рабочих нагрузок, например, связанных с глубоким обучением.
Данный KEP делает эти поля (spec.completions
и spec.parallelism
) изменяемыми (mutable), но с некоторыми ограничениями (они должны быть равны).
Allow StatefulSet to control start replica ordinal numbering
#3335
Цель KEP«а — разрешить миграцию StatefulSet«а между пространствами имен, между кластерами, а также разбивать его на сегменты без простоев в работе приложения.
В манифест StatefulSet«а добавляется новое поле spec.ordinals.start
, в котором указывается стартовый номер для реплик, контролируемых StatefulSet«ом. Подробнее — в нашем обзоре нововведений Kubernetes 1.26.
Retriable and non-retriable Pod failures for Jobs
#3329
Чтобы ограничить время выполнения Job«а, используются два параметра:
Если Job не запускается, и политика перезапуска установлена в OnFailure
, Kubernetes попытается запустить его заново — столько раз, сколько указано в backoffLimit
.
KEP помогает учитывать некоторые причины незапуска Job«а и, при необходимости, завершать его досрочно, игнорируя backoffLimit
. Для этого в Job API добавлено новое поле podFailurePolicy
. Дополнительная информация и пример конфигурации с использованием podFailurePolicy
— в обзоре новинок K8s 1.25.
Auto remove PVCs created by StatefulSet
#1847
KEP вводит необязательное поле .spec.persistentVolumeClaimRetentionPolicy
для контроля за тем, когда и как PVC удаляются во время жизненного цикла StatefulSet«а.
Stable-фичи
TimeZone support in CronJob
#3140
CronJob создает Job«ы в соответствии с графиком, который определен пользователем. Однако часовой пояс, используемый в процессе создания Job«а, соответствует часовому поясу kube-controller-manager«а. Если пользователь забыл это учесть, Job может быть выполнен не по плану.
KEP добавляет в CronJob API новое поле .spec.timeZone
, в котором можно заранее установить часовой пояс для запуска Job«а.
Хранилище
Alpha-фичи
VolumeGroupSnapshot
#3476; KEP
KEP реализует API Kubernetes, позволяющий снимать согласованные snapshot«ы сразу с нескольких томов. Для группировки PVC используются селекторы меток. В рамках KEP 3476 добавляется поддержка snapshot«ов групп томов для драйверов томов CSI.
Существующий API VolumeSnapshot позволяет делать snapshot«ы томов для защиты от потери или повреждения данных. Однако часть потребностей им не покрывается. Некоторые системы хранения поддерживают согласованный snapshot, т.е. снимок с нескольких томов в один и тот же момент времени для соблюдения согласованности порядка записи. Такая функция может пригодиться для приложений, работающих сразу с несколькими томами. Например, данные такого приложения могут храниться на одном томе, логи — на другом. Если snapshot«ы с этих томов снимать в разное время, информация на них окажется рассогласована. Соответственно, приложение не сможет нормально функционировать, если эти snapshot«ы использовать для восстановления после сбоя.
Да, можно предварительно «заморозить» (quiesce) приложение, однако это требует дополнительного времени и не всегда возможно. Кроме того, последовательное снятие snapshot«ов также может занять больше времени, нежели согласованное групповое.
KEP вводит новые CRD VolumeGroupSnapshot
, VolumeGroupSnapshotContent
и VolumeGroupSnapshotClass
.
Для объединения нескольких PVC в VolumeGroupSnapshot
на них навешивается соответствующая метка, которая затем указывается в селекторе labelSelector
в VolumeGroupSnapshot
, если драйвер CSI поддерживает возможность CREATE_DELETE_GET_VOLUME_GROUP_SNAPSHOT
. Подробнее о логике работы можно почитать в разделе Proposal KEP«а.
Beta-фичи
ReadWriteOncePod PersistentVolume Access Mode
#2485
В Kubernetes нет режима доступа для PersistentVolumes, который позволяет ограничить доступ так, чтобы на одном узле мог работать только один такой под. Это чревато проблемами для некоторых рабочих нагрузок. Пример: некая рабочая нагрузка выполняет обновление устройства хранения (с помощью ReadWriteOnce) и масштабируется на несколько подов. В этом случае второй под может оказаться на том же узле и начать работать с устройством хранения параллельно с первым.
В случае критичных рабочих нагрузок отсутствие режима, который позволяет ограничить доступ так, чтобы на одном узле мог работать только один под, приходится обходить другими способами (например, планируя лишь один под на узел и используя ReadWriteOnce), что может приводить к неэффективному использованию ресурсов в кластере.
KEP вводит новых режим доступа ReadWriteOncePod
, который позволяет ограничить доступ к PersistentVolumes одиночным подом на одиночном узле. Для сравнения, существующий режим ReadWriteOnce (RWO) ограничивает доступ к одиночному узлу, но разрешает одновременный доступ к этому узлу из нескольких подов.
Introduce nodeExpandSecret in CSI PV source
#3107
Для передачи секретов в RPC-запросах к CSI-драйверам при расширении емкости томов на узле с помощью операции nodeExpandVolume.
В запрос nodeExpandVolume
, который kubelet отправляет CSI-драйверу, добавлено новое поле secretRef
.
Кроме того, в объект CSIPersistentVolumeSource
добавлен параметр NodeExpandSecretRef
для передачи секретов в PVC-запросах на расширение тома. Подробнее — в обзоре нововведений Kubernetes 1.25.
Prevent unauthorised volume mode conversion during volume restore
#3141
С помощью API-ресурса VolumeSnapshot можно создавать PVC (PersistentVolumeClaim) из снапшота. Это делается через установку в PVC параметра Spec.dataSource
, который указывает на существующий VolumeSnapshot. При этом нет никакого механизма проверки, соответствует ли режим доступа у вновь созданного PVC режиму доступа, заданному для исходного PVC.
Чтобы улучшить контроль за режимом доступа к тому, авторы KEP«а предлагают следующие изменения:
добавить новое поле
SourceVolumeMode
в спецификации APIVolumeSnapshotContent
; в нем устанавливается режим доступа к тому, с которого сделан снапшот;добавить аннотацию со ссылкой на ресурс, который может использовать доверенный пользователь для VolumeSnapshot;
усовершенствовать методы контроля за snapshot-controller и external-provisioner.
Speed up recursive SELinux label change
#1710
На хостах с SELinux в принудительном режиме (enforcing mode) пользователи одного контейнера не могут получить доступ к другому контейнеру или к хосту. Это обеспечивается за счет контекста, который уникален для каждого контейнера, и лейблов, которые назначаются каждому файлу в каждом томе. Злоумышленник, которому удалось выбраться из контейнера, не сможет получить доступ к данным в других контейнерах, потому что у каждого контейнера свои тома со своими лейблами.
Однако такая защита может усложнять жизнь пользователям, которые разворачивают кластеры на базе SELinux: при запуске нового контейнера запускается рекурсивное переназначение лейблов для всех файлов в томе, привязанном к поду. Если том большой, процесс переназначения может затянуться.
Новая функция позволяет пропустить этап переназначения лейблов и тем самым ускорить монтирование тома. Подробности см. в обзоре Kubernetes 1.25.
Robust VolumeManager reconstruction after kubelet restart
#3756
Этот KEP является частью предыдущего, #1710, поэтому сразу позиционируется как бета. Его цель — уменьшить время, необходимое kubelet«у для восстановления информации о примонтированных томах после перезапуска.
Такая информация теряется после перезапуска kubelet«а, и для ее восстановления ему приходится сопоставлять данные сервера API и ОС хоста. Kubelet проверяет, какие поды должны быть запущены и какие тома примонтированы на самом деле.
Однако этот процесс несовершенен и лишен некоторой ключевой информации, например, о том, какие опции для монтирования томов использовал прежний kubelet.
KEP #3756 является своего рода работой над ошибками и предусматривает значительный рефакторинг кода. Именно поэтому он выделен из «родительского» KEP«а и снабжен отдельным переключателем функциональности (feature flag) NewVolumeManagerReconstruction
.
Планировщик
Beta-фичи
Pod Scheduling Readiness
#3521
Поды считаются готовыми к планированию сразу после того, как созданы. Планировщик Kubernetes ищет узлы для размещения всех ожидающих подов. Однако в реальности некоторые поды могут долго оставаться в состоянии miss-essential-resources
(«отсутствие необходимых ресурсов»). Эти поды «сбивают с толку» планировщик и компоненты типа Cluster Autoscaler.
В улучшении дорабатывается API и механика — так, чтобы пользователи или оркестраторы понимали, когда под полностью готов для планирования. В Pod API добавляется поле .spec.schedulingGates
со значением по умолчанию nil
. Поды, у которых значение этого поля не равно nil
, будут «припаркованы» во внутреннем пуле unschedulablePods
планировщика. Он обработает их, когда поле изменится на nil
.
Mutable Pod scheduling directives when gated
#3838
KEP #3521 Pod scheduling readiness позволяет помечать поды как готовые к планированию. Данный KEP развивает эту идею, делая переключатели планирования (scheduling gates) изменяемыми, чтобы другие компоненты, например, кастомные контроллеры планирования, могли использовать их для расширения возможностей kube-scheduler«а. См. KEP #3521 выше.
Respect PodTopologySpread after rolling upgrades
#3243
KEP решает проблему с несбалансированным распределением подов при плавающих обновлениях Deployment«а.
В TopologySpreadConstraint
вводится новое поле MatchLabelKeys
в качестве дополнения к существующему labelSelector
. В новом поле передается набор ключей для лейблов подов — их планировщик учитывает при распределении.
Фича позволяет применять ограничения PodTopologySpread
только в границах новой ревизии Depolyment«а, а не во всех ревизиях.
Stable-фичи
Mutable scheduling directives for suspended Jobs
#2926
Начиная с Kubernetes 1.23, появилась возможность обновлять поля node affinity
, node selector
, tolerations
, labels
и annotations
в шаблоне пода Job«а перед его запуском. Это позволяет контролировать, где будут запущены поды, например, в одной зоне или на узлах с одинаковой моделью GPU.
Сеть
Alpha-фичи
Cloud Dual-Stack --node-ip Handling
#3705; KEP
kubelet поддерживает dual-stack-значения --node-ip
для необлачных кластеров (например, bare-metal-кластеров), но не для их облачных аналогов. Данный KEP исправляет это.
В настоящее время при передаче параметра --cloud-provider
в kubelet последний ожидает, что --node-ip
не будет задан или будет представлять собой один IP-адрес. Если сразу указаны и --cloud-provider
, и --node-ip
(при этом --node-ip
отличен от 0.0.0.0
или ::
), kubelet добавит к узлу аннотацию alpha.kubernetes.io/provided-node-ip
. Облачные провайдеры ожидают, что эта аннотация будет соответствовать установленному синтаксису --node-ip
(т.е. значение будет единственным); в ином случае они выдадут ошибку и не уберут с узла taint node.cloudprovider.kubernetes.io/uninitialized
, в результате чего тот окажется непригодным для использования до перезапуска kubelet«а с действительным (или пустым) --node-ip
.
KEP позволит администраторам кластеров, в которых используются внешние облачные ресурсы, гибко менять IP-адреса узлов, назначаемые облаком. Администраторы смогут:
переопределять IP-адрес узла в dual-stack-кластере, и это не будет приводить к тому, что узел станет single-stack;
переопределять оба IP-адреса узла в dual-stack-кластере;
изменять порядок IP-адресов узлов в dual-stack-кластере (т.е. задавать первичность IPv6 или IPv4);
переключать узлы в single-stack-режим, когда поставщик облачных услуг предлагает dual-stack-режим, без необходимости указывать конкретный IP-адрес узла в формате IPv4 или IPv6.
Reserve nodeport ranges for dynamic and static allocation
#3668; KEP
Этот KEP развивает идею KEP 3070 (см. обзор нововведений Kubernetes 1.24), помогая избежать конфликтов при резервировании портов для сервисов типа NodePort.
Сервис Kubernetes — это абстрактный способ открыть для внешнего трафика приложение, работающее на некотором наборе подов. У сервиса есть виртуальный ClusterIP, который позволяет балансировать трафик между подами. ClusterIP может назначаться:
динамически: кластер выбирает один адрес из указанного диапазона сервисных IP-адресов.
статически: пользователь задает один адрес в пределах указанного диапазона сервисных IP-адресов.
В настоящее время, создавая сервис со статическим ClusterIP, невозможно узнать, не выбрал ли этот адрес какой-либо другой сервис динамически.
Диапазон IP-адресов сервисов можно логически разделить, избежав тем самым риска конфликтов между сервисами, использующими статическое и динамическое распределение IP-адресов.
При создании сервиса типа NodePort kube-proxy выделяет порт в диапазоне 30000–32767 и открывает этот порт на интерфейсе eth0 каждого узла. Подключения к этому порту затем перенаправляются на IP-адрес сервиса в кластере. KEP 3668 позволяет зарезервировать диапазон портов за определенным сервисом.
Multiple Service CIDRs
#1880; KEP
Позволяет динамически увеличивать количество IP-адресов, доступных для сервисов.
Некоторые типы сервисов — ClusterIP, NodePort и LoadBalancer — используют виртуальный IP-адрес ClusterIP, который должен быть уникальным в пределах кластера. Попытка создать сервис с адресом ClusterIP, который уже занят, приведет к ошибке.
Текущая реализация логики распределения IP-адресов для сервисов имеет несколько ограничений:
Нельзя менять размер или увеличивать диапазоны IP, выделяемых сервисам; это приводит к проблемам, когда сети перекрываются или в кластере заканчиваются доступные IP.
Диапазон IP-адресов сервисов не разглашается (not exposed), поэтому другие компоненты в кластере не могут его использовать.
Конфигурация привязана к конкретному серверу API; консенсус отсутствует; в результате разные серверы API могут конкурировать между собой, удаляя IP-адреса, закрепленные друг за другом.
Для IPv4 размер префикса для сервиса ограничен /12, однако для IPv6 он составляет /112 или меньше. Это вызывает проблемы у пользователей IPv6, поскольку /64 является стандартной и минимально рекомендуемой длиной префикса.
Feature gate 3070 позволяет использовать только зарезервированный диапазон IP-адресов сервиса.
Данный KEP ставит своей целью реализацию новой логики механизма распределения. Предлагается создать два объекта API — ServiceCIDR
и IPAddress
— и позволить пользователям динамически увеличивать количество доступных для сервисов IP-адресов, задавая новые диапазоны ServiceCIDR.
Beta-фичи
Cleaning up IPTables Chain Ownership
#3178
KEP оптимизирует работу с цепочками iptables, создаваемыми kubelet«ом. Опция IPTablesOwnershipCleanup запрещает kubelet«у создавать цепочки KUBE-MARK-DROP, KUBE-MARK-MASQ, KUBE-POSTROUTING и KUBE-KUBELET-CANARY (остается лишь KUBE-FIREWALL для обработки марсианских пакетов). Кроме того, она предупреждает, что аргументы kubelet«а --iptables-masquerade-bit
и --iptables-drop-bit
устарели и больше не работают.
Minimizing iptables-restore input size
#3453
KEP повышает производительность работы kube-proxy в режиме iptables, убирая из вызовов к iptables-restore
правила, которые не изменились (подробнее — в обзоре нововведений Kubernetes 1.26).
Remove transient node predicates from KCCM’s service controller
#3458
Контроллер сервисов в Kubernetes cloud controller manager (KCCM) добавляет/удаляет узлы из набора узлов балансировщиков нагрузки в следующих случаях:
Когда на узел навешивается/с узла удаляется taint
ToBeDeletedByClusterAutoscaler
;Когда узел переходит в состояние Ready/NotReady.
Однако второй случай относится только к сервисам с externalTrafficPolicy: Cluster
. При этом в обоих случаях удаление узла из набора узлов балансировщиков нагрузки приведет к тому, что все соединения на этом узле будут мгновенно прерваны. Подобное поведение представляется неоптимальным для узлов в переходном состоянии готовности или завершающих свою работу и выглядит как ошибка, поскольку в таких случаях соединениям не разрешается разрываться, даже если балансировщик нагрузки поддерживает это.
Данный KEP предусматривает прекращение синхронизации набора узлов балансировщиков нагрузки в таких случаях. Для удобства в систему будет интегрирован feature gate StableLoadBalancerNodeSet
.
API
Alpha-фичи
CEL-based admission webhook match conditions
#3716; KEP
KEP добавляет так называемые «условия соответствия» (match conditions) к admission-вебхукам как расширение существующих правил для определения области применения вебхука. matchCondition представляет собой CEL-выражение. Если оно истинно, admission-запрос будет отправлен на вебхук. Если оно ложно, вебхук запрос пропустит (неявно разрешено).
Авторы KEP«а считают, что предложенный механизм позволит оптимизировать работу с вебхуками в следующих областях:
Надежность. Для многих пользователей Kubernetes admission-вебхуки остаются больным местом. Выход вебхука из строя может оказать значительное влияние на доступность кластера. Данное предложение смягчает (но не устраняет) эти проблемы, делая вебхуки более узконаправленными и целевыми.
Производительность. Admission-вебхуки критически важны для write-запросов. Проверочные (validating) вебхуки могут выполняться параллельно, но мутирующие (mutating) веб хуки должны выполняться последовательно (до 2 раз!). Это делает их чрезвычайно чувствительными к задержкам, и даже те вебхуки, которые не выполняет никакой работы, все равно несут процесс из-за круговых задержек (RTT).
Поддерживаемость. В случае hosted- или managed-дистрибутивов Kubernetes вебхуки могут мешать запросам managed-компонентов. Существующие критерии для фильтрации запросов для многих случаев недостаточны, и их нелегко дополнить правилами провайдера.
KEP добавляет поле MatchConditions
в объекты ValidatingWebhook
и MutatingWebhook
(в admissionregistration.k8s.io). Оценка условия MatchCondition
выполняется теми же библиотеками, которые используются для CEL ValidatingAdmissionPolicy
. Единственное различие в выражениях заключается в наличии переменной params
. Выражения, требующие доступа к дополнительной информации вне AdmissionRequest
, должны выполняться в вебхуке и выходят за рамки данного предложения.
CEL for Admission Control
#3488; KEP
KEP реализует настраиваемую in-process-валидацию запросов к API-серверу Kubernetes как альтернативу для проверочных (validating) admission-вебхуков. Предложение базируется на возможностях CRD Validation Rules (в beta, начиная с v1.25), но с акцентом на возможности применения политик при валидации контроля допуска.
KEP снижает инфраструктурный барьер для внедрения кастомизируемых политик и реализует примитивы, способствующие применению лучших практик при работе как с K8s, так и его расширениями.
В настоящее время кастомные политики реализуются с помощью admission-вебхуков. Эти хуки отличаются высокой гибкостью, но имеют ряд недостатков по сравнению с применением политик «в процессе»:
Требуют создания инфраструктуры для размещения admission-вебхуков.
Увеличивают задержку.
Из-за дополнительных инфраструктурных зависимостей вебхуки менее надежны, чем их in-process-аналоги.
Управление вебхуками обременительно для администраторов кластера. Приходится заботиться о наблюдаемости и безопасности, а также формировать план выпуска/развертывания/отката вебхуков.
KEP вводит новый kind ValidatingAdmissionPolicy
в группу admissionregistration.k8s.io
.
На высоком уровне API будет по