В среду состоялся релиз Kubernetes 1.11. Продолжаем нашу традицию и рассказываем о наиболее значимых изменениях, основываясь на данных из CHANGELOG-1.11 и многочисленных issues, pull requests и design proposals. Что нового в K8s 1.11?

Сети


Начнём с сетей, поскольку анонс Kubernetes 1.11 ознаменовал официальную стабилизацию (т.е. перевод в статус General Availability) сразу двух важных нововведений, представленных в предыдущих релизах. Первое из них — балансировка нагрузки сервисов внутри кластера, основанная на IPVS (IP Virtual Server). Эта возможность пришла из компании Huawei, что весной прошлого года представила сообществу результаты своей работы по улучшению балансировки нагрузки на 50+ тысяч сервисов с помощью IPVS вместо iptables. Такой выбор объяснялся весьма логично: «Если iptables созданы для файрволов и основаны на списках правил в ядре, то IPVS создан для балансировки нагрузок и основан на хэш-таблицах в ядре; кроме того, IPVS поддерживает более продвинутые алгоритмы балансировки нагрузки, чем iptables, а также ряд других полезных возможностей (например, проверка состояния, повторные попытки и т.п.)».


Слайд из презентации «Scaling Kubernetes to Support 50,000 Services» от Huawei на KubeCon Europe 2017

Что это принесло на практике? «Лучшую пропускную способность сети, меньшую программную задержку [речь о времени, за которое новые endpoints добавляются в сервисы, — прим. перев.] и лучшую масштабируемость для балансировщика нагрузок в кластере». Альфа-версия режима IPVS для kube-proxy появилась в Kubernetes 1.8 и «доросла» до стабильной к нынешнему релизу 1.11: пусть по умолчанию он всё ещё не включён, но для обслуживания трафика в production-кластерах уже официально готов.

Вторая созревшая фича — CoreDNS в качестве DNS-сервера, используемого кластером Kubernetes. Подробнее об этом решении мы писали в отдельном обзоре, а если вкратце, то это гибкий и легко расширяемый DNS-сервер, изначально основанный на веб-сервере Caddy, ставший преемником SkyDNS (к слову, именно на нём основан и собственно kube-dns, на замену которому приходит CoreDNS), написанный на языке Go и ориентированный на мир облачных (cloud native) приложений. Примечательным CoreDNS делает и тот факт, что он представляется единственным исполняемым файлом и единственным процессом в системе. Теперь это не просто очередной вариант DNS для кластера Kubernetes, но и опция по умолчанию для kubeadm. Инструкция по использованию CoreDNS в Kubernetes доступна здесь (а для Cluster Federation — здесь).

Среди прочих обновлений в сетевом «мире» Kubernetes:

  • в NetworkPolicies теперь можно указывать определённые поды в других пространствах имён, используя namespaceSelector и podSelector;
  • сервисы теперь могут слушать одинаковые порты хоста на разных интерфейсах (указывается в --nodeport-addresses);
  • исправлен баг, из-за которого Kubelet при использовании --node-ip переставал сообщать ExternalDNS, InternalDNS и ExternalIP.

Хранилища


Представленная в Kubernetes 1.9 фича защиты от удаления PVCs (PersistentVolumeClaims), используемых какими-либо подами, и PVs (PersistentVolumes), привязанных к PVCs, позже (в K8s 1.10) получившая название StorageProtection, объявлена стабильной.

Возможность изменения размера тома (PVs) после рестарта пода переведена в статус бета-версии, а в рамках альфа-версии стало доступным изменение размера тома в режиме реального времени, т.е. без необходимости в перезагрузке пода.

В поддержке AWS EBS и GCE PD был увеличен лимит для максимально возможного количества подключённых к узлу томов, а в плагинах AWS EBS, Azure Disk, GCE PD и Ceph RBD реализовали поддержку динамического provisioning'а томов блочных raw-устройств. Для томов AWS EBS также добавлена возможность использования в подах в режиме ReadOnly.

Кроме того, в Kubernetes 1.11 появилась альфа-версия поддержки динамических лимитов на тома в зависимости от типа узла, а также представлена поддержка в API для блочных томов во внешних драйверах хранилищ CSI (Container Storage Interface — появился в Kubernetes 1.9). Вдобавок, для CSI реализовали интеграцию с новым механизмом регистрации плагинов Kubelet.

Узлы кластера


В топ-5 главных изменений релиза Kubernetes 1.11 также входит перевод в статус бета-версии динамической конфигурации Kubelet, впервые появившейся ещё в K8s 1.8 и требующей множественных изменений (отследить их можно в изначальном тикете по Dynamic Kubelet Configuration). Эта возможность позволяет выкатывать новые конфигурации Kubelet на «живых», работающих кластерах (в противовес прежней ситуации, когда настройки для Kubelet передавались через флаги командной строки). Для её использования необходимо установить опцию --dynamic-config-dir (при запуске Kubelet).

Объявлен стабильным проект cri-tools. Он предлагает инструменты для системных администраторов, которые позволяют анализировать и отлаживать работу узлов в production вне зависимости от используемой исполняемой среды для контейнеров. Пакеты с ним (crictl) теперь поставляются вместе с остальными утилитами kubeadm (в форматах DEB и RPM). Подробнее о предназначении и возможностях crictl мы писали в недавней статье об интеграции containerd с Kubernetes, заменяющей «традиционный» Docker.


Примеры использования crictl из документации проекта

Экспериментальная поддержка sysctls на Linux переведена в статус бета-версии (включается по умолчанию с помощью feature-флага Sysctls). У объектов PodSecurityPolicy и Pod появились специальные поля для указания/контроля sysctls.

Также в ResourceQuota появилась возможность указания класса приоритета (в таком случае квота применяется только к подам с этим классом — см. подробнее в design-proposals), а в статус пода добавлено условие ContainersReady.

Права и безопасность


Представленная в K8s 1.9 возможность ClusterRole Aggregation, позволяющая добавлять права (permissions) уже существующим (в том числе, создаваемым автоматически) ролям объявлена стабильной, не получив никаких изменений. Также была добавлена отдельная роль для cluster-autoscaler (ClusterRole) — она используется вместо системной (cluster-admin).

Ряд работ был проведён в направлении прозрачности того, что (и почему) происходит внутри кластера. В частности, информация по RBAC в audit-логах теперь содержит дополнительные аннотации к событиям:

  • authorization.k8s.io/decisionallow или forbid;
  • authorization.k8s.io/reason — понятная человеку причина принятого решения.

Также в audit-логи добавлена информация о допуске от PodSecurityPolicy в виде аннотаций podsecuritypolicy.admission.k8s.io/admit-policy и podsecuritypolicy.admission.k8s.io/validate-policy (какая политика допустила под?).

Консольные утилиты


Множество (пусть не столь значимых, но полезных!) улучшений представлено в CLI-инструментах для Kubernetes:

  • Новая команда kubectl wait для ожидания момента, когда указанные ресурсы будут удалены или достигнут определённого условия.
  • Новая команда kubectl api-resources для просмотра ресурсов:

  • Поддержка автодополнения для kubectl cp.
  • В Go-шаблонах kubectl стала доступной функция base64decode, название которой говорит за себя.
  • В kubectl patch добавлена поддержка флага --dry-run.
  • Флаг --match-server-version стал глобальным — его будет учитывать и kubectl version.
  • В kubectl config view --minify теперь учитывается глобальный флаг context.
  • В kubectl apply --prune добавлена поддержка ресурсов CronJob.

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


  • Планировщик (kube-scheduler) научился планировать поды в DaemonSet (альфа-версия).
  • Представлена возможность указания конкретной системной группы пользователей (RunAsGroup) для контейнеров в поде (альфа-версия).
  • Возможность удаления «сирот» (orphan delete) для CustomResources.
  • Улучшения в поддержке Kubernetes API для подов и контейнеров на Windows — добавлены метрики для подов, контейнеров и файловой системы с логами, scurity-контексты run_as_user, локальные постоянные тома и fstype для диска Azure.
  • Для Azure добавлена поддержка стандартного балансировщика нагрузки SKU и публичного IP.

Совместимость


  • Поддерживаемая версия etcd — 3.2.18 (в Kubernetes 1.10 была 3.1.12).
  • Проверенные версии Docker — от 1.11.2 до 1.13.1 и 17.03.x (не изменились с релиза K8s 1.10).
  • Версия Go — 1.10.2 (вместо 1.9.3), минимально поддерживаемая — 1.9.1.
  • Версия CNI — 0.6.0.
  • Версия CSI — 0.3.0 (вместо 0.2.0).

P.S.


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

Комментарии (3)


  1. rjeka
    29.06.2018 18:24
    +2

    Спасибо за обзор. В своих кластерах Вы использовали или тестировали работу IPVS, CoreDns или containerd?


    1. distol Автор
      30.06.2018 12:24
      +1

      Нет. Ни IPVS, ни CoreDNS, ни containerd не принесут какой-то конкретной пользы в наших кейсах.


      Более того, мы несколько застряли на 1.8, но сделали это вполне осознанно — на практике, в 1.8 нас все более-менее устраивает, и мы сейчас уделяем большую часть внимания другим вопросам. Однако, так-как в 1.11 наконец-то появился online PV resizing, мы скорей всего обновимся до конца лета.


      Из связанного с 1.11, мы считаем, что не так важно какой DNS, как важно его правильно поставить — если на каждое подключение к redis у нас добавляется дополнительный латенси на DNS resolve, то это прямо беда (понятно, что надо делать постоянные соединения, но замените пример с redis на что-то другое). Мы думаем над схемой, когда основной DNS стоит на каждом узле (DaemonSet) плюс запасной стоит в Deployment'е — такая схема убирает сетевой латенси, сохраняя при этом отказоустойчивость. Сделать такой вариант в отдельно взятом кластере, особенно развернутом вручную, не составляет никакого труда, а вот чтобы сделать универсальное решение, работающее в динамически масштабируемых кластерах на любом клауде и на железе, нужна возможность централизованного управления конфигами kubelet, которая в 1.11 значительно продвинулась.


      1. rjeka
        02.07.2018 08:44

        А вынос redis в StatefulSet частично не решит проблему с DNS?
        Интересно узнать какой cidr Вы используете в своих кластерах? В идеале бы хотелось бы в Вашем блоге почитать статью про сетевое взаимодействие в кластерах исходя из «боевого» опыта )))