НОВОСТИ Kubernetes 1.19: обзор основных новшеств

NewsBot
Оффлайн

NewsBot

.
.
Регистрация
21.07.20
Сообщения
40.408
Реакции
1
Репутация
0
Сегодня, 25 августа, новый релиз Kubernetes (его в общей сложности задержали почти на 2 месяца) — 1.19. По традиции нашего блога, рассказываем о наиболее значимых изменениях в новой версии.

ikfkvcpsfthwkjwnot2onqz2b0i.png


Информация, использованная для подготовки этого материала, взята из официального анонса, , , обзора , а также соответствующих issues, pull requests, Kubernetes Enhancement Proposals (KEP).

Начнём с нескольких крупных новшеств достаточно общего характера…

С выпуском Kubernetes 1.19 «окно поддержки» для версий Kubernetes с 9 месяцев (т.е. 3 последних релизов) до 1 года (т.е. 4 релизов). Почему?

Оказалось, что из-за высокой скорости развития проекта (частых major-релизов) администраторы кластеров Kubernetes не успевают обновлять свои инсталляции. Авторы ссылаются на опрос, проведённый рабочей группой в начале прошлого года и показавший, что около трети пользователей Kubernetes имеют дело с устаревшими релизами K8s, запущенными в production:

ayggsrh5hzldlr36zntman-i6do.png

(На момент опроса актуальной версией Kubernetes была 1.13, т.е. все пользователи K8s 1.9 и 1.10 работали с релизами, которые на тот момент уже не поддерживались.)

Таким образом, предполагается, что продление на 3 месяца периода поддержки релизов Kubernetes — выпуска патчей, исправляющих обнаруженные в коде проблемы, — позволит добиться того, что более 80 % пользователей будут работать на поддерживаемых версиях K8s (вместо предполагаемых 50-60 % на данный момент).

Другое большое событие: стандарт для структурированных логов. Нынешняя система логирования в control plane не гарантирует единой структуры для сообщений и ссылок на объекты в Kubernetes, что усложняет обработку таких логов. Чтобы решить эту проблему, вводится новая структура для сообщений в логах, для чего библиотеку klog расширили новыми методами, которые предоставляют структурированный интерфейс для формирования логов, а также вспомогательными методами для идентификации K8s-объектов в логах.

Одновременно с миграцией на klog v2 осуществляется и переход на новый формат вывода логов в JSON, который упростит выполнение запросов к логам и их обработку. Для этого появляется флаг --logging-format, который по умолчанию использует прежний текстовый формат.

Поскольку репозиторий Kubernetes огромен, а авторы — реалисты, они сосредоточат свои усилия по воплощению в жизнь новых идей на наиболее общих сообщениях.

Иллюстрация логирования с помощью новых методов в klog:


klog.InfoS("Pod status updated", "pod", "kubedns", "status", "ready")

I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kubedns"


klog.InfoS("Pod status updated", "pod", klog.KRef("kube-system", "kubedns"), "status", "ready")

I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"


klog.ErrorS(err, "Failed to update pod status")

E1025 00:15:15.525108 1 controller_utils.go:114] "Failed to update pod status" err="timeout"

Использование формата JSON:


pod := corev1.Pod{Name: "kubedns", Namespace: "kube-system", ...}
klog.InfoS("Pod status updated", "pod", klog.KObj(pod), "status", "ready")


{
"ts": 1580306777.04728,
"v": 4,
"msg": "Pod status updated",
"pod":{
"name": "nginx-1",
"namespace": "default"
},
"status": "ready"
}

Ещё одно важное (и очень актуальное) новшество — механизм информирования об устаревших (deprecated) API, сразу в виде бета-версии (т.е. активен в инсталляциях по умолчанию). Как авторы, у Kubernetes постоянно множество устаревших возможностей, пребывающих в разном состоянии и с разными временными перспективами. Следить за ними, внимательно читая все Release Notes и вручную вычищая конфиги/настройки, практически нереально.

Для решения этой проблемы теперь при использовании устаревшего API в его ответы добавляется заголовок Warning, который распознаётся на стороне клиента (client-go) с возможностью разного реагирования: игнорировать, дедуплицировать, логировать. В утилите kubectl научили выводить эти сообщения в stderr, подсвечивать цветом сообщение в консоли, а также добавили флаг --warnings-as-errors с говорящим за себя названием.

В дополнение к этому, добавлены специальные метрики, сообщающие об использовании устаревших API и audit-аннотации.

Наконец, разработчики продвижением фич Kubernetes из бета-версии. Как показал опыт проекта, некоторые новые фичи и изменения в API «застревали» в статусе Beta по той причине, что они уже автоматически (по умолчанию) активировались и не требовали дальнейших действий от пользователей.

