Вчера, 25 марта, состоялся очередной релиз Kubernetes — 1.18. По сложившейся для нашего блога традиции, мы рассказываем о наиболее значимых изменениях в новой версии.
Информация, использованная для подготовки этого материала, взята из официального анонса, таблицы Kubernetes enhancements tracking, CHANGELOG-1.18, обзоров от SUSE и Sysdig, а также соответствующих issues, pull requests, Kubernetes Enhancement Proposals (KEP)…
Релиз Kubernetes 1.18 получил свой официальный логотип, суть которого сводится к сравнению проекта с Большим адронным коллайдером. Подобно БАК, что стал результатом работы тысяч учёных со всего мира, Kubernetes объединил вокруг себя тысячи разработчиков из сотен организаций, и все они работают над общим делом: «улучшением облачных вычислений во всех аспектах».
Тем временем, энтузиасты из команды SUSE подготовили облако слов, созданное на основе записей release notes к 3412 коммитам, сделанным для релиза K8s 1.18. И оно получилось таким:
Теперь — о том, что же стоит за этими словами, в более понятном для пользователей виде.
Планировщик
Главное новшество здесь — это профили планирования (Scheduling Profiles). Связано оно с тем, что чем более неоднородными становятся рабочие нагрузки в кластере, тем скорее возникает потребность в разных подходах к их планированию.
Для решения этой проблемы авторы предлагают, чтобы планировщик использовал разные конфигурации, назначаемые на имя планировщика и называемые профилями. Стартуя, kube-scheduler просматривает все доступные профили и сохраняет их в реестр. Если профилей в конфигурации нет, выбирается вариант по умолчанию (default-scheduler
). После того, как pod'ы попадают в очередь, kube-scheduler выполняет их планирование с учётом выбранного планировщика.
Сами политики планирования основываются на предикатах (PodFitsResources
, PodMatchNodeSelector
, PodToleratesNodeTaints
и т.п.) и приоритетах (SelectorSpreadPriority
, InterPodAffinityPriority
, MostRequestedPriority
, EvenPodsSpreadPriority
и т.п.). В реализации сразу предусмотрена система плагинов, чтобы все профили добавлялись через специальный фреймворк.
Текущая структура конфигурации (вскоре будет изменена):
type KubeSchedulerConfiguration struct {
...
SchedulerName string
AlgorithmSource SchedulerAlgorithmSource
HardPodAffinitySymmetricWeight
Plugins *Plugins
PluginConfig []PluginConfig
...
}
… и пример настройки:
profiles:
- schedulerName: 'default-scheduler'
pluginConfig:
- name: 'InterPodAffinity'
- args:
hadPodAffinityWeight: <value>
К следующему релизу K8s ожидается перевод фичи в бета-версию, а ещё через два — стабилизация. Подробнее о профилях для планировщика см. в соответствующем KEP.
Другое новшество, появившееся в статусе альфа-версии, — настраиваемое по умолчанию правило для равномерного распределения pod'ов (Even Pod Spreading). В настоящий момент правила определяются в PodSpec
и привязываются к pod'ам, а теперь стало возможным задавать глобальную настройку на уровне кластера. Подробности — в KEP.
В то же время сама фича Pod Topology Spread (её feature gate — EvenPodsSpread
), позволяющая равно распределять pod'ы по кластеру категории multi-zone, переведена в статус бета-версии.
Кроме того, объявлено о стабилизации Taint Based Eviction, призванной добавлять taints на узлы при наступлении определённых условий. Впервые фича появилась в уже далёком релизе K8s 1.8, а статус бета-версии получила в 1.13.
Настраиваемая скорость масштабирования в HPA
Больше года в печи Kubernetes enhancements томится занятная фича под названием Configurable scale velocity for HPA, т.е. настраиваемая скорость горизонтального масштабирования. (К слову её разработку инициировал наш соотечественник.) В новом релизе она была доведена до первой стадии массового использования — стала доступна в альфа-версии.
Как известно, Horizontal Pod Autoscaler (HPA) в Kubernetes масштабирует число pod'ов у любого ресурса, поддерживающего подресурс scale
, основываясь на потреблении CPU или других метриках. Новая возможность позволяет контролировать скорость, с которой это масштабирование происходит, причём в обе стороны. До сих пор её можно было регулировать весьма ограничено (см., например, глобальный для кластера параметр --horizontal-pod-autoscaler-downscale-stabilization-window
).
Основная мотивация к введению настраиваемой скорости масштабирования — возможность разделения рабочих нагрузок кластера по их важности для бизнеса, позволив одним приложениям (обрабатывающим самый критичный трафик) иметь максимальную скорость увеличения в размере и невысокую скорость сворачивания (т.к. может случиться новый всплеск нагрузки), а другим — масштабироваться по иным критериям (для экономии средств и т.п.).
Предложенное решение — для конфигураций HPA добавлен объект behavior
, позволяющий определять правила для контролирования масштабирования в обе стороны (scaleUp
и scaleDown
). Например, конфигурация:
behavior:
scaleUp:
policies:
- type: percent
value: 900%
… приведёт к тому, что число запущенных в настоящий момент pod'ов будет увеличиваться на 900%. Т.е., если приложение стартует как один pod, в случае необходимости масштабирования оно начнёт расти как 1 → 10 → 100 → 1000.
Другие примеры и детали по реализации — см. в KEP.
Узлы
Прогресс в поддержке HugePages (общий KEP по фиче): в альфа-версии реализована поддержка этих страниц на уровне контейнеров и возможность запрашивать страницы разного размера.
Менеджер топологии узла (Node Topology Manager), призванный унифицировать подход к тонкой настройке распределения аппаратных ресурсов для различных компонентов в Kubernetes, переведён в статус бета-версии.
Также статус бета-версии получила представленная в K8s 1.16 фича PodOverhead, предлагающая механизм подсчёта накладных расходов на pod'ы.
kubectl
Добавлена альфа-версия команды kubectl debug (её KEP), которая развила концепцию «эфемерных контейнеров». Они были впервые представлены в K8s 1.16 с целью упростить отладку в pod'ах. Для этого в нужном pod'е запускается временный (т.е. живущий непродолжительное время) контейнер, содержащий в себе необходимые инструменты для отладки. Как мы уже писали, эта команда по своей сути идентична существовавшему до сих пор плагину kubectl-debug (его обзор).
Иллюстрация работы kubectl debug
:
% kubectl help debug
Execute a container in a pod.
Examples:
# Start an interactive debugging session with a debian image
kubectl debug mypod --image=debian
# Run a debugging session in the same namespace as target container 'myapp'
# (Useful for debugging other containers when shareProcessNamespace is false)
kubectl debug mypod --target=myapp
Options:
-a, --attach=true: Automatically attach to container once created
-c, --container='': Container name.
-i, --stdin=true: Pass stdin to the container
--image='': Required. Container image to use for debug container.
--target='': Target processes in this container name.
-t, --tty=true: Stdin is a TTY
Usage:
kubectl debug (POD | TYPE/NAME) [-c CONTAINER] [flags] -- COMMAND [args...] [options]
Use "kubectl options" for a list of global command-line options (applies to all commands).
Другая команда — kubectl diff, — впервые появившаяся ещё в K8s 1.9 и получившая статус бета-версии в 1.13, наконец-то объявлена стабильной. Как понятно из названия, она позволяет сравнивать конфигурации кластеров. По случаю стабилизации фичи у неё появился KEP, а также была обновлена вся соответствующая документация на сайте Kubernetes.
Кроме того, флагу kubectl --dry-run добавили поддержку разных значений (client
, server
, none
), что позволяет пробовать исполнение команды только на стороне клиента или сервера. Для её реализации на стороне сервера реализована поддержка основных команд включая create
, apply
, patch
и другие.
Сети
Началось перемещение ресурса Ingress из текущей группы API (extensions.v1beta1
) в networking.v1beta1
с последующей стабилизацией в виде v1
. Для этого запланировано проведение ряда изменений (KEP). На данный момент — в рамках бета-версии в K8s 1.18 — Ingress получил два значимых новшества:
- новое поле
pathType
, позволяющее определять, по какому принципу будет производиться сопоставление пути (Exact
,Prefix
илиImplementationSpecific
; последнее поведение определяется вIngressClass
); - новый ресурс
IngressClass
и новое (неизменяемое) полеClass
в определенииIngressSpec
, указывающее на то, какой котроллер реализует ресурс Ingress. Эти изменения приходят на смену аннотацииkubernetes.io/ingress.class
, использование которой объявят устаревшим.
Для многих сетевых фич был повышен статус готовности:
- стабильным стал плагин NodeLocal DNS Cache, улучшающий производительность работы DNS благодаря использованию агента для DNS-кэша на узлах кластера;
- стабильным объявлено и поле
AppProtocol
, определяющее прикладной протокол для каждого порта сервиса (ресурсыServicePort
иEndpointPort
); - поддержка IPv6 признана достаточно стабильной, чтобы перевести её в бета-версию;
- по умолчанию теперь активирован (в рамках бета-версии) и EndpointSlices API, выступающий как более масштабируемая и расширяемая замена обычным Endpoints.
Хранилища
В альфа-версии представлена основа для создания томов с предварительно загруженными на них данными — Generic Data Populators (KEP). В качестве реализации предлагается ослабить валидацию поля DataSource
с тем, чтобы источниками данных могли быть объекты произвольных типов.
Перед bind-монтированием тома в контейнер права на все его файлы меняются в соответствии со значением fsGroup
. Эта операция может сломать работу некоторых приложений (например, популярных СУБД), а также занимать очень много времени (для больших томов — более 1 Тб). Новое поле PermissionChangePolicy
для PersistentVolumeClaimVolumeSource
позволяет определять, требуется ли менять владельца для содержимого тома. Текущая реализация — альфа-версия, подробности — в KEP.
Для объектов Secrets
и ConfigMaps
добавлено новое поле immutable
, делающее их неизменяемыми. Как правило, эти объекты используются в pod'ах как файлы. Любые изменения в этих файлах быстро (примерно через минуту) распространяются на все pod'ы, примонтировавшие файлы. Таким образом, неудачное обновление секрета или ConfigMap'а может привести к сбою всего приложения.
Авторы фичи заявляют, что даже в случае обновления приложений рекомендуемым способом — через rolling upgrades — возможны сбои, вызванные неудачными обновлениями существующих секретов/ConfigMap'ов. Более того, сам процесс обновления этих объектов в запущенных pod'ах сложен с точки зрения производительности и масштабируемости (каждый kubelet вынужден постоянно следить за каждым уникальным секретом/CM).
В текущей реализации сделано так, что после того, как ресурс отмечен как неизменяемый, это изменение невозможно откатить. Потребуется не только удалить объект и создать его снова, но и пересоздать pod'ы, использующие удалённый секрет. Версия — альфа, подробности — KEP.
Стабильными объявлены:
- клонирование PVC;
- возможность использовать блочные raw-устройства (не сетевые) как Persistent Volumes;
- поддержка блочных raw-устройств в CSI;
- передача информации о pod'е, который запрашивает том.
Прочие изменения
Среди других новшеств в Kubernetes 1.18 (более полный перечень см. в CHANGELOG):
- До сих пор JWT-токены для Kubernetes service accounts (KSA) аутентифицировались только в Kubernetes API. В альфа-версии появилась возможность использовать сторонние системы аутентификации. Для этого в API-сервер добавлен discovery-документ, совместимый с OIDC (OpenID Connect) и содержащий публичные ключи. Существующие системы аутентификации по OIDC (т.е. службы вне K8s-кластера) могут использовать такие ключи для валидации KCA-токенов, снижая нагрузку на API-сервер. Подробности — в KEP.
- Альфа-версия Priority and Fairness для API (KEP) — нового обработчика для более тонкого контролирования ограничения запросов к API-серверу (речь про max-in-flight). В качестве реализации предлагается продвинутая система приоритетов. В ней определяются разные типы запросов (через объекты
FlowSchema
) и им назначаются ресурсы (через объектыRequestPriority
). Иллюстрация конфигурации для обработки пользовательских запросов черезkubectl
:kind: RequestPriority meta: name: workload-high spec: assuredConcurrencyShares: 30 queues: 128 handSize: 6 queueLengthLimit: 100 kind: FlowSchema meta: name: workload-high spec: requestPriority: name: workload-high flowDistinguisher: source: namespace # no transformation in this case match: - and: # users using kubectl - notPatternMatch: field: user pattern: system:serviceaccount:.*
- Объявлен стабильным CertificateSigningRequest API, предлагающий программный интерфейс для автоматизации запроса и получения x509-сертификатов от Certificate Authority. Он был представлен ещё в K8s 1.4 и получил статус бета-версии в 1.6.
- Ряд заметных улучшений в работе с ОС Windows: поддержка CRI-ContainerD (альфа-версия), реализация RuntimeClass (альфа-версия), поддержка CSI-драйверов через CSI proxy (альфа-версия), стабильные версии поддержки GMSA (Group Managed Service Account) и RunAsUserName.
Изменения в зависимостях:
- версия CoreDNS в составе kubeadm — 1.6.7;
- cri-tools 1.17.0;
- CNI (Container Networking Interface) 0.8.5, Calico 3.8.4;
- используемая версия Go — 1.13.8.
Что устарело?
- API Server не обслуживает устаревшие API: все ресурсы с
apps/v1beta1
иextensions/v1beta1
должны перейти наapps/v1
, также стоит обратить внимание на частности с ресурсамиdaemonsets
,deployments
,replicasets
,networkpolicies
,podsecuritypolicies
; - endpoint для метрик
/metrics/resource/v1alpha1
не обслуживается — вместо него теперь/metrics/resource
; - все генераторы команды
kubectl run
убраны кроме единственного, отвечающего за генерацию pod'а.
P.S.
Читайте также в нашем блоге:
- «Kubernetes 1.17: обзор основных новшеств»;
- «Kubernetes 1.16: обзор основных новшеств»;
- «Kubernetes 1.15: обзор основных новшеств»;
- «Kubernetes 1.14: обзор основных новшеств».
Автор: Dmitry Stolyarov