Перейти к основному содержимому
Версия: 3.19.0

Изменения с Helm 2

Изменения с Helm 2

Ниже приведён исчерпывающий список всех основных изменений, появившихся в Helm 3.

Удаление Tiller

В процессе разработки Helm 2 мы представили Tiller. Tiller играл важную роль для команд, работающих в общем кластере — он позволял нескольким операторам взаимодействовать с одним и тем же набором релизов.

С включением управления доступом на основе ролей (RBAC) по умолчанию в Kubernetes 1.6, защита Tiller для использования в production-среде стала сложнее в управлении. Из-за множества возможных политик безопасности мы придерживались позиции предоставления разрешительной конфигурации по умолчанию. Это позволяло новым пользователям начать экспериментировать с Helm и Kubernetes без необходимости сразу погружаться в настройки безопасности. К сожалению, такая разрешительная конфигурация могла предоставить пользователю широкий набор прав, которые не были предусмотрены. DevOps-инженерам и SRE приходилось изучать дополнительные операционные шаги при установке Tiller в мультитенантный кластер.

Узнав, как участники сообщества использовали Helm в определённых сценариях, мы обнаружили, что системе управления релизами Tiller не обязательно полагаться на оператор внутри кластера для поддержания состояния или как на центральный узел для информации о релизах Helm. Вместо этого мы могли просто получать информацию от API-сервера Kubernetes, выполнять рендеринг чартов на стороне клиента и сохранять запись об установке в Kubernetes.

Основная цель Tiller могла быть достигнута без него, поэтому одним из первых решений относительно Helm 3 стало полное удаление Tiller.

С удалением Tiller модель безопасности Helm радикально упростилась. Helm 3 теперь поддерживает все современные функции безопасности, идентификации и авторизации Kubernetes. Права Helm определяются с помощью вашего файла kubeconfig. Администраторы кластера могут ограничивать права пользователей с любой необходимой детализацией. Релизы по-прежнему записываются в кластер, а остальная функциональность Helm сохраняется.

Улучшенная стратегия обновления: трёхстороннее стратегическое слияние патчей

В Helm 2 использовалось двухстороннее стратегическое слияние патчей. При обновлении сравнивался манифест последнего чарта с предложенным манифестом чарта (предоставленным во время helm upgrade). Сравнивались различия между этими двумя чартами, чтобы определить, какие изменения необходимо применить к ресурсам в Kubernetes. Если изменения вносились в кластер вне Helm (например, во время kubectl edit), они не учитывались. Это приводило к невозможности откатить ресурсы к предыдущему состоянию: поскольку Helm рассматривал только последний применённый манифест чарта как текущее состояние, при отсутствии изменений в состоянии чарта фактическое состояние оставалось неизменным.

В Helm 3 мы используем трёхстороннее стратегическое слияние патчей. При генерации патча Helm учитывает старый манифест, его фактическое состояние и новый манифест.

Примеры

Рассмотрим несколько типичных примеров того, на что влияет это изменение.

Откат при изменении фактического состояния

Ваша команда только что развернула приложение в production на Kubernetes с помощью Helm. Чарт содержит объект Deployment, в котором количество реплик установлено на три:

$ helm install myapp ./myapp

В команду приходит новый разработчик. В первый рабочий день, наблюдая за production-кластером, он случайно проливает кофе на клавиатуру и выполняет kubectl scale, уменьшая количество реплик production-deployment с трёх до нуля.

$ kubectl scale --replicas=0 deployment/myapp

Другой разработчик в команде замечает, что production-сайт не работает, и решает откатить релиз к предыдущему состоянию:

$ helm rollback myapp

Что происходит?

В Helm 2 генерировался патч путём сравнения старого манифеста с новым. Поскольку это откат, манифесты одинаковые. Helm определял, что нечего менять, так как нет различий между старым и новым манифестом. Количество реплик продолжало оставаться на нуле. Начиналась паника.