Чтобы этого не происходило, автоматически отправлять в список устаревания те фичи, которые находятся в бета-версии на протяжении 6 месяцев (двух релизов) и не удовлетворяют ни одному из этих условий:

  1. соответствуют критериям GA и продвигаются в стабильный статус;
  2. имеют новую бета-версию, которая делает устаревшей прошлую бету.

А теперь — о других изменениях в Kubernetes 1.19, разбитых по категориям соответствующих им SIG.

Хранилища


Новые объекты CSIStorageCapacity улучшить процесс планирования pod'ов, в которых используются CSI-тома: они не будут размещаться на узлах, в хранилищах которых закончилось место. Для этого информация о доступном дисковом пространстве будет храниться в API-сервере, доступна CSI-драйверам и планировщику. Текущий статус реализации — альфа-версия; подробности — в .

Другое новшество в альфа-версии — возможность определения эфемерных томов прямо в спецификациях pod'ов, ( ). Эфемерные тома создаются для определённых pod'ов во время их появления и удаляются вместе с завершением их работы. Их можно было определять и раньше (в том числе, прямо в спецификации, т.е. методом inline), однако существующий подход, доказав состоятельность самой фичи, покрывал не все случаи её использования.

Новый механизм предлагает простой API, позволяющий определять эфемерные тома для любого драйвера с поддержкой динамического provisioning'а (раньше для этого пришлось бы модифицировать драйвер). Он позволяет работать с любыми эфемерными томами (и CSI, и in-tree вроде EmptyDir), а также обеспечивает поддержку другой новой фичи (описанной чуть выше) — отслеживания доступного пространства хранилища.

Пример высокоуровневого объекта Kubernetes, использующего новый эфемерный том (generic inline):


apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
volumeMounts:
- name: varlog
mountPath: /var/log
- name: scratch
mountPath: /scratch
volumes:
- name: varlog
hostPath:
path: /var/log
- name: scratch
ephemeral:
metadata:
labels:
type: fluentd-elasticsearch-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi

Здесь контроллер DaemonSet создаёт pod'ы с именами вида fluentd-elasticsearch-b96sd, после чего для такого pod'а будет добавлен PersistentVolumeClaim fluentd-elasticsearch-b96sd-scratch.

И последняя полностью новая фича в области хранения, как альфа-версия, — новое поле csidriver.spec.SupportsFSGroup для CSI-драйверов, указывающее на факт поддержки определения прав доступа на основе ( ). Мотивация: смена владельца для CSI-тома выполняется перед тем, как он монтируется в контейнер, однако не все виды хранилищ поддерживают такую операцию (например, NFS), из-за чего сейчас она может приводить к ошибкам.

До бета-версии (т.е. включения по умолчанию) «доросли»:

  • CSI-драйверы для и (с миграцией всех вызовов в старых плагинах, реализованных внутри кодовой базы Kubernetes);
  • .

Узлы / Kubelet


