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

Этой ночью, 5 августа (по американскому времени), состоится новый релиз Kubernetes — 1.22. Рассказываем о наиболее значимых изменениях в новой версии.

image-loader.svg

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

В новом релизе 56 улучшений. Из них:

  • 16 новых функций (alpha);

  • 24 продолжают улучшаться (beta);

  • 13 признаны стабильными (stable);

  • 3 перешли в статус «устаревших» (deprecation).

Достаточно много фич прямо или косвенно относятся к повышению уровня безопасности в Kubernetes — с них и начнем.

Безопасность

Pod Security Admission Control

На смену устаревшей в 1.21 PodSecurityPolicy пришел контроллер доступа PodSecurity admission controller, пока в альфа-версии. Теперь именно он определяет стандарты безопасности pod«ов на уровне пространства имен, ориентируясь на лейблы.

Новые политики работают в трех режимах:

  • принудительный (enforce): нарушение политик приводит к отказу в запуске pod«а;

  • проверочный (audit): нарушения вызывают добавление аннотации аудита, но допускаются;

  • предупредительный (warn): пользователь предупреждается о нарушениях, но они допускаются.

В одном пространстве имен можно применять несколько политик одновременно.

Пример настройки ресурса AdmissionConfiguration:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    defaults:  # Значения по умолчанию, если лейбл с режимом не задан
      enforce:         
      enforce-version: 
      audit:         
      audit-version: 
      warn:          
      warn-version:  
    exemptions: # Исключения из правил
      usernames:         [  ]
      runtimeClassNames: [  ]
      namespaces:        [  ]
...

В KEP перечислены основные причины, из-за которых пришлось отказаться от PodSecurityPolicy. Об этом также писали в блоге Kubernetes.

Seccomp by default

Seccomp by default — важная и долгожданная фича в статусе альфа, которая повышает безопасность «ванильного» Kubernetes. Теперь фильтрация системных вызовов автоматически включается при запуске любых контейнеров (в предыдущих версиях K8s это нужно делать вручную).

Seccomp — режим, при котором все неразрешенные системные вызовы блокируются. Это помогает избегать атак на узел или целый кластер через контейнер, а также повышает устойчивость K8s к zero day-уязвимостям. Подробнее об алгоритме работы новой фичи мы писали в этой новости.

Kubelet-in-UserNS (aka Rootless mode)

Kubelet-in-UserNS, он же rootless mode, — еще одна функция, которая помогает защищать от угроз, связанных с потенциальными уязвимостями в базовых компонентах Kubernetes, работающих на хосте (KEP). В rootless-режиме можно запускать kubelet, CNI, CRI, OCI и любые компоненты с приставкой «kube-» от имени обычных пользователей (т. е. не root). Пользователи shared-машин (отдельно упоминаются HPC-узлы — High Performance Computing) теперь могут разворачивать кластер и не переживать за безопасность коллег. Эксперименты для появления этой фичи проводились в рамках проекта Usernetes — в частности, его наработки используются в k3s.

Stable-фичи

Также некоторые функции, относящиеся к безопасности, достигли стабильного уровня:

Узлы

Node system swap support

Предложение включить в K8s поддержку свопинга памяти (подкачки страниц) для контейнеров появилось еще в 2015-м, но было отвергнуто. Повторно вопрос поднимали в 2017-м — с тем же итогом. К 2021-му сообщество наконец-таки созрело до того, чтобы реализовать альфа-версию Node system swap support (KEP-2400). Она помогает более гибко управлять производительностью узлов и контейнеров: swapping доступен на уровне хоста, узлов и конкретных рабочих нагрузок, а контролируется kubelet«ом.

Важную роль в добавлении функции сыграло расширение сценариев использования свопинга. В частности, авторы указывают на появление алгоритмов управления памятью вроде oomd, которые решают проблему out of memory в пользовательском пространстве (userspace). Для его корректной работы нужна поддержка свопинга.

Еще один распространенный сценарий — длительно работающее ПО (long-running applications). Например, среды выполнения Java и Node.js используют свопинг для улучшения производительности приложений.