В Helm 3 патч генерируется с использованием старого манифеста, фактического состояния и нового манифеста. Helm распознаёт, что старое состояние было три, фактическое состояние — ноль, а новый манифест хочет вернуть значение к трём, поэтому генерирует патч для возврата состояния к трём.

Обновление при изменении фактического состояния

Многие service mesh и другие приложения на основе контроллеров внедряют данные в объекты Kubernetes. Это может быть sidecar-контейнер, метки или другая информация. Допустим, у вас был такой манифест, сгенерированный из чарта:

containers:
- name: server
image: nginx:2.0.0

А фактическое состояние было изменено другим приложением на:

containers:
- name: server
image: nginx:2.0.0
- name: my-injected-sidecar
image: my-cool-mesh:1.0.0

Теперь вы хотите обновить тег образа nginx до 2.1.0. Вы обновляетесь до чарта с таким манифестом:

containers:
- name: server
image: nginx:2.1.0

Что происходит?

В Helm 2 генерировался патч объекта containers между старым и новым манифестом. Фактическое состояние кластера не учитывалось при генерации патча.

Фактическое состояние кластера изменялось на:

containers:
- name: server
image: nginx:2.1.0

Sidecar-контейнер удалялся из фактического состояния. Опять паника.

В Helm 3 генерируется патч объекта containers между старым манифестом, фактическим состоянием и новым манифестом. Helm замечает, что новый манифест изменяет тег образа на 2.1.0, но фактическое состояние содержит sidecar-контейнер.

Фактическое состояние кластера изменяется на:

containers:
- name: server
image: nginx:2.1.0
- name: my-injected-sidecar
image: my-cool-mesh:1.0.0

Имена релизов теперь ограничены namespace

С удалением Tiller информация о каждом релизе должна была где-то храниться. В Helm 2 она хранилась в том же namespace, что и Tiller. На практике это означало, что после использования имени для релиза никакой другой релиз не мог использовать то же имя, даже при развёртывании в другом namespace.

В Helm 3 информация о конкретном релизе теперь хранится в том же namespace, что и сам релиз. Это означает, что пользователи могут выполнить helm install wordpress stable/wordpress в двух разных namespace, и на каждый можно ссылаться через helm list, изменив контекст текущего namespace (например, helm list --namespace foo).

Благодаря лучшему соответствию нативным namespace кластера, команда helm list больше не показывает все релизы по умолчанию. Вместо этого она показывает только релизы в namespace вашего текущего контекста Kubernetes (то есть namespace, отображаемый при выполнении kubectl config view --minify). Это также означает, что необходимо указать флаг --all-namespaces для команды helm list, чтобы получить поведение, аналогичное Helm 2.

Secrets как хранилище по умолчанию

В Helm 3 Secrets теперь используются как хранилище по умолчанию. В Helm 2 по умолчанию использовались ConfigMaps для хранения информации о релизах. В Helm 2.7.0 был реализован новый бэкенд хранилища, использующий Secrets, и теперь он является значением по умолчанию в Helm 3.

Переход на Secrets в Helm 3 по умолчанию обеспечивает дополнительную безопасность для защиты чартов в сочетании с появлением шифрования Secrets в Kubernetes.

Шифрование secrets в покое появилось как alpha-функция в Kubernetes 1.7 и стало стабильным в Kubernetes 1.13. Это позволяет пользователям шифровать метаданные релизов Helm в покое, что является хорошей отправной точкой для последующего расширения на использование чего-то вроде Vault.

Изменения путей импорта Go

В Helm 3 путь импорта Go изменился с k8s.io/helm на helm.sh/helm/v3. Если вы планируете перейти на клиентские библиотеки Go Helm 3, убедитесь, что изменили пути импорта.

Capabilities

Встроенный объект .Capabilities, доступный на этапе рендеринга, был упрощён.

Встроенные объекты

Валидация значений чарта с помощью JSONSchema

Теперь к значениям чарта можно применить JSON Schema. Это гарантирует, что значения, предоставленные пользователем, соответствуют схеме, определённой разработчиком чарта, обеспечивая лучшую отчётность об ошибках при предоставлении некорректных значений.

Валидация выполняется при вызове следующих команд:

  • helm install
  • helm upgrade
  • helm template
  • helm lint

Подробнее см. в документации по файлам схем.

Консолидация requirements.yaml в Chart.yaml

Система управления зависимостями чартов переехала из requirements.yaml и requirements.lock в Chart.yaml и Chart.lock. Мы рекомендуем использовать новый формат для новых чартов, предназначенных для Helm 3. Однако Helm 3 по-прежнему понимает Chart API версии 1 (v1) и загрузит существующие файлы requirements.yaml.

В Helm 2 requirements.yaml выглядел так:

dependencies:
- name: mariadb
version: 5.x.x
repository: https://charts.helm.sh/stable
condition: mariadb.enabled
tags:
- database

В Helm 3 зависимость выражается так же, но теперь в вашем Chart.yaml:

dependencies:
- name: mariadb
version: 5.x.x
repository: https://charts.helm.sh/stable
condition: mariadb.enabled
tags:
- database

Чарты по-прежнему загружаются и помещаются в директорию charts/, поэтому подчарты, находящиеся в директории charts/, продолжат работать без изменений.

Имя (или --generate-name) теперь обязательно при установке

В Helm 2 при отсутствии имени автоматически генерировалось имя. На практике это оказалось скорее неудобством, чем полезной функцией. В Helm 3 Helm выдаст ошибку, если имя не указано при helm install.

Для тех, кто по-прежнему хочет автоматически сгенерированное имя, можно использовать флаг --generate-name.

Публикация чартов в OCI-реестры

Это экспериментальная функция, представленная в Helm 3. Для её использования установите переменную окружения HELM_EXPERIMENTAL_OCI=1.

На высоком уровне репозиторий чартов — это место, где чарты могут храниться и распространяться. Клиент Helm упаковывает и отправляет чарты в репозиторий. Проще говоря, репозиторий чартов — это базовый HTTP-сервер, содержащий файл index.yaml и упакованные чарты.

Хотя API репозитория чартов удовлетворяет базовым требованиям к хранению, у него есть ряд недостатков:

  • Репозиториям чартов очень сложно абстрагировать большинство реализаций безопасности, необходимых в production-среде. Стандартный API для аутентификации и авторизации очень важен в production-сценариях.
  • Инструменты Helm для подписи и проверки целостности и происхождения чарта являются необязательной частью процесса публикации чарта.
  • В мультитенантных сценариях один и тот же чарт может быть загружен другим арендатором, что удваивает затраты на хранение одного и того же содержимого. Более продвинутые репозитории чартов были разработаны для решения этой проблемы, но это не является частью формальной спецификации.
  • Использование одного индексного файла для поиска, информации о метаданных и получения чартов затрудняет проектирование безопасных мультитенантных реализаций.

Проект Distribution от Docker (также известный как Docker Registry v2) является преемником проекта Docker Registry. Многие крупные облачные провайдеры предлагают продукты на основе проекта Distribution, и благодаря этому проект получил многолетнюю закалку, лучшие практики безопасности и проверку в боевых условиях.

Подробнее о том, как упаковать чарт и отправить его в Docker-реестр, см. в helm help chart и helm help registry.

Дополнительная информация на этой странице.

Удаление helm serve

helm serve запускал локальный репозиторий чартов на вашем компьютере для целей разработки. Однако он не получил широкого распространения как инструмент разработки и имел множество проблем с архитектурой. В итоге мы решили удалить его и выделить в плагин.

Для аналогичного опыта работы с helm serve обратите внимание на опцию локального файлового хранилища в ChartMuseum и плагин servecm.

Поддержка библиотечных чартов

Helm 3 поддерживает класс чартов, называемых «библиотечными чартами». Это чарты, которые используются другими чартами, но не создают собственных артефактов релиза. Шаблоны библиотечного чарта могут объявлять только элементы define. Глобальный контент, не являющийся define, просто игнорируется. Это позволяет пользователям повторно использовать и делиться фрагментами кода, которые можно использовать в нескольких чартах, избегая избыточности и сохраняя чарты DRY.

Библиотечные чарты объявляются в директиве dependencies в Chart.yaml и устанавливаются и управляются как любой другой чарт.

dependencies:
- name: mylib
version: 1.x.x
repository: quay.io

Мы с нетерпением ждём сценариев использования, которые откроет эта функция для разработчиков чартов, а также лучших практик, возникающих при использовании библиотечных чартов.

Обновление apiVersion в Chart.yaml

С появлением поддержки библиотечных чартов и консолидацией requirements.yaml в Chart.yaml, клиенты, понимавшие формат пакетов Helm 2, не смогут понять эти новые функции. Поэтому мы изменили apiVersion в Chart.yaml с v1 на v2.

helm create теперь создаёт чарты с использованием нового формата, поэтому apiVersion по умолчанию также был изменён.

Клиенты, желающие поддерживать обе версии чартов Helm, должны проверять поле apiVersion в Chart.yaml, чтобы понять, как разбирать формат пакета.

Поддержка XDG Base Directory

Спецификация XDG Base Directory — это переносимый стандарт, определяющий, где в файловой системе должны храниться файлы конфигурации, данных и кэша.

В Helm 2 вся эта информация хранилась в ~/.helm (известной как helm home), которую можно было изменить, установив переменную окружения $HELM_HOME или используя глобальный флаг --home.

В Helm 3 Helm теперь использует следующие переменные окружения в соответствии со спецификацией XDG Base Directory:

  • $XDG_CACHE_HOME
  • $XDG_CONFIG_HOME
  • $XDG_DATA_HOME

Плагинам Helm по-прежнему передаётся $HELM_HOME как псевдоним для $XDG_DATA_HOME для обратной совместимости с плагинами, использующими $HELM_HOME как рабочую директорию.

Для адаптации к этому изменению в окружение плагина также передаются несколько новых переменных окружения:

  • $HELM_PATH_CACHE — путь к кэшу
  • $HELM_PATH_CONFIG — путь к конфигурации
  • $HELM_PATH_DATA — путь к данным

Плагинам Helm, желающим поддерживать Helm 3, следует рассмотреть использование этих новых переменных окружения.

Переименование команд CLI

Для лучшего соответствия терминологии других пакетных менеджеров helm delete была переименована в helm uninstall. helm delete по-прежнему сохраняется как псевдоним для helm uninstall, поэтому можно использовать любую форму.

В Helm 2 для очистки истории релиза необходимо было указать флаг --purge. Эта функциональность теперь включена по умолчанию. Чтобы сохранить предыдущее поведение, используйте helm uninstall --keep-history.

Кроме того, несколько других команд были переименованы для соответствия тем же соглашениям:

  • helm inspect -> helm show
  • helm fetch -> helm pull

Эти команды также сохранили свои старые названия как псевдонимы, поэтому вы можете продолжать использовать их в любой форме.

Автоматическое создание namespace

При создании релиза в несуществующем namespace Helm 2 создавал namespace. Helm 3 следует поведению других инструментов Kubernetes и возвращает ошибку, если namespace не существует. Helm 3 создаст namespace, если вы явно укажете флаг --create-namespace.

Что произошло с .Chart.ApiVersion?

Helm следует типичному соглашению CamelCase, которое требует использования заглавных букв в аббревиатурах. Мы применяли это в других частях кода, например, в .Capabilities.APIVersions.Has. В Helm v3 мы исправили .Chart.ApiVersion в соответствии с этим паттерном, переименовав его в .Chart.APIVersion.