Флант corporate blog
Open source
IT Infrastructure
DevOps
Kubernetes
18 September

Kubernetes 1.16: обзор основных новшеств



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

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

Узлы


По-настоящему большое число заметных нововведений (в статусе альфа-версии) представлено на стороне узлов K8s-кластеров (Kubelet).

Во-первых, представлены так называемые «эфемерные контейнеры» (Ephemeral Containers), призванные упростить процессы отладки в pod'ах. Новый механизм позволяет запускать специальные контейнеры, которые стартуют в пространстве имён существующих pod'ов и живут непродолжительное время. Их предназначение — взаимодействие с другими pod'ами и контейнерами в целях решения каких-либо проблем и отладки. Для этой возможности реализована новая команда kubectl debug, схожая по своей сути с kubectl exec: только вместо запуска процесса в контейнере (как в случае exec) она запускает контейнер в pod'е. Например, такая команда подсоединит новый контейнер к pod'у:

kubectl debug -c debug-shell --image=debian target-pod -- bash

Подробности об эфемерных контейнерах (и примеры их использования) можно найти в соответствующем KEP. Текущая реализация (в K8s 1.16) — альфа-версия, а среди критериев её перевода в бета-версию значится «тестирование Ephemeral Containers API на протяжении не менее 2 релизов [Kubernetes]».

NB: По своей сути и даже названию фича напоминает уже существующий плагин kubectl-debug, о котором мы уже писали. Предполагается, что с появлением эфемерных контейнеров развитие отдельного внешнего плагина прекратится.

Другое новшество — PodOverhead — призвано предоставить механизм подсчёта накладных расходов на pod'ы, которые могут сильно отличаться в зависимости от используемой исполняемой среды (runtime). В качестве примера авторы этого KEP приводят Kata Containers, которые требуют запуска гостевого ядра, агента kata, init-системы и т.п. Когда overhead становится таким большим, его нельзя игнорировать, а значит — требуется способ учитывать его для дальнейшего квотирования, планирования и т.п. Для его реализации в PodSpec добавлено поле Overhead *ResourceList (сопоставляется с данными в RuntimeClass, если таковой используется).

Ещё одно заметное нововведение — менеджер топологии узла (Node Topology Manager), призванный унифицировать подход к тонкой настройке распределения аппаратных ресурсов для различных компонентов в Kubernetes. Эта инициатива вызвана растущей потребностью различных современных систем (из области телекоммуникаций, машинного обучения, финансовых услуг и т.п.) в высокопроизводительных параллельных вычислениях и минимизации задержек при исполнении операций, для чего они используют продвинутые возможности CPU и аппаратного ускорения. Такие оптимизации в Kubernetes до сих пор достигались благодаря разрозненным компонентам (CPU manager, Device manager, CNI), а теперь им добавят единый внутренний интерфейс, который унифицирует подход и упростит подключение новых аналогичных — так называемых topology-aware — компонентов на стороне Kubelet. Подробности — в соответствующем KEP.


Схема компонентов Topology Manager

Следующая фича — проверка контейнеров во время их запуска (startup probe). Как известно, для контейнеров, что долго запускаются, затруднительно получить актуальный статус: их либо «убивают» ещё до реального начала функционирования, либо они на долгое время попадают в deadlock. Новая проверка (включается через feature gate под названием StartupProbeEnabled) отменяет — точнее, откладывает — действие любых других проверок до того момента, когда pod закончил свой запуск. По этой причине фичу изначально называли pod-startup liveness-probe holdoff. Для pod'ов, что долго стартуют, можно проводить опрос состояния в относительно короткие временные интервалы.

Кроме того, сразу в статусе бета-версии представлено улучшение для RuntimeClass, добавляющее поддержку «гетерогенных кластеров». C RuntimeClass Scheduling теперь вовсе не обязательно каждому узлу иметь поддержку каждого RuntimeClass'а: для pod'ов можно выбирать RuntimeClass, не думая о топологии кластера. Раньше для достижения этого — чтобы pod'ы оказывались на узлах с поддержкой всего им нужного — приходилось назначать соответствующие правила к NodeSelector и tolerations. В KEP рассказывается о примерах использования и, конечно же, подробностях реализации.

Сеть


