В понедельник должен был официально состояться (но пока этого не случилось) очередной релиз Kubernetes — 1.15. По сложившейся для нашего блога традиции, рассказываем о наиболее значимых изменениях в новой версии.
Информация, использованная для подготовки этого материала, взята из таблицы Kubernetes enhancements tracking, CHANGELOG-1.15 и сооветствующих issues, pull requests, а также Kubernetes Enhancement Proposals (KEP). Поскольку на следующей неделе пройдет конференция KubeCon в Шанхае, у этого релиза был сокращённый 11-недельный цикл (вместо 12 недель), что на количество значимых изменений, впрочем, заметно не повлияло. Итак, поехали!..
Хранилища данных
Представлен новый API ExecutionHook
, позволяющий динамически исполнять пользовательские команды в pod'е/контейнере или группе pod'ов/контейнеров, а вместе с ним — соответствующий контроллер (ExecutionHookController
), реализующий управление жизненным циклом хука. Мотивацией к появлению этой фичи стало желание предоставить пользователям возможность создавать/удалять снапшоты в соответствии с логикой работы приложения, т.е. выполнять какие-то специфичные для приложения команды до и после создания снапшота. Предполагается, что такие хуки также могут быть полезны и для других ситуаций — например, выполнения обновлений, отладки, обновления конфигурационных файлов, рестарта контейнера, подготовки к иным событиям вроде миграции базы данных. Текущий статус — альфа-версия (ожидается перевод в бету для следующего релиза), подробности — в KEP.
В ephemeral-storage, что позволяет разграничивать для конкретных pod'ов/контейнеров объём общего разделяемого пространства (shared storage), добавлена поддержка квот файловой системы. Этот новый механизм использует квоты на проект (project quotas), доступные в XFS и ext4, обеспечивая мониторинг потребления ресурсов и опциональное накладывание лимитов на них. Текущий статус — альфа-версия; планы по будущим релизам пока не уточняются.
Ещё одна новая возможность, представленная sig-storage, — использование существующих PVC в качестве DataSource
для создания новых PVC. Иными словами, это реализация функции клонирования томов. Клоны следует отличать от снапшотов, поскольку каждый клон является новым и «полноценным» томом: он создан как копия уже существующего, однако полностью следует жизненному циклу обычных томов (в отличие от снапшотов, хоть и являющихся копиями томов на определённый момент времени, но не самостоятельными томами). Иллюстрация использования возможности:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-2
namespace: myns
spec:
capacity:
storage: 10Gi
dataSource:
kind: PersistentVolumeClaim
name: pvc-1
В этом случае будет создан новый самостоятельный PV/PVC (pvc-2
), содержащий те же данные, что были на pvc-1
. При этом указано, что новый PVC должен иметь то же пространство имён, что и оригинальный.
Существующие ограничения — поддержка только динамического provisioner'а и только плагинов CSI (у них должна присутствовать capability CLONE_VOLUME
). Подробнее читайте в KEP.
До статуса бета-версии (а значит и активации в инсталляциях Kubernetes по умолчанию) «доросли» следующие возможности:
- Функция расширения размера Persistent Volume «онлайн», т.е. без необходимости в рестарте pod'а, использующего соответствующий PVC. Впервые (в статусе альфа-версии) она появилась в K8s 1.11.
- Поддержка переменных окружения для названий директорий, монтируемых как
subPath
, которая была впервые представлена в K8s 1.11 и получила развитие в прошлом 1.14.
А вот процесс миграции внутренностей старых плагинов для хранилищ, реализованных внутри кодовой базы Kubernetes (in-tree), в пользу плагинов для нового интерфейса CSI затянулся. Ожидалось, что к релизу 1.15 завершат миграцию всех плагинов облачных провайдеров, однако принято решение оставить статус альфа-версии, поскольку фича зависит от API, представленных в K8s 1.15 и пока что реализованных тоже лишь в альфа-версии (в частности, речь идёт об улучшениях в поддержке Azure: плагинов Azure File и Azure Disk в csi-translation-lib).
Планировщик
Два заметных нововведения — оба пока в виде альфа-версий — доступны в планировщике Kubernetes.
Первое — фреймворк планирования (Kubernetes Scheduling Framework), представляющий собой новый набор API для плагинов, расширяющих возможности существующего планировщика. Плагины создаются вне основного репозитория (out-of-tree), но входят в состав планировщика при компиляции. Таким образом, функциональное ядро планировщика остаётся максимально простым и удобным в поддержке, а дополнительные возможности реализуются отдельно, причём без тех многочисленных ограничений, которыми «страдал» нынешний способ расширения фич планировщика (с помощью webhooks).
В новом фреймворке каждая попытка планирования pod'а разбивается на два этапа:
- планирования (scheduling cycle) — где выбирается узел для pod'а,
- и привязывания (binding cycle) — где выбранное решение реализуется в рамках кластера.
На каждом из этих этапов (вместе их ещё называют контекстом планирования — scheduling context) существует множество точек расширения (extension points), на каждой из которых могут вызываться плагины фреймворка.
(Жизненный цикл для вызова плагинов в Scheduling Framework.)
В рамках альфа-версии фреймворка реализованы только точки Reserve, Unreserve и Prebind. Подробности об этом масштабном нововведении читайте в KEP.
Второе — опция Non-Preempting для PriorityClasses
.
Классы приоритетов получили стабильный (GA) статус в прошлом релизе Kubernetes, что повлияло на процессы планирования и выборки pod'ов: pod'ы планируются в соответствии с приоритетом, а если pod не может быть создан из-за недостатка ресурсов, то pod'ы с более низким приоритетом могут вытесняться для освобождения необходимого пространства.
Новая опция — Preempting
, определяемая как булев в структуре PriorityClass
, означает: если pod ожидает своего планирования и имеет Preempting=false
, его создание не приведёт к вытеснению других pod'ов. Это поле появляется в PodSpec
в процессе pod admission (аналогично тому, как и значение PriorityClass
). Подробности о реализации — в KEP.
API Machinery
Для CustomResources представлены улучшения, призванные реализовать для данных, хранимых таким образом (в рамках JSON в CRD), поведение, которое лучше соответствует общепринятому в Kubernetes API (для «родных» объектов K8s):
- автоматическое удаление полей, не указанных в схемах валидации OpenAPI, — подробности см. в KEP «Pruning for Custom Resources»;
- возможность задавать в схемах валидации OpenAPI v3 значения по умолчанию (defaulting) для полей, что особенно важно для сохранения совместимости API при добавлении объектам новых полей, — подробности см. в KEP «Defaulting for Custom Resources».
Обе фичи изначально планировались на включение в состав релиза K8s 1.12, однако только теперь представлены в виде альфа-версий.
Этим изменения в CRD не ограничились:
- возможность Publish CRD OpenAPI — т.е. валидация CustomResources на стороне сервера (с помощью схемы OpenAPI v3), представленная в прошлом релизе Kubernetes, — достигла бета-версии и теперь включена по умолчанию;
- механизм преобразования версий CRD-ресурсов, основанный на внешних webhooks, тоже переведён в бета-версию.
Другое интересное нововведение получило название Watch bookmark. Его суть сводится к добавлению нового типа события в Watch API — Bookmark
. Этот тип означает метку, что все объекты до определённой resourceVersion
уже были обработаны watch'ем. Такой механизм позволит снизить нагрузку на kube-apiserver, уменьшив количество событий, которые требуется обрабатывать при каждом перезапуске watch'а, а также снизить количество нежелательных ошибок типа «resource version too old». В Kubernetes 1.15 фича имеет статус альфа-версии, а её повышение до беты ожидается к следующему релизу.
Added EventType = "ADDED"
Modified EventType = "MODIFIED"
Deleted EventType = "DELETED"
Error EventType = "ERROR"
Bookmark EventType = "BOOKMARK"
(Возможные типы событий в Watch API.)
В Admission Webhooks:
- добавлена поддержка селектора объектов (object selector) в дополнение к существующим селекторам пространств имён;
- реализована возможность регистрации конкретной версии ресурса и вызова, когда модифицируется любая более старая версия этого ресурса;
- в AdmissionReview API добавлено поле
Option
, сообщающее об опциях выполняемой операции.
Сеть
Значимое новшество в сетевой части Kubernetes — так называемая «защита финализатора» (Finalizer Protection) для балансировщиков нагрузки. Теперь перед тем, как удалять ресурсы LoadBalancer'а, производится проверка, что соответствующий ресурс Service'а не был полностью удалён. Для этого к каждому сервису с type=LoadBalancer
прикрепляется так называемый finalizer: при удалении такого сервиса реальное удаление ресурса блокируется, пока finalizer не будет удалён, а сам finalizer не удаляется до тех пор, пока не завершится «подчистка» ресурсов соответствующего балансировщика нагрузки (service.kubernetes.io/load-balancer-cleanup
). Текущая версия реализации — альфа-версия, а подробности о ней можно найти в KEP.
Кроме того:
- Плагин NodeLocal DNS Cache, представленный в Kubernetes 1.13 и улучшающий производительность работы DNS, достиг бета-версии.
- Kube-proxy больше автоматически не удаляет сетевые правила, созданные в результате его работы в других режимах (для этого требуется явный запуск
kube-proxy --cleanup
).
CLI
Как всегда, не обошлось без приятных мелочей в консольных командах для работы с кластерами Kubernetes:
- Перевод
kubectl get
на получение данных с сервера (а не клиента) для полноценной поддержки расширений объявлен завершённым (стабильным). - В
kubectl top
добавили опцию--sort-by
:$ kubectl --kubeconfig=kubectl.kubeconfig top pod --sort=memory NAME CPU(cores) MEMORY(bytes) elasticsearch-logging-v1-psc43 2m 2406Mi hadoop-journalnode-2 13m 362Mi hodor-v0.0.5-3204531036-fqb0q 23m 64Mi kubernetes-admin-mongo-... 5m 44Mi cauth-v0.0.5-2463911897-165m8 34m 10Mi test-1440672787-kvx8h 0m 1Mi
- В
kubectl rollout restart
добавили поддержку DaemonSets и StatefulSets. - Добавлена новая команда
kubeadm upgrade node
для обновления узлов кластера, заменившая (ныне объявленные устаревшими)kubeadm upgrade node config
иkubeadm upgrade node experimental-control-plane
. - Добавлены новые команды
kubeadm alpha certs certificate-key
(для генерации случайного ключа, который можно затем передать вkubeadm init --experimental-upload-certs
) иkubeadm alpha certs check-expiration
(для проверки времени действия локальных PKI-сертификатов). - Команда
kubeadm config upload
объявлена устаревшей, поскольку её замена (kubeadm init phase upload-config
) стала зрелой.
Другие
Среди прочих заметных изменений в Kubernetes 1.15:
- Поддержка Pod Disruption Budget (PDB) добавлена и для сторонних ресурсов/контроллеров, основанных на CRD (например: EtcdCluster, MySQLReplicaSet…), с помощью Scale subresource. Пока это бета-версия, которую сделают стабильной уже в следующем релизе. Подробности — в KEP.
- До бета-версии дошли две фичи для узлов/Kubelet: поддержка сторонних плагинов для мониторинга устройств (дабы вынести из Kubelet, т.е. out-of-tree, все специфичные для устройств знания) и
SupportNodePidsLimit
(изоляция PID'ов от узла к pod'ам). - Для кодовой базы Kubernetes добавлена и включена по умолчанию поддержка Go Modules (вместо Godep и режима GOPATH, объявленного устаревшим).
- Поддержка AWS NLB (Network Load Balancer), впервые представленная ещё в K8s 1.9, достигла уровня бета-версии. В частности, она получила возможность конфигурации
accessLogs
, терминации TLS иобновления LoadBalancerSourceRanges
. - Реализована возможность конфигурировать облачного провайдера Azure из секретов Kubernetes (для этого добавлена новая опция
cloudConfigType
, одним из значений которой может бытьsecret
). Также Kubelet в Azure теперь может работать без Azure identity (для этого должен быть включёнuseInstanceMetadata
). - В cluster-lifecycle довели до бета-версии возможность создания HA-кластеров с помощью kubeadm, а также завершили очередной этап (v1beta2) в реорганизации формата конфигурационного файла kubeadm.
- В метрики от планировщика добавлено количество pods в статусе pending в разных очередях, а от CSI — статистика о томах через kubelet volume metrics.
- Обновления в используемом/зависимом программном обеспечении: Go 1.12.5, cri-tools 1.14.0, etcd 3.3.10 (версия не изменилась для сервера, но обновилась для клиента). Не изменились версии CNI, CSI, CoreDNS (в одной из альфа-версий Kubernetes 1.15 её обновили до 1.5.0, но потом снова откатили к 1.3.1), поддерживаемые версии Docker.
P.S.
Читайте также в нашем блоге:
- «Kubernetes 1.14: обзор основных новшеств»;
- «Kubernetes 1.13: обзор основных новшеств»;
- «Kubernetes 1.12: обзор основных новшеств»;
- «Kubernetes 1.11: обзор основных новшеств».
Автор: Dmitry Stolyarov