Где еще может быть полезен свопинг:

  • on-premise и bare metal-инсталляции, когда наращивание памяти — недешевая и негибкая процедура;

  • развертывание кластера локально на хосте с быстрыми дисками — например, на ноутбуке с SSD;

  • развертывание кластера на устройствах с малым объемом ОЗУ.

Также подкачка страниц помогает снизить издержки при запуске кластера на виртуальных машинах (ВМ), например, через kubevirt. Некоторые рабочие нагрузки на ВМ периодически требуют дополнительной памяти, которая выделяется автоматически и иногда в больших количествах. Свопинг помогает избежать необязательного overhead«а во время скачкообразного потребления RAM.

New CPU Manager Policies

Важное обновление в политиках управления ресурсами ЦПУ: с помощью опций CPU Manager теперь можно более тонко распределять ресурсы процессора между рабочими нагрузками. В первую очередь новая фича пригодится для развертывания ПО, которое чувствительно к задержкам — например, приложений типа DPDK (Data Plane Development Kit). В то же время у приложений, которые не адаптированы под SMT (одновременную многопоточность), будет меньший приоритет, чем у SMT-native.

Текущая политика static распределяет ядра процессора между контейнерами без надежной гарантии того, что определенный контейнер действительно получит необходимые ресурсы. При этом, если разные контейнеры делят одно и то же физическое ядро, распределение его ресурсов между контейнерами невозможно предсказать — как и возникновение задержек. Для подобных ситуаций придумали метафору «шумные соседи» (noisy neighbors). Новые политики CPU Manager решают эту проблему.

Фича пока представлена в альфа-версии. Планируется, что она станет бета-версией в 1.24, стабильной — в 1.25. Инициатор KEP«а — сотрудник Red Hat Франческо Романи (Francesco Romani) — в этом треде подробно обосновывает необходимость нововведения.

Memory QoS with cgroups v2

В релизе 1.22 появились сразу две функции в статусе альфа, которые связаны с механизмом организации процессов ​​cgroups v2: его непосредственная поддержка, а также поддержка Memory QoS. (Об особенностях cgroups v2, представленных в Linux 2.6.24, можно почитать, например, здесь.)

Первые наработки по поддержке cgroups v2 появились ещё раньше, во времена релиза Kubernetes 1.18, но только теперь они получили всё необходимое (включая правки в документации) для начала применения.

QoS же ранее был доступен только для регулирования ресурсов CPU (например, через параметр cpu_shares), а теперь — и для памяти.

Для настройки Memory QoS доступно несколько параметров:

  • memory.min — минимальный объем памяти, который ​​cgroups всегда должен сохранять;

  • memory.max — максимальный, жёсткий предел по использованию памяти (финальный механизм защиты);

  • memory.low — защита памяти типа best-effort, т.е. «мягкая гарантия» того, что, если cgroup и все его потомки находятся ниже этого порога, эта память cgroup не будет освобождена (если только она не может быть получена из незащищенных ​​cgroup);

  • memory.high — если использование памяти превышает этот уровень, процессы cgroup throttle«ятся и принудительно высвобождаются.

Beta- и Stable-фичи

В предыдущем релизе появилась возможность менять размер томов emptyDir, которые хранятся в оперативной памяти. Теперь эта функция перешла в бета-версию.

Поддержка HugePages в downward API (KEP-1967) тоже получила повышение до уровня бета.

Функции, которые достигли версии stable:

  • поддержка HugePages на уровне контейнеров и возможность запрашивать страницы разного размера;

  • возможность задавать FQDN (Fully Qualified Domain Name) для хоста pod’а, что улучшает совместимость устаревших приложений с K8s.

Сеть

Expanded DNS configuration

Новая функция Expanded DNS configuration в альфа-версии расширяет возможности для настройки DNS. Теперь в K8s можно использовать больше путей поиска DNS и увеличить список этих путей, чтобы не отставать от последних тенденций DNS-сервисов в преобразовании доменных имен.

После активации feature gate MaxDNSSearchPathsExpanded меняются два параметра в настройках DNS:

Kube-proxy handling terminating endpoints

Сейчас сервисы с параметром externalTrafficPolicy=Local отбрасывают весь трафик балансировщика нагрузки, если количество endpoint«ов уменьшается до нуля. При таком подходе во время непрерывных обновлений (rolling updates) возможны простои.

Проблема решена благодаря реализации новой фичи «мягкого» управления трафиком — Graceful Termination for Local External Traffic Policy (пока тоже в альфе). Теперь во время отключения узла внешний трафик направляется на endpoint«ы со статусом Ready, а также Not ready. Это гарантирует, что трафик не будет отброшен между моментом, когда узел не проходит проверку работоспособности (нет endpoint«ов), и моментом, когда он удаляется из пула узлов балансировщика нагрузки.

Beta- и Stable-фичи

Бета-версий достигли два улучшения для сервисов типа LoadBalancer: возможность отключать NodePorts и возможность назначать один порт разным протоколам.

Поддержка режима dual-stack IPv4/IPv6 (KEP-563) также повысилась в статусе до бета.

Функции, которые перешли на уровень stable:

  • API EndpointSlice, который заменил предыдущий Core/V1 Endpoints;

  • поле AppProtocol в Services и Endpoints (реализация была полностью готова в прошлых релизах, но теперь завершили формальную стабилизацию, убрав соответствующий feature gate).

Также обратите внимание, что версия v1beta1 для Ingress API объявлена устаревшей (теперь используется v1).

Приложения

Job tracking without lingering Pods

Существующий Job-контроллер завершает job«ы постепенно, не удаляя pod«ы до тех пор, пока job«ы окончательно не завершатся. Это помогает контроллеру точнее отслеживать статус job. Ресурсы кластера освобождаются только после окончательного удаления pod«ов.

С новой функцией в альфа-версии job«ы получили возможность сразу удалять неиспользуемые pod«ы, чтобы быстрее освобождать ресурсы. Подробнее о новом алгоритме можно узнать в KEP-2307.

Allow DaemonSets to surge during update like Deployments

Поддержка опции Surge, т.е. «наращивания», для плавающих обновлений DaemonSet (RollingUpdateStrategy) появилась недавно, в релизе Kubernetes 1.20. Теперь фича перешла в статус бета. Работает функция примерно по тому же принципу, что в Deployment«е: при обновлениях типа RollingUpdate в дополнение к рабочим pod«ам запускаются «запасные», которые минимизируют возможный простой DaemonSet«ов. Простой может возникнуть, например, при скачивании и установке нового образа, потому что происходит это не мгновенно. Нужное количество дополнительных pod«ов задается в поле maxSurge — в «штуках», либо в процентах.

Add minReadySeconds to Statefulsets

И ещё одно новшество в альфа-версии — опция minReadySeconds для StatefulSets. Она позволяет указывать минимальное количество секунд, за которое новый созданный Pod должен стать Ready (при условии, что ни один из его контейнеров не упал).

Stable-фичи

  • CronJob API наконец-то признан стабильным (спустя 4 года с момента релиза в Kubernetes 1.8). По итогам продолжительного использования функции в альфа- и бета-статусах код CronJob API оптимизировали, чтобы улучшить масштабируемость и добавить новые метрики.

  • PodDisruptionBudget — еще одна фича-«ветеран», представленная как альфа-версия в Kubernetes 1.4 и стабилизированная только в 1.21. В нынешнем релизе стабильным признан родственный подресурс Eviction, который отвечает за вытеснение pod«ов. Именно он используется компонентами, которые хотят удалить pod«ы из-за нарушения ими бюджета.

Другие улучшения

API Server Tracing

Сейчас трассировка API-сервера в K8s довольно ограниченная: можно анализировать задержки операций и выявлять те, что превышают установленный лимит. Новая фича в альфа-версии — API Server Tracing (KEP-647) — предлагает расширить эти возможности с помощью стандарта распределенного трейсинга и мониторинга OpenTelemetry. Коллектор OpenTelemetry умеет собирать метрики и трейсы из множества источников и транслировать их в нужный пользователю формат: Prometheus, Jaeger, VictoriaMetrics и т. д.

Реализация в K8s подразумевает запуск коллектора OpenTelemetry в отдельном контейнере в качестве sidecar«а, DaemonSet«а или Deployment«а для API Server. Возможна комбинация, при которой DaemonSet собирает трейсы и пересылает их в Deployment для дальнейшего агрегирования в БД.

Появление фичи логично и ожидаемо: сложно добиться приемлемого уровня observability компонентов кластера, анализируя только лишь метрики и логи. Полноценная трассировка API Server облегчит диагностику проблем.

New RWO access mode

Одно из нововведений, которое относится к хранилищам, — режим доступа ReadWriteOncePod PersistentVolume (KEP-2485). RWOP работает для PersistentVolumes, которым нужно ограничить доступ к одиночному pod«у на одиночном узле. Для сравнения, существующий режим ReadWriteOnce (RWO) ограничивает доступ к одиночному узлу, но разрешает одновременный доступ к этому узлу из нескольких pod«ов.

Windows Privileged Containers and Host Networking Mode

Привилегированные контейнеры и возможность назначать таким контейнерам сеть хоста — опции, которые давно доступны в Kubernetes пользователям Linux. Привилегированные контейнеры используются, например, для запуска kube-proxy (через kubeadm), для некоторых задач хранения и сетевого взаимодействия, а также в других сценариях, когда нужен root-доступ к хосту. Многие из этих сценариев актуальны и для пользователей Windows. Новая фича Windows Privileged Containers and Host Networking Mode (KEP-1981) призвана удовлетворить этот запрос (пока в альфа-версии).

Kubeadm Config file graduation

Продолжается оптимизация формата конфигурационного файла kubeadm (KEP-970). Основная проблема с конфигом была в том, что количество опций, которые в нем настраиваются, со временем сильно выросло; в то же время количество параметров, которые можно регулировать через CLI, осталось прежним. В результате файл конфигурации был единственным способом создать кластер с несколькими специфическими вариантами использования.

Фича, которая расширила возможности настройки kubeadm, была представлена в альфа-версии в 1.15, и теперь получила очередные улучшения в рамках бета-версии (​​v1beta3). Среди изменений, которые появились в обновленной версии:

  • удалены устаревшия поля ClusterConfiguration.useHyperKubeImage и ClusterConfiguration.DNS.Type;

  • добавлены поля InitConfiguration.SkipPhases и JoinConfiguration.SkipPhases, чтобы пропускать ряд фаз во время выполнения команд для инициализации узла и присоединения к кластеру K8s (kubeadm init/join);

  • добавлены поля InitConfiguration.Patches.Directory и JoinConfiguration.Patches.Directory. В них можно указывать директорию с патчами для компонентов, которые разворачиваются с помощью kubeadm.

Beta- и Stable-фичи

Статус бета получила функция Priority and Fairness for API Server Requests (KEP-1040). Она улучшила механизм приоритизации и обработки запросов, которые поступают в API Server. Предыдущий механизм был слишком грубый, из-за чего могли отфильтровываться важные запросы.

Новый алгоритм активируется с помощью feature gate APIPriorityAndFairness. Типы запросов и приоритеты определяются в объекте FlowSchema. Пример настройки для низкоприоритетного сервиса (сборщика мусора):

kind: FlowSchema
meta:
  name: system-low
spec:
  matchingPriority: 900
  requestPriority:
    name: system-low
  flowDistinguisher:
    source: user
  match:
  - and:
    - equals:
      field: user
      value: system:controller:garbage-collector

Функции, которые достигли версии stable в Kubernetes 1.22:

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

Обновления в зависимостях Kubernetes:

  • cri-tools 1.21.0;

  • плагины CNI (Container Networking Interface) 0.9.1, Calico 3.19.1, CoreDNS 1.8.4;

  • etcd 3.5.0;

  • используемая версия Go — 1.16.6.

P. S.

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

© Habrahabr.ru