Две значимые сетевые фичи, что появились впервые (в альфа-версии) в Kubernetes 1.16 — это:

  • Поддержка двойного сетевого стека — IPv4/IPv6 — и соответствующее его «понимание» на уровне pod'ов, узлов, сервисов. Она включает в себя взаимодействие IPv4-to-IPv4 и IPv6-to-IPv6 между pod'ами, с pod'ов во внешние сервисы, эталонные реализации (в рамках плагинов Bridge CNI, PTP CNI и Host-Local IPAM), а также обратную совместимость с кластерами Kubernetes, работающими только по IPv4 или IPv6. Подробности реализации — в KEP.

    Пример вывода IP-адресов двух видов (IPv4 и IPv6) в списке pod'ов:

    kube-master# kubectl get pods -o wide
    NAME               READY     STATUS    RESTARTS   AGE       IP                          NODE
    nginx-controller   1/1       Running   0          20m       fd00:db8:1::2,192.168.1.3   kube-minion-1
    kube-master#

  • Новый API для EndpointEndpointSlice API. Он решает проблемы существующего Endpoint API с производительностью/масштабируемостью, что затрагивают различные компоненты в control-plane (apiserver, etcd, endpoints-controller, kube-proxy). Новый API будет добавлен в API-группу Discovery и сможет обслуживать десятки тысяч backend endpoint'ов на каждом сервисе в кластере, состоящем из тысячей узлов. Для этого каждый Service отображается в N объектов EndpointSlice, каждый из которых по умолчанию имеет не более 100 endpoint'ов (значение настраивается). В EndpointSlice API предусмотрят и возможности для его будущего развития: поддержки множества IP-адресов у каждого pod'а, новых состояний для endpoint'ов (не только Ready и NotReady), динамического subsetting для endpoint'ов.

До бета-версии продвинулся представленный в прошлом релизе finalizer, названный service.kubernetes.io/load-balancer-cleanup и прикрепляемый к каждому сервису с типом LoadBalancer. В момент удаления такого сервиса он предотвращает фактическое удаление ресурса, пока не завершена «зачистка» всех соответствующих ресурсов балансировщика.

API Machinery


Настоящая «веха стабилизации» зафиксирована в области API-сервера Kubernetes и взаимодействия с ним. Во многом это случилось благодаря переводу в статус stable не нуждающихся в особом представлении CustomResourceDefinitions (CRD), что имели статус бета-версии со времён далёкого Kubernetes 1.7 (а это июнь 2017 года!). Такая же стабилизация пришла и к связанным с ними фичам:


Ещё один механизм, давно ставший привычным для администраторов Kubernetes: admission webhook — тоже долгое время пребывал в статусе беты (с K8s 1.9) и теперь объявлен стабильным.

Две другие фичи достигли бета-версии: server-side apply и watch bookmarks.

А единственным значимым нововведением в альфа-версии стал отказ от SelfLink — специального URI, представляющего указанный объект и являющегося частью ObjectMeta и ListMeta (т.е. частью любого объекта в Kubernetes). Зачем от него отказываются? Мотивация «по-простому» звучит как отсутствие настоящих (непреодолимых) причин для того, чтобы это поле по-прежнему существовало. Более формальные причины — оптимизировать производительность (убрав ненужное поле) и упростить работу generic-apiserver, который вынужден обрабатывать такое поле особым образом (это единственное поле, которое устанавливается прямо перед сериализацией объекта). Настоящее «устаревание» (в рамках бета-версии) SelfLink произойдет к версии Kubernetes 1.20, а окончательное — 1.21.

Хранение данных


Основная работа в области storage, как и в прошлых релизах, наблюдается в области поддержки CSI. Главными изменениями здесь стали:

  • впервые (в альфа-версии) появилась поддержка CSI-плагинов для рабочих узлов с Windows: актуальный способ работы с хранилищами и здесь придёт на смену плагинам in-tree в ядре Kubernetes и FlexVolume-плагинам от Microsoft на базе Powershell;


    Схема реализации CSI-плагинов в Kubernetes для Windows
  • возможность изменения размера CSI-томов, представленная ещё в K8s 1.12, доросла до бета-версии;
  • аналогичного «повышения» (с альфа- до бета-версии) достигла возможность использования CSI для создания локальных эфемерных томов (CSI Inline Volume Support).

Появившаяся в прошлой версии Kubernetes функция клонирования томов (использование существующих PVC в качестве DataSource для создания новых PVC) тоже теперь получила статус бета-версии.

Планировщик


Два заметных изменения в планировании (оба в альфа-версии):

  • EvenPodsSpreading — возможность использовать для «честного распределения» нагрузок pod'ы вместо логических единиц приложения (вроде Deployment и ReplicaSet) и регулировки этого распределения (как жёсткого требования или как мягкого условия, т.е. приоритета). Фича расширит имеющиеся возможности распределения планируемых pod'ов, ныне ограниченные опциями PodAffinity и PodAntiAffinity, предоставив администраторам более тонкий контроль в этом вопросе, а значит — лучшую высокую доступность и оптимизированное потребление ресурсов. Подробности — в KEP.
  • Использование BestFit Policy в RequestedToCapacityRatio Priority Function во время планирования pod'ов, что позволит применять bin packing («упаковку в контейнеры») как для основных ресурсов (процессор, память), так и расширенных (вроде GPU). Подробнее см. в KEP.


    Планирование pod'ов: до использования best fit policy (напрямую через default scheduler) и с её использованием (через scheduler extender)

Кроме того, представлена возможность создавать свои плагины для планировщика вне основного дерева разработки Kubernetes (out-of-tree).

Другие изменения


Также в релизе Kubernetes 1.16 можно отметить инициативу по приведению имеющихся метрик в полный порядок, а если точнее — в соответствие с официальными предписаниями к инструментации K8s. Они по большому счёту опираются на соответствующую документацию Prometheus. Несыстоковки же образовались по разным причинам (например, некоторые метрики были попросту созданы ещё до того, как текущие инструкции появились), и разработчики решили, что настало время привести всё к единому стандарту, «в соответствие с остальной экосистемой Prometheus». Текущая реализация этой инициативы носит статус альфа-версии, который будет последовательно повышаться в последующих версиях Kubernetes до беты (1.17) и стабильного (1.18).

Кроме того, можно отметить следующие изменения:

  • Развитие поддержки Windows с появлением утилиты Kubeadm для этой ОС (альфа-версия), возможностью RunAsUserName для Windows-контейнеров (альфа-версия), улучшением поддержки Group Managed Service Account (gMSA) до бета-версии, поддержкой mount/attach для томов vSphere.
  • Переработанный механизм сжатия данных в ответах API. Раньше для этих целей использовался HTTP-фильтр, который накладывал ряд ограничений, препятствующих его включению по умолчанию. Теперь работает «прозрачное сжатие запросов»: клиенты, отправляющие Accept-Encoding: gzip в заголовке, получают сжатый в GZIP ответ, если его размер превышал 128 Кб. Клиенты на Go автоматически поддерживают сжатие (отправляют нужный заголовок), так что сразу заметят снижение трафика. (Для других языков могут потебоваться небольшие модификации.)
  • Стало возможным масштабирование HPA из/до нуля pod'ов на основе внешних метрик. Если масштабирование производится на основе объектов/внешних метрик, то когда рабочие нагрузки простаивают, можно автоматически масштабироваться до 0 реплик, чтобы сэкономить ресурсы. Особенно полезной эта фича должна оказаться для случаев, когда worker'ы запрашивают ресурсы GPU, а количество различных типов простаивающих worker'ов превышает число доступных GPU.
  • Новый клиент — k8s.io/client-go/metadata.Client — для «обобщённого» доступа к объектам. Он предназначен для того, чтобы легко получать метаданные (т.е. подраздел metadata) из ресурсов кластера и осуществлять с ними операции из разряда сбора мусора и квотирования.
  • Собирать Kubernetes теперь можно без устаревших («встроенных» в in-tree) облачных провайдеров (альфа-версия).
  • В утилиту kubeadm добавили экспериментальную (альфа-версия) возможность применять патчи kustomize во время операций init, join и upgrade. Подробнее о том, как пользоваться флагом --experimental-kustomize, см. в KEP.
  • Новый endpoint для apiserver — readyz, — позволяющий экспортировать информацию о его готовности (readiness). Также у API-сервера появился флаг --maximum-startup-sequence-duration, позволяющий регулировать его перезапуски.
  • Две фичи для Azure объявлены стабильными: поддержка зон доступности (Availability Zones) и cross resource group (RG). Кроме того, в Azure добавлены:
  • У AWS появилась поддержка для EBS в Windows и оптимизированы API-вызовы EC2 DescribeInstances.
  • Kubeadm теперь самостоятельно мигрирует конфигурацию CoreDNS при обновлении версии CoreDNS.
  • Бинарники etcd в соответствующем Docker-образе сделали world-executable, что позволяет запускать этот образ без необходимости в правах root. Кроме того, образ миграции etcd прекратил поддержку версии etcd2.
  • В Cluster Autoscaler 1.16.0 перешли на использование distroless в качестве базового образа, улучшили производительность, добавили новых облачных провайдеров (DigitalOcean, Magnum, Packet).
  • Обновления в используемом/зависимом программном обеспечении: Go 1.12.9, etcd 3.3.15, CoreDNS 1.6.2.

P.S.


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


+35
8.9k 37
Leave a comment