Поддержка seccomp стабильной (GA). В частности, эти работы привели к переходу на поля для seccomp в API вместо аннотаций, объявленных устаревшими (новые Kubelet'ы игнорируют аннотации), и затронули .

В PodSpec новое поле fqdnInHostname, позволяющее задавать FQDN (Fully Qualified Domain Name) для хоста pod'а. Цель — улучшение поддержки устаревших (legacy) приложений в Kubernetes. Вот как авторы свои намерения:

«Традиционно Unix и некоторые Linux-дистрибутивы, такие как Red Hat и CentOS, рекомендовали устанавливать FQDN-хост в поле ядра hostname. Как следствие, многие приложения, созданные до Kubernetes, полагаются на такое поведение. Наличие подобной фичи поможет контейнеризировать существующие приложения без рискованных изменений кода».​

Значением по умолчанию будет false, чтобы сохранить прежнее (для Kubernetes) поведение. Статус фичи — альфа-версия, которую планируется объявить стабильной уже в следующем релизе (1.20).

Принято решение от метрик Accelerator Metrics, собираемых Kubelet. Сбор таких метрик предлагается выполнять внешними агентами мониторинга через PodResources API. Сам этот API был созданно именно с целью выноса всех специфичных для устройств метрик из основного репозитория Kubernetes, позволив вендорам реализовывать их без внесения изменений в ядро Kubernetes. PodResources API находится в бета-версии (за него отвечает feature gate KubeletPodResources) и скоро станет стабильным. Для текущего релиза процесс отказа имеет статус альфа-версии, подробности — в .

Отныне Kubelet без Docker: под этим «без» авторы подразумевают отсутствие любого специфичного для Docker кода и зависимости от Golang-пакета docker/docker. Конечная цель этой инициативы — прийти к полностью «dockerless» (т.е. лишенному зависимости от Docker'а) Kubelet. Подробнее о мотивации можно прочитать, как всегда, в . Эта возможность сразу получила статус GA.

Менеджер топологии узла (Node Topology Manager), достигший своей бета-версии в прошлом релизе K8s, возможность выравнивания ресурсов на уровне pod'ов.

Планировщик


Ещё в мы писали про глобальную конфигурацию для равномерного распределения pod'ов (Even Pod Spreading), однако тогда эту фичу отложить по итогам тестирования производительности. Теперь она вошла в Kubernetes (в статусе альфа-версии).

Суть новшества заключается в добавлении глобальных ограничений (DefaultConstraints), позволяющих регулировать правила распределения pod'ов на более высоком уровне — на уровне кластера, а не только в PodSpec (через ), как было до сих пор. Конфигурация по умолчанию будет схожа с нынешним плагином DefaultPodTopologySpread:


defaultConstraints:
- maxSkew: 3
topologyKey: "kubernetes.io/hostname"
whenUnsatisfiable: ScheduleAnyway
- maxSkew: 5
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: ScheduleAnyway

Подробности — в .

Другая возможность, связанная с Even Pod Spreading: распределение группы pod'ов по failure domains (регионам, зонам, узлам и т.п.), — из альфа-версии в бету (включена по умолчанию).

Аналогичного «повышения» достигли и три другие фичи в планировщике:

  • (Scheduling Profiles), в 1.18;
  • опция для в PriorityClasses;
  • конфигурационный файл .

Сети


Ресурс Ingress наконец-то стабильным и получил версию v1 в API. В связи с этим, было представлено в соответствующей документации. Особое внимание стоит обратить на заметные пользователю изменения из : например, там есть такие переименования, как spec.backend → spec.defaultBackend, serviceName → service.name, servicePort → service.port.number…

В статус бета-версии переведены для Services и Endpoints, а также (kube-proxy на Linux начинает использовать EndpointSlices по умолчанию, но для Windows остался в альфа-версии) и .

kubeadm


Две новые фичи (в альфа-версии) представлены для утилиты kubeadm.

Первая — для модификации манифестов, генерируемых kubeadm. Их модификация уже с помощью Kustomize (в альфа-версии), однако разработчики kubeadm , что использование обычных патчей является более предпочтительным способом (поскольку Kustomize становится лишней зависимостью, что не приветствуется).

Теперь применение raw-патчей возможно (через флаг --experimental-patches) для команд kubeadm init, join и upgrade, а также их фаз. Реализацию на базе Kustomize (флаг --experimental-kustomize) объявят устаревшей и удалят.

Вторая фича — к работе с конфигами компонентов, с которыми работает kubeadm. Утилита генерирует, валидирует, устанавливает значения по умолчанию, хранит конфиги (в виде ConfigMaps) для таких компонентов кластера Kubernetes, как Kubelet и kube-proxy. Со временем стало ясно, что это приносит ряд сложностей: как различать конфиги, сгенерированные kubeadm или переданные пользователем (а если никак, то что делать с миграцией конфига)? Какие поля со значениями по умолчанию были автоматически сгенерированы, а какие — намеренно установлены?..

Для решения этих проблем и представлен большой , включающий в себя: отказ от выставления значений по умолчанию (это должны делать сами компоненты), делегацию валидации конфигов самим компонентам, подписывание каждого сгенерированного ConfigMap и т.п.

Прочие изменения


  • Статус GA получили 3 фичи в области аутентификации: , к определённым API (через admission-плагин NodeRestriction), клиентского сертификата Kubelet.
  • Также объявлен стабильным с измененным подходом к дедупликации (во избежание перегрузки кластера событиями);
  • Kubelet и стандартный Docker runtime запуск эфемерных контейнеров в пространстве имен процессов target-контейнера, определяемого полем TargetContainerName в EphemeralContainer (реализация в других исполняемых средах ожидается).
  • cri-containerd в Windows достигла бета-версии.

Изменения в зависимостях:

  • версия CoreDNS в составе kubeadm — 1.7.0;
  • cri-tools 1.18.0;
  • CNI (Container Networking Interface) 0.8.6;
  • etcd 3.4.9;
  • используемая версия Go — 1.15.0-rc.1.


P.S.


Читайте также в нашем блоге:

  • « »;
  • « »;
  • « »;
  • « ».
 
Сверху Снизу