Вчера, 9 декабря, состоялся очередной релиз Kubernetes — 1.17. По сложившейся для нашего блога традиции, мы рассказываем о наиболее значимых изменениях в новой версии.
Информация, использованная для подготовки этого материала, взята из официального анонса, таблицы Kubernetes enhancements tracking, CHANGELOG-1.17 и соответствующих issues, pull requests, а также Kubernetes Enhancement Proposals (KEP). Итак, что нового?..
Маршрутизация с учётом топологии
Вот уже долгое время в сообществе Kubernetes ждали этой фичи — Topology-aware service routing. Если KEP по ней берёт своё начало в октябре 2018-го, а официальный enhancement — 2 года назад, то обычные issues (вроде этого) — и вовсе старше ещё на несколько лет…
Общая идея сводится к тому, чтобы предоставить возможность реализовывать «локальную» маршрутизацию для сервисов, находящихся в Kubernetes. «Локальность» в данном случае означает «тот же самый топологический уровень» (topology level), коим может являться:
одинаковый для сервисов узел,
та же самая серверная стойка,
тот же самый регион,
тот же самый облачный провайдер,
…
Примеры использования такой фичи:
экономия на трафике в облачных инсталляциях со множеством зон доступности (multi-AZ) — см. свежую иллюстрацию на примере трафика одного региона, но разных AZ в AWS;
меньшие задержки в производительности/лучшая пропускная способность;
шардированный сервис, имеющий локальную информацию об узле в каждом шарде;
размещение fluentd (или аналогов) на один узел с приложениями, логи которых собираются;
Подробности о том, как фича устроена и как ей уже можно воспользоваться, читайте в этой статье от одного из авторов.
Поддержка двойного стека IPv4/IPv6
Значительный прогресс зафиксирован в другой сетевой фиче: одновременной поддержке двух IP-стеков, что была впервые представлена в K8s 1.16. В частности, новый релиз принёс следующие изменения:
в kube-proxy реализована возможность одновременной работы в обоих режимах (IPv4 и IPv6);
в Pod.Status.PodIPsпоявилась поддержка downward API (одновременно с этим в /etc/hosts теперь требуют для хоста добавлять и IPv6-адрес);
поддержка двух стеков в KIND (Kubernetes IN Docker) и kubeadm;
обновлённые e2e-тесты.
Иллюстрация использования двойного стека IPV4/IPv6 в KIND
Инициатива по миграции плагинов томов на CSI — CSI Migration — достигла бета-версии. Эта фича критична для того, чтобы перевести существующие плагины хранилищ (in-tree) на современный интерфейс (CSI, out-of-tree) незаметно для конечных пользователей Kubernetes. Администраторам кластеров будет достаточно активировать CSI Migration, после чего существующие stateful-ресурсы и рабочие нагрузки будут по-прежнему «просто работать»… но уже с использованием актуальных CSI-драйверов вместо устаревших, входящих в ядро Kubernetes.
На данный момент в статусе бета-версии готова миграция для драйверов AWS EBS (kubernetes.io/aws-ebs) и GCE PD (kubernetes.io/gce-pd). Прогнозы по другим хранилищам таковы:
О том, как «традиционная» поддержка хранилищ в K8s пришла к CSI, мы рассказывали в этой статье. А переходу миграции CSI в статус бета-версии посвящена отдельная публикация в блоге проекта.
Кроме того, статуса бета-версии (т.е. включения по умолчанию) в релизе Kubernetes 1.17 достигла другая значимая функциональность в контексте CSI, берущая своё начало (альфа-реализацию) в K8s 1.12, — создание снапшотов и восстановление из них. Среди изменений, произведённых в Kubernetes Volume Snapshot на пути к бета-релизу:
разбивка sidecar’а CSI external-snapshotter на два контроллера,
добавлен секрет на удаление (deletion secret) как аннотация к содержимому снапшота тома,
новый финализатор (finalizer) для предотвращения удаления API-объекта снапшота при наличии оставшихся связей.
На момент релиза 1.17 фича поддерживается у трёх CSI-драйверов: GCE Persistent Disk CSI Driver, Portworx CSI Driver и NetApp Trident CSI Driver. Подробнее о её реализации и использовании можно прочитать в этой публикации в блоге.
Cloud Provider Labels
Лейблы, которые автоматически назначаются на создаваемые узлы и тома в зависимости от используемого облачного провайдера, были доступны в Kubernetes как бета-версия уже очень давно — начиная с релиза K8s 1.2 (апрель 2016 года!). Учитывая их широкое применение так долго, разработчики решили, что настало время объявить фичу стабильной (GA).
Посему все они были переименованы соответствующим образом (по топологиям):
… но по-прежнему доступны и по своим старым названиям (для обратной совместимости). Впрочем, всем администраторам рекомендуется переходить на актуальные лейблы. Соответствующая документация K8s была обновлена.
Мотивация к реализации этой фичи (согласно KEP) такова:
Хоть Kubernetes и может быть развёрнут вручную, стандартом де-факто (если не де-юре) для этой операции является использование kubeadm. Популярные инструменты управления системами вроде Terraform опираются на kubeadm для деплоя Kubernetes. Запланированные улучшения в Cluster API включают в себя компонуемый пакет для bootstrapping’а Kubernetes с kubeadm и cloud-init.
Без структурированного вывода даже самые безобидные на первый взгляд изменения могут сломать Terraform, Cluster API и другой софт, использующий результаты работы kubeadm.
В ближайших планах значится поддержка (в виде структурированного вывода) для следующих команд kubeadm:
alpha certs
config images list
init
token create
token list
upgrade plan
version
Иллюстрация JSON-ответа на команду kubeadm init -o json:
Вообще же, релиз Kubernetes 1.17 состоялся под девизом «Стабильность». Тому способствовал тот факт, что очень многие фичи в нём (их общее количество — 14) получили статус GA. Среди таковых:
«защита финализатора» (Finalizer Protection) для балансировщиков нагрузки (проверка соответствующих ресурсов Service’а перед удалением ресурсов LoadBalancer’а);
оптимизация kube-apiserver в производительности при работе со множеством watches, наблюдащих за идентичными наборами объектов, — достигается благодаря избегаю повторной сериализации одних и тех же объектов ддя каждого watcher’а.
Прочие изменения
Полный список новшеств в Kubernetes 1.17, конечно, не ограничивается перечисленными выше. Вот некоторые другие из них (а для более полного перечня — см. CHANGELOG):
аналогичное изменение постигло EndpointSlice API (тоже из K8s 1.16), однако пока это решение для улучшенеия производительности/масштабируемости Endpoint API не активировано по умолчанию;