Прим. перев.: 16 мая этого года — значимая веха в развитии менеджера пакетов для Kubernetes — Helm. В этот день был представлен первый альфа-релиз будущей крупной версии проекта — 3.0. Её выход принесёт в Helm существенные и долгожданные изменения, на которые многие в Kubernetes-сообществе возлагают большие надежды. К таковым относимся и мы сами, поскольку активно используем Helm для деплоя приложений: мы интегрировали его в свой инструмент для реализации CI/CD werf и от случая к случая вносим посильный вклад в развитие upstream. Этот перевод объединяет 7 заметок из официального блога Helm, что приурочены к первому альфа-релизу Helm 3 и рассказывают об истории проекта и основных фичах Helm 3. Их автор — Matt «bacongobbler» Fisher, сотрудник Microsoft и один из ключевых мейнтейнеров Helm.
15 октября 2015 года родился проект, ныне известный как Helm. Всего через год после основания сообщество Helm присоединилось к Kubernetes, попутно активно работая над Helm 2. В июне 2018 года Helm вошел в состав CNCF в качестве развивающегося (incubating) проекта. Перенесемся в настоящее — и вот уже на подходе первый альфа-релиз нового Helm 3 (этот релиз уже состоялся в середине мая — прим. перев.).
В этой этом материале я расскажу о том, с чего все начиналось, как мы дошли до нынешней стадии, представлю некоторые уникальные особенности, доступные в первом альфа-релизе Helm 3, и объясню, как мы планируем развиваться дальше.
Краткое содержание:
история создания Helm;
нежное прощание с Tiller’ом;
репозитории чартов;
управление релизами;
изменения в зависимостях чартов;
library charts;
что дальше?
История создания Helm
Рождение
Helm 1 начинался как Open Source-проект, созданный компанией Deis. Мы были небольшим стартапом, поглощенным Microsoft весной 2017 года. У нашего другого Open Source-проекта, также носящего имя Deis, был инструмент deisctl, который использовался (кроме прочего) для установки и эксплуатации платформы Deis в кластере Fleet. В то время Fleet был одной из первых платформ для оркестровки контейнеров.
В середине 2015-го мы решили сменить курс и перевели Deis (на тот момент переименованный в Deis Workflow) с Fleet на Kubernetes. Одним из первых был переработан инструмент установки deisctl. Мы использовали его для инсталляции и управления Deis Workflow в кластере Fleet.
Helm 1 был создан по образу и подобию известных пакетных менеджеров, таких как Homebrew, apt и yum. Его основной задачей являлось упрощение таких задач, как упаковка и инсталляция приложений в Kubernetes. Официально Helm был представлен в 2015 году на конференции KubeCon в Сан-Франциско.
Наша первая попытка с Helm сработала, однако не обошлось без серьезных ограничений. Он брал набор манифестов Kubernetes, сдобренных генераторами в качестве вводных YAML-блоков (front-matter)*, и загружал результаты в Kubernetes.
* Прим. перев.: С первой версии Helm для описания ресурсов Kubernetes был выбран синтаксис YAML, а при написании конфигураций поддерживались шаблоны Jinja и Python-скрипты. Подробнее об этом и устройстве первой версии Helm вообще мы писали в главе «Краткая история Helm» этого материала.
Например, чтобы заменить поле в YAML-файле, нужно было добавить в манифест следующую конструкцию:
#helm:generate sed -i -e s|ubuntu-debootstrap|fluffy-bunny| my/pod.yaml
Классно, что сегодня существуют шаблонизаторы, не правда ли?
По многим причинам этот ранний Kubernetes-инсталлятор требовал жестко прописанный список манифест-файлов и выполнял только небольшую фиксированную последовательность событий. Пользоваться им было настолько тяжело, что R&D-команде Deis Workflow пришлось несладко, когда они попытались перевести свой продукт на эту платформу — впрочем, семена идеи уже были посеяны. Наша первая попытка стала отличной возможностью для обучения: мы осознали, что по-настоящему увлечены созданием прагматичных инструментов, решающих повседневные проблемы для наших пользователей.
Опираясь на опыт прошлых ошибок, мы приступили к разработке Helm 2.
Создание Helm 2
В конце 2015 года с нами связалась команда Google. Они работали над похожим инструментом для Kubernetes. Deployment Manager для Kubernetes был портом существующего инструмента, который использовался для Google Cloud Platform. «Не хотим ли мы, — спросили они, — потратить несколько дней на обсуждение сходств и различий?»
В январе 2016 команды Helm’а и Deployment Manager’а встретились в Сиэтле, чтобы обменяться идеями. Переговоры завершились амбициозным планом: объединить оба проекта, чтобы создать Helm 2. Вместе с Deis и Google к команде разработчиков присоединились парни из SkippBox(ныне входит в состав Bitnami — прим. перев.), и мы приступили к работе над Helm 2.
Мы хотели сохранить простоту использования Helm, но добавить следующее:
шаблоны чартов для кастомизации;
внутрикластерное управление для команд;
первоклассный репозиторий чартов;
стабильный формат пакетов с возможностью подписи;
твердую приверженность семантическому версионированию и сохранению обратной совместимости между версиями.
Для достижения этих целей в экосистему Helm был добавлен второй элемент. Этот внутрикластерный компонент назывался Tiller и занимался инсталляцией Helm-чартов и их управлением.
С момента выхода Helm 2 в 2016-м Kubernetes оброс несколькими серьезными нововведениями. Появилось управление доступом на основе ролей (RBAC), которое в конечном итоге заменило контроль доступа на основе атрибутов (ABAC). Были представлены новые типы ресурсов (Deployments в то время по-прежнему оставались в статусе бета-версии). Были изобретены Custom Resource Definitions (изначально они назывались Third Party Resources или TPRs). А самое главное — появился набор лучших практик.
На фоне всех этих изменений Helm продолжал служить верой и правдой пользователям Kubernetes. После трех лет и множества новых дополнений стало ясно, что пора вносить существенные изменения в кодовую базу, чтобы Helm и дальше мог удовлетворять растущие потребности развивающейся экосистемы.
Нежное прощание с Tiller’ом
Во время разработки Helm 2 мы представили Tiller как часть нашей интеграции с Deployment Manager’ом от Google. Tiller играл важную роль для команд, работающих в рамках общего кластера: он позволял различным специалистам, эксплуатирующим инфраструктуру, взаимодействовать с одним и тем же набором релизов.
Поскольку контроль доступа на основе ролей (RBAC) был по умолчанию включен в Kubernetes 1.6, работа с Tiller’ом в production становилась сложнее. Из-за огромного числа возможных политик безопасности наша позиция состояла в том, чтобы по умолчанию предлагать разрешительную конфигурацию. Это позволяло новичкам проводить эксперименты с Helm и Kubernetes без необходимости сначала погружаться в настройки безопасности. К сожалению, эта разрешительная конфигурация могла наделить пользователя слишком широким диапазоном разрешений, которые ему не были нужны. DevOps- и SRE-инженерам приходилось изучать дополнительные эксплуатационные шаги, устанавливая Tiller в многопользовательский (multi-tenant) кластер.
Узнав, как представители сообщества используют Helm в конкретных ситуациях, мы поняли, что системе управления релизами Tiller’а не нужно полагаться на внутрикластерный компонент, чтобы поддерживать состояния или функционировать в качестве центрального хаба с информацией о релизе. Вместо этого мы могли бы просто получать информацию от API-сервера Kubernetes, генерировать чарт на стороне клиента и сохранять запись об установке в Kubernetes.
Основную задачу Tiller’а можно было осуществить и без Tiller’а, поэтому одним из первых наших решений в отношении Helm 3 стал полный отказ от Tiller’а.
С уходом Tiller’а модель безопасности Helm радикально упростилась. Helm 3 теперь поддерживает все современные способы безопасности, идентификации и авторизации нынешнего Kubernetes. Разрешения Helm определяются с помощью файла kubeconfig. Администраторы кластера могут ограничивать права пользователей с любой степенью детализации. Релизы по-прежнему сохраняются внутри кластера, остальная функциональность Helm сохраняется.
Репозитории чартов
На высоком уровне репозиторий чартов — это место, где можно хранить и совместно использовать чарты. Клиент Helm пакует и отправляет чарты в репозиторий. Проще говоря, репозиторий чартов — это примитивный HTTP-сервер с файлом index.yaml и некоторыми упакованными чартами.
Хотя есть некоторые преимущества в том, что API репозитория чартов отвечает наиболее основным требованиям к хранилищу, у него есть и несколько недостатков:
Репозитории чартов плохо совместимы с большинством реализаций безопасности, необходимых в production-окружении. Наличие стандартного API для аутентификации и авторизации крайне важно в production-сценариях.
Инструменты Helm’а для отслеживания происхождения чарта, используемые для подписи, проверки целостности и происхождения чарта, являются необязательной частью процесса публикации Chart’а.
В многопользовательских сценариях один и тот же чарт может быть загружен другим пользователем, в два раза увеличивая объем пространства, необходимый для хранения одного и того же контента. Для решения этой проблемы были разработаны более умные репозитории, однако они не являются частью формальной спецификации.
Использование единого индекс-файла для поиска, хранения метаданных и получения чартов усложнило разработку безопасных многопользовательских реализаций.
Проект Docker Distribution (также известный как Docker Registry v2) является преемником Docker Registry и фактически выступает набором инструментов для упаковки, отправки, хранения и поставки образов Docker. Многие крупные облачные сервисы предлагают продукты на основе Distribution. Благодаря такому повышенному вниманию проект Distribution выиграл от многолетних усовершенствований, лучших практик в области безопасности и тестирования в «боевых» условиях, превративших его в одного из самых успешных невоспетых героев мира Open Source.
Но знаете ли вы, что проект Distribution был разработан для распространения любой формы контента, а не только образов контейнеров?
Благодаря усилиям Open Container Initiative (или OCI), Helm-чарты могут быть размещены на любом экземпляре Distribution. Пока этот процесс носит экспериментальный характер. Работа над поддержкой логинов и другими функции, необходимыми для полноценного Helm 3, еще не окончена, но мы очень рады возможности учиться на открытиях, сделанных командами OCI и Distribution за эти годы. А благодаря их наставничеству и руководству мы узнаём, что такое эксплуатация высокодоступного сервиса в большом масштабе.
Более подробное описание некоторых предстоящих изменений в репозиториях Helm-чартов доступно по ссылке.
Управление релизами
В Helm 3 состояние приложения отслеживается внутри кластера парой объектов:
release object — представляет экземпляр приложения;
release version secret — представляет желаемое состояние приложения в конкретный момент времени (например, релиз новой версии).
Вызов helm install создает release object и release version secret. Вызов helm upgrade требует наличия release object (который он может менять) и создает новый release version secret, содержащий новые значения и подготовленный манифест.
Release object содержит информацию о релизе, где релиз — конкретная инсталляция именованного чарта и значений. Этот объект описывает метаданные верхнего уровня о релизе. Release object сохраняется в течение всего жизненного цикла приложения и выступает владельцем всех release version secret’ов, а также всех объектов, которые непосредственно создаются Helm-чартом.
Release version secret связывает релиз с серией ревизий (инсталляция, обновления, откаты, удаление).
В Helm 2 ревизии были исключительно последовательными. Вызов helm install создавал v1, последующее обновление (upgrade) — v2, и так далее. Release и release version secret были свернуты в единый объект, известный как revision. Revision’ы хранились в том же пространстве имен, что и Tiller, что означало, что каждый релиз был «глобален» в плане пространства имен; в результате можно было использовать только один экземпляр имени.
В Helm 3 каждый релиз связан с одним или несколькими release version secret’ами. Release object всегда описывает текущий релиз, развернутый в Kubernetes. Каждый release version secret описывает только одну версию этого релиза. Обновление (upgrade), например, создаст новый release version secret и затем изменит release object, чтобы тот указывал на эту новую версию. В случае отката (rollback) можно использовать предыдущие release version secret’ы, чтобы откатить релиз к предыдущему состоянию.
После отказа от Tiller’а Helm 3 хранит данные о релизе в едином с релизом пространстве имен. Подобное изменение позволяет инсталлировать чарт с таким же именем релиза в другое пространство имен, и данные сохраняются между обновлениями/перезагрузками кластера в etcd. Например, можно установить WordPress в пространство имен «foo», а затем в пространство имен «bar», и оба релиза могут называться «wordpress».
Изменения в зависимостях чартов
Чарты, упакованные (с помощью helm package) для использования с Helm 2, можно инсталлировать с Helm 3, однако рабочий процесс разработки чартов был полностью пересмотрен, поэтому необходимо внести некоторые изменения, чтобы продолжить разработку чартов с Helm 3. В частности, изменилась система управления зависимостями чартов.
Система управления зависимостями чарта перешла с requirements.yaml и requirements.lock на Chart.yaml и Chart.lock. Это означает, что чарты, использовавшие команду helm dependency, требуют некоторой настройки, чтобы работать в Helm 3.
Давайте рассмотрим пример. Добавим зависимость к чарту в Helm 2 и посмотрим, что изменится при переходе к Helm 3.
В Helm 2 requirements.yaml выглядел следующим образом:
Чарты по-прежнему загружаются и помещаются в директорию charts/, поэтому субчарты (subcharts), лежащие в каталоге charts/, продолжат работать без изменений.
Представляем Library Charts
Helm 3 поддерживает класс чартов, получивший название чартов-библиотек (library chart). Этот чарт используется другими чартами, но самостоятельно не создает никаких артефактов релиза. Шаблоны library chart’ов могут объявлять только элементы define. Иной контент попросту игнорируется. Это позволяет пользователям повторно использовать и обмениваться фрагментами кода, которые можно задействовать во многих чартах, тем самым избежав дублирования и придерживаясь принципа DRY.
Library charts объявляются в разделе dependencies в файле Chart.yaml. Установка и управление ими не отличаются от других чартов.
Мы с предвкушением ждем вариантов использования, которые этот компонент откроет перед разработчиками чартов, а также лучших практик, что могут возникнуть благодаря library charts.
Что дальше?
Helm 3.0.0-alpha.1 — основа, опираясь на которую, мы начинаем создавать новую версию Helm. В статье я описал некоторые интересные возможности Helm 3. Многие из них пока находятся на ранних стадиях разработки и это нормально; суть альфа-релиза в том, чтобы проверить идею, собрать отзывы от первых пользователей и подтвердить наши предположения.
Как только альфа-версия будет выпущена (напомним, что это уже произошло — прим. перев.), мы начнем принимать патчи для Helm 3 от сообщества. Необходимо создать надежный фундамент, который позволит разрабатывать и принимать новые функциональные возможности, а пользователи смогут чувствовать себя вовлеченными в процесс, открывая тикеты и внося исправления.
В статье я постарался осветить некоторые серьезные улучшения, которые появятся в Helm 3, однако этот список ни в коем случае нельзя назвать исчерпывающим. Полномасштабный план для Helm 3 включает в себя такие нововведения, как улучшенные стратегии обновления, более глубокая интеграция с реестрами OCI и использование JSON-схем для проверки значений чартов. Также мы планируем очистить кодовую базу и обновить те ее части, которые оставались без внимания последние три года.
Если чувствуете, что мы что-то упустили, будем рады услышать ваши мысли!
#helm-users для вопросов и простого общения с сообществом;
#helm-dev для обсуждения pull requests, кода и багов.
Вы также можете пообщаться в наших еженедельных Public Developer Calls по четвергам в 19:30 MSK. Встречи посвящены обсуждению задач, над которыми работают ключевые разработчики и сообщество, а также темам обсуждения на неделю. Любой желающий может присоединиться и принять участие во встрече. Ссылка доступна в Slack-канале #helm-dev.