26 March

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

Флант corporate blogOpen sourceDevOpsKubernetes
Вчера, 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.

Стабильными объявлены:


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


Среди других новшеств в 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.


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

Tags:Kubernetes
Hubs: Флант corporate blog Open source DevOps Kubernetes
+46
9.4k 29
Comments 5