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

Чарты

Helm использует формат упаковки, называемый чартами. Чарт — это набор файлов, описывающих связанный набор ресурсов Kubernetes. Один чарт может использоваться для развёртывания чего-то простого, например пода с memcached, или чего-то сложного, например полного стека веб-приложения с HTTP-серверами, базами данных, кешами и так далее.

Чарты создаются как файлы, организованные в определённую структуру каталогов. Их можно упаковывать в версионированные архивы для развёртывания.

Если вы хотите скачать и посмотреть файлы опубликованного чарта без его установки, вы можете сделать это с помощью команды helm pull chartrepo/chartname.

Этот документ описывает формат чартов и даёт базовое руководство по созданию чартов в Helm.

Файловая структура чарта

Чарт организован как набор файлов внутри каталога. Имя каталога — это имя чарта (без информации о версии). Таким образом, чарт, описывающий WordPress, будет храниться в каталоге wordpress/.

Внутри этого каталога Helm ожидает структуру, соответствующую следующей:

wordpress/
Chart.yaml # A YAML file containing information about the chart
LICENSE # OPTIONAL: A plain text file containing the license for the chart
README.md # OPTIONAL: A human-readable README file
values.yaml # The default configuration values for this chart
values.schema.json # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
charts/ # A directory containing any charts upon which this chart depends.
crds/ # Custom Resource Definitions
templates/ # A directory of templates that, when combined with values,
# will generate valid Kubernetes manifest files.
templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

Helm резервирует использование каталогов charts/, crds/ и templates/, а также перечисленных имён файлов. Остальные файлы останутся без изменений.

Файл Chart.yaml

Файл Chart.yaml является обязательным для чарта. Он содержит следующие поля:

apiVersion: The chart API version (required)
name: The name of the chart (required)
version: The version of the chart (required)
kubeVersion: A SemVer range of compatible Kubernetes versions (optional)
description: A single-sentence description of this project (optional)
type: The type of the chart (optional)
keywords:
- A list of keywords about this project (optional)
home: The URL of this projects home page (optional)
sources:
- A list of URLs to source code for this project (optional)
dependencies: # A list of the chart requirements (optional)
- name: The name of the chart (nginx)
version: The version of the chart ("1.2.3")
repository: (optional) The repository URL ("https://example.com/charts") or alias ("@repo-name")
condition: (optional) A yaml path that resolves to a boolean, used for enabling/disabling charts (e.g. subchart1.enabled )
tags: # (optional)
- Tags can be used to group charts for enabling/disabling together
import-values: # (optional)
- ImportValues holds the mapping of source values to parent key to be imported. Each item can be a string or pair of child/parent sublist items.
alias: (optional) Alias to be used for the chart. Useful when you have to add the same chart multiple times
maintainers: # (optional)
- name: The maintainers name (required for each maintainer)
email: The maintainers email (optional for each maintainer)
url: A URL for the maintainer (optional for each maintainer)
icon: A URL to an SVG or PNG image to be used as an icon (optional).
appVersion: The version of the app that this contains (optional). Needn't be SemVer. Quotes recommended.
deprecated: Whether this chart is deprecated (optional, boolean)
annotations:
example: A list of annotations keyed by name (optional).

Начиная с версии v3.3.2, дополнительные поля не допускаются. Рекомендуемый подход — добавлять пользовательские метаданные в annotations.

Чарты и версионирование

Каждый чарт должен иметь номер версии. Версия должна соответствовать стандарту SemVer 2, но это не строго обязательно. В отличие от Helm Classic, Helm v2 и более поздние версии используют номера версий как маркеры релизов. Пакеты в репозиториях идентифицируются по имени и версии.

Например, чарт nginx, в котором поле version установлено как version: 1.2.3, будет называться:

nginx-1.2.3.tgz

Поддерживаются и более сложные имена SemVer 2, такие как version: 1.2.3-alpha.1+ef365. Однако имена, не соответствующие SemVer, явно запрещены системой. Исключение составляют версии в формате x или x.y. Например, если указана версия с начальной буквой v или без всех 3 частей (например, v1.2), система попытается преобразовать её в корректную семантическую версию (например, v1.2.0).

ПРИМЕЧАНИЕ: В то время как Helm Classic и Deployment Manager были сильно ориентированы на GitHub при работе с чартами, Helm v2 и более поздние версии не полагаются на GitHub или даже Git и не требуют их. Соответственно, Git SHA вообще не используются для версионирования.

Поле version внутри Chart.yaml используется многими инструментами Helm, включая CLI. При создании пакета команда helm package использует версию из Chart.yaml как токен в имени пакета. Система предполагает, что номер версии в имени пакета чарта соответствует номеру версии в Chart.yaml. Несоответствие этому требованию приведёт к ошибке.

Поле apiVersion

Поле apiVersion должно быть v2 для чартов Helm, требующих как минимум Helm 3. Чарты, поддерживающие предыдущие версии Helm, имеют apiVersion, установленный в v1, и по-прежнему могут быть установлены Helm 3.

Изменения с v1 на v2:

  • Поле dependencies, определяющее зависимости чарта, которое для чартов v1 находилось в отдельном файле requirements.yaml (см. Зависимости чартов).
  • Поле type, разделяющее прикладные и библиотечные чарты (см. Типы чартов).

Поле appVersion

Обратите внимание, что поле appVersion не связано с полем version. Это способ указания версии приложения. Например, чарт drupal может иметь appVersion: "8.2.1", указывающий, что версия Drupal, включённая в чарт (по умолчанию), — 8.2.1. Это поле носит информационный характер и не влияет на расчёт версии чарта. Рекомендуется заключать версию в кавычки. Это заставляет парсер YAML обрабатывать номер версии как строку. Без кавычек в некоторых случаях могут возникнуть проблемы парсинга. Например, YAML интерпретирует 1.0 как число с плавающей точкой, а git commit SHA вроде 1234e10 — как научную нотацию.

Начиная с Helm v3.5.0, helm create заключает поле appVersion по умолчанию в кавычки.

Поле kubeVersion

Необязательное поле kubeVersion позволяет определить ограничения на поддерживаемые версии Kubernetes в формате semver. Helm проверяет ограничения версий при установке чарта и завершается с ошибкой, если кластер работает на неподдерживаемой версии Kubernetes.

Ограничения версий могут включать сравнения AND, разделённые пробелами, например:

>= 1.13.0 < 1.15.0

которые можно комбинировать с оператором OR ||, как в следующем примере:

>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0

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

Помимо ограничений версий с использованием операторов = != > < >= <=, поддерживаются следующие сокращённые нотации:

  • диапазоны через дефис для закрытых интервалов, где 1.1 - 2.3.4 эквивалентно >= 1.1 <= 2.3.4.
  • подстановочные знаки x, X и *, где 1.2.x эквивалентно >= 1.2.0 < 1.3.0.
  • тильда-диапазоны (допускаются изменения патч-версии), где ~1.2.3 эквивалентно >= 1.2.3 < 1.3.0.
  • каретка-диапазоны (допускаются изменения минорной версии), где ^1.2.3 эквивалентно >= 1.2.3 < 2.0.0.

Подробное объяснение поддерживаемых ограничений semver см. в Masterminds/semver.

Устаревание чартов

При управлении чартами в репозитории чартов иногда необходимо пометить чарт как устаревший. Для этого можно использовать необязательное поле deprecated в Chart.yaml. Если последняя версия чарта в репозитории помечена как устаревшая, то весь чарт считается устаревшим. Имя чарта можно использовать повторно, опубликовав более новую версию, не помеченную как устаревшая. Процедура устаревания чартов:

  1. Обновите Chart.yaml чарта, чтобы пометить его как устаревший, увеличив версию
  2. Опубликуйте новую версию чарта в репозитории чартов
  3. Удалите чарт из исходного репозитория (например, git)

Типы чартов

Поле type определяет тип чарта. Есть два типа: application и library. Application — это тип по умолчанию, представляющий собой стандартный чарт, с которым можно выполнять все операции. Библиотечный чарт предоставляет утилиты или функции для разработчика чартов. Библиотечный чарт отличается от прикладного тем, что он не устанавливается и обычно не содержит объектов ресурсов.

Примечание: Прикладной чарт может использоваться как библиотечный. Для этого нужно установить тип в library. Тогда чарт будет отрендерен как библиотечный, где можно использовать все утилиты и функции. Все объекты ресурсов чарта не будут рендериться.

Файлы LICENSE, README и NOTES чарта

Чарты также могут содержать файлы, описывающие установку, конфигурацию, использование и лицензию чарта.

LICENSE — это простой текстовый файл, содержащий лицензию чарта. Чарт может содержать лицензию, так как может иметь программную логику в шаблонах и, следовательно, не является только конфигурацией. При необходимости могут быть также отдельные лицензии для приложения, устанавливаемого чартом.

README для чарта должен быть отформатирован в Markdown (README.md) и обычно содержит:

  • Описание приложения или сервиса, предоставляемого чартом
  • Любые предварительные требования для запуска чарта
  • Описание опций в values.yaml и значений по умолчанию
  • Любую другую информацию, которая может быть полезна при установке или конфигурации чарта

Когда хабы и другие пользовательские интерфейсы отображают информацию о чарте, эта информация берётся из содержимого файла README.md.

Чарт также может содержать короткий текстовый файл templates/NOTES.txt, который будет выводиться после установки и при просмотре статуса релиза. Этот файл обрабатывается как шаблон и может использоваться для отображения примечаний по использованию, следующих шагов или любой другой информации, относящейся к релизу чарта. Например, можно предоставить инструкции по подключению к базе данных или доступу к веб-интерфейсу. Поскольку этот файл выводится в STDOUT при выполнении helm install или helm status, рекомендуется делать содержимое кратким и ссылаться на README для получения более подробной информации.

Зависимости чартов

В Helm один чарт может зависеть от любого количества других чартов. Эти зависимости могут быть динамически связаны с помощью поля dependencies в Chart.yaml или добавлены в каталог charts/ и управляться вручную.

Управление зависимостями с помощью поля dependencies

Чарты, требуемые текущим чартом, определяются как список в поле dependencies.

dependencies:
- name: apache
version: 1.2.3
repository: https://example.com/charts
- name: mysql
version: 3.2.1
repository: https://another.example.com/charts
  • Поле name — это имя нужного вам чарта.
  • Поле version — это версия нужного вам чарта.
  • Поле repository — это полный URL репозитория чартов. Обратите внимание, что вы также должны использовать helm repo add для локального добавления этого репозитория.
  • Вы можете использовать имя репозитория вместо URL
$ helm repo add fantastic-charts https://charts.helm.sh/incubator
dependencies:
- name: awesomeness
version: 1.0.0
repository: "@fantastic-charts"

После определения зависимостей вы можете выполнить helm dependency update, и команда использует ваш файл зависимостей для загрузки всех указанных чартов в каталог charts/.

$ helm dep up foochart
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "local" chart repository
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "example" chart repository
...Successfully got an update from the "another" chart repository
Update Complete. Happy Helming!
Saving 2 charts
Downloading apache from repo https://example.com/charts
Downloading mysql from repo https://another.example.com/charts

Когда helm dependency update получает чарты, она сохраняет их как архивы чартов в каталоге charts/. Таким образом, для примера выше можно ожидать следующие файлы в каталоге charts:

charts/
apache-1.2.3.tgz
mysql-3.2.1.tgz

Поле alias в зависимостях

В дополнение к другим полям выше, каждая запись зависимости может содержать необязательное поле alias.

Добавление псевдонима для зависимого чарта добавляет чарт в зависимости, используя псевдоним в качестве имени новой зависимости.

alias можно использовать, когда нужно обращаться к чарту под другим именем (именами).

# parentchart/Chart.yaml

dependencies:
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-1
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-2
- name: subchart
repository: http://localhost:10191
version: 0.1.0

В примере выше мы получим 3 зависимости для parentchart:

subchart
new-subchart-1
new-subchart-2

Ручной способ достижения этого — копирование одного и того же чарта в каталог charts/ несколько раз с разными именами.

Поля tags и condition в зависимостях

В дополнение к другим полям выше, каждая запись зависимости может содержать необязательные поля tags и condition.

По умолчанию загружаются все чарты. Если присутствуют поля tags или condition, они вычисляются и используются для управления загрузкой чартов, к которым они применяются.

Condition — поле condition содержит один или несколько путей YAML (разделённых запятыми). Если этот путь существует в значениях верхнего родительского чарта и разрешается в булево значение, чарт будет включён или отключён в зависимости от этого булева значения. Вычисляется только первый найденный допустимый путь из списка, и если ни один путь не существует, условие не имеет эффекта.

Tags — поле tags представляет собой YAML-список меток для ассоциации с этим чартом. В значениях верхнего родительского чарта все чарты с тегами могут быть включены или отключены путём указания тега и булева значения.

# parentchart/Chart.yaml

dependencies:
- name: subchart1
repository: http://localhost:10191
version: 0.1.0
condition: subchart1.enabled,global.subchart1.enabled
tags:
- front-end
- subchart1
- name: subchart2
repository: http://localhost:10191
version: 0.1.0
condition: subchart2.enabled,global.subchart2.enabled
tags:
- back-end
- subchart2
# parentchart/values.yaml

subchart1:
enabled: true
tags:
front-end: false
back-end: true

В примере выше все чарты с тегом front-end будут отключены, но поскольку путь subchart1.enabled в значениях родителя разрешается в 'true', условие переопределяет тег front-end, и subchart1 будет включён.

Поскольку subchart2 помечен тегом back-end, и этот тег разрешается в true, subchart2 будет включён. Также обратите внимание, что хотя для subchart2 указано условие, в значениях родителя нет соответствующего пути и значения, поэтому это условие не имеет эффекта.

Использование CLI с тегами и условиями

Параметр --set можно использовать как обычно для изменения значений тегов и условий.

helm install --set tags.front-end=true --set subchart2.enabled=false
Разрешение тегов и условий
  • Условия (когда установлены в значениях) всегда переопределяют теги. Первый существующий путь условия побеждает, последующие пути для этого чарта игнорируются.
  • Теги вычисляются как «если любой из тегов чарта истинен, то включить чарт».
  • Значения тегов и условий должны быть установлены в значениях верхнего родительского чарта.
  • Ключ tags: в значениях должен быть ключом верхнего уровня. Глобальные и вложенные таблицы tags: в настоящее время не поддерживаются.

Импорт значений дочерних чартов через dependencies

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

Ключи, содержащие импортируемые значения, могут быть указаны в dependencies родительского чарта в поле import-values с использованием YAML-списка. Каждый элемент списка — это ключ, который импортируется из поля exports дочернего чарта.

Для импорта значений, не содержащихся в ключе exports, используйте формат child-parent. Примеры обоих форматов описаны ниже.

Использование формата exports

Если файл values.yaml дочернего чарта содержит поле exports в корне, его содержимое может быть импортировано непосредственно в значения родителя путём указания ключей для импорта, как в примере ниже:

# parent's Chart.yaml file

dependencies:
- name: subchart
repository: http://localhost:10191
version: 0.1.0
import-values:
- data
# child's values.yaml file

exports:
data:
myint: 99

Поскольку мы указываем ключ data в нашем списке импорта, Helm ищет в поле exports дочернего чарта ключ data и импортирует его содержимое.

Итоговые значения родителя будут содержать наше экспортированное поле:

# parent's values

myint: 99

Обратите внимание, что родительский ключ data не содержится в итоговых значениях родителя. Если вам нужно указать родительский ключ, используйте формат 'child-parent'.

Использование формата child-parent

Для доступа к значениям, не содержащимся в ключе exports значений дочернего чарта, вам нужно указать исходный ключ импортируемых значений (child) и путь назначения в значениях родительского чарта (parent).

import-values в примере ниже указывает Helm взять любые значения по пути child: и скопировать их в значения родителя по пути, указанному в parent:

# parent's Chart.yaml file

dependencies:
- name: subchart1
repository: http://localhost:10191
version: 0.1.0
...
import-values:
- child: default.data
parent: myimports

В примере выше значения, найденные по пути default.data в значениях subchart1, будут импортированы в ключ myimports в значениях родительского чарта, как показано ниже:

# parent's values.yaml file

myimports:
myint: 0
mybool: false
mystring: "helm rocks!"
# subchart1's values.yaml file

default:
data:
myint: 999
mybool: true

Итоговые значения родительского чарта будут:

# parent's final values

myimports:
myint: 999
mybool: true
mystring: "helm rocks!"

Итоговые значения родителя теперь содержат поля myint и mybool, импортированные из subchart1.

Ручное управление зависимостями через каталог charts/

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

Зависимость должна быть распакованным каталогом чарта, но её имя не может начинаться с _ или .. Такие файлы игнорируются загрузчиком чартов.

Например, если чарт WordPress зависит от чарта Apache, чарт Apache (правильной версии) поставляется в каталоге charts/ чарта WordPress:

wordpress:
Chart.yaml
# ...
charts/
apache/
Chart.yaml
# ...
mysql/
Chart.yaml
# ...

Пример выше показывает, как чарт WordPress выражает свою зависимость от Apache и MySQL, включая эти чарты в свой каталог charts/.

СОВЕТ: Чтобы добавить зависимость в каталог charts/, используйте команду helm pull

Операционные аспекты использования зависимостей

Разделы выше объясняют, как указывать зависимости чартов, но как это влияет на установку чарта с помощью helm install и helm upgrade?

Предположим, что чарт с именем "A" создаёт следующие объекты Kubernetes:

  • namespace "A-Namespace"
  • statefulset "A-StatefulSet"
  • service "A-Service"

Кроме того, A зависит от чарта B, который создаёт объекты:

  • namespace "B-Namespace"
  • replicaset "B-ReplicaSet"
  • service "B-Service"

После установки/обновления чарта A создаётся/модифицируется один релиз Helm. Релиз создаст/обновит все вышеперечисленные объекты Kubernetes в следующем порядке:

  • A-Namespace
  • B-Namespace
  • A-Service
  • B-Service
  • B-ReplicaSet
  • A-StatefulSet

Это происходит потому, что при установке/обновлении чартов объекты Kubernetes из чартов и всех их зависимостей:

  • агрегируются в единый набор; затем
  • сортируются по типу, а затем по имени; и затем
  • создаются/обновляются в этом порядке.

Таким образом, создаётся один релиз со всеми объектами для чарта и его зависимостей.

Порядок установки типов Kubernetes задаётся перечислением InstallOrder в kind_sorter.go (см. исходный файл Helm).

Шаблоны и значения

Шаблоны чартов Helm написаны на языке шаблонов Go с добавлением около 50 дополнительных функций шаблонов из библиотеки Sprig и нескольких других специализированных функций.

Все файлы шаблонов хранятся в папке templates/ чарта. Когда Helm рендерит чарты, он пропускает каждый файл в этом каталоге через движок шаблонов.

Значения для шаблонов предоставляются двумя способами:

  • Разработчики чартов могут предоставить файл values.yaml внутри чарта. Этот файл может содержать значения по умолчанию.
  • Пользователи чартов могут предоставить YAML-файл со значениями. Его можно указать в командной строке с помощью helm install.

Когда пользователь предоставляет пользовательские значения, они переопределяют значения в файле values.yaml чарта.

Файлы шаблонов

Файлы шаблонов следуют стандартным соглашениям для написания шаблонов Go (подробности см. в документации пакета text/template Go). Пример файла шаблона может выглядеть примерно так:

apiVersion: v1
kind: ReplicationController
metadata:
name: deis-database
namespace: deis
labels:
app.kubernetes.io/managed-by: deis
spec:
replicas: 1
selector:
app.kubernetes.io/name: deis-database
template:
metadata:
labels:
app.kubernetes.io/name: deis-database
spec:
serviceAccount: deis-database
containers:
- name: deis-database
image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }}
imagePullPolicy: {{ .Values.pullPolicy }}
ports:
- containerPort: 5432
env:
- name: DATABASE_STORAGE
value: {{ default "minio" .Values.storage }}

Пример выше, основанный на https://github.com/deis/charts, является шаблоном для контроллера репликации Kubernetes. Он может использовать следующие четыре значения шаблона (обычно определяемые в файле values.yaml):

  • imageRegistry: Исходный реестр для Docker-образа.
  • dockerTag: Тег для docker-образа.
  • pullPolicy: Политика pull для Kubernetes.
  • storage: Бэкенд хранилища, значение по умолчанию — "minio"

Все эти значения определяются автором шаблона. Helm не требует и не диктует параметры.

Чтобы увидеть множество работающих чартов, посетите CNCF Artifact Hub.

Предопределённые значения

Значения, предоставляемые через файл values.yaml (или через флаг --set), доступны из объекта .Values в шаблоне. Но есть и другие предопределённые данные, к которым вы можете получить доступ в шаблонах.

Следующие значения предопределены, доступны в каждом шаблоне и не могут быть переопределены. Как и все значения, имена чувствительны к регистру.

  • Release.Name: Имя релиза (не чарта)
  • Release.Namespace: Пространство имён, в которое был выпущен чарт.
  • Release.Service: Сервис, выполнивший релиз.
  • Release.IsUpgrade: Устанавливается в true, если текущая операция — обновление или откат.
  • Release.IsInstall: Устанавливается в true, если текущая операция — установка.
  • Chart: Содержимое Chart.yaml. Таким образом, версия чарта доступна как Chart.Version, а мейнтейнеры — в Chart.Maintainers.
  • Files: Объект, подобный map, содержащий все неспециальные файлы в чарте. Он не даст вам доступа к шаблонам, но предоставит доступ к дополнительным файлам, которые присутствуют (если они не исключены с помощью .helmignore). Доступ к файлам осуществляется с помощью {{ index .Files "file.name" }} или функции {{.Files.Get name }}. Вы также можете получить доступ к содержимому файла как []byte с помощью {{ .Files.GetBytes }}
  • Capabilities: Объект, подобный map, содержащий информацию о версиях Kubernetes ({{ .Capabilities.KubeVersion }}) и поддерживаемых версиях API Kubernetes ({{ .Capabilities.APIVersions.Has "batch/v1" }})

ПРИМЕЧАНИЕ: Любые неизвестные поля Chart.yaml будут отброшены. Они не будут доступны внутри объекта Chart. Таким образом, Chart.yaml нельзя использовать для передачи произвольно структурированных данных в шаблон. Для этого можно использовать файл values.

Файлы values

Рассматривая шаблон из предыдущего раздела, файл values.yaml, предоставляющий необходимые значения, будет выглядеть так:

imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "s3"

Файл values форматируется в YAML. Чарт может включать файл values.yaml по умолчанию. Команда helm install позволяет пользователю переопределять значения, предоставляя дополнительные YAML-значения:

$ helm install --generate-name --values=myvals.yaml wordpress

Когда значения передаются таким образом, они объединяются с файлом значений по умолчанию. Например, рассмотрим файл myvals.yaml, который выглядит так:

storage: "gcs"

Когда он объединяется с values.yaml в чарте, результирующее сгенерированное содержимое будет:

imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "gcs"

Обратите внимание, что было переопределено только последнее поле.

ПРИМЕЧАНИЕ: Файл значений по умолчанию, включённый в чарт, должен называться values.yaml. Но файлы, указанные в командной строке, могут называться как угодно.

ПРИМЕЧАНИЕ: Если флаг --set используется с helm install или helm upgrade, эти значения просто преобразуются в YAML на стороне клиента.

ПРИМЕЧАНИЕ: Если в файле values существуют обязательные записи, они могут быть объявлены как обязательные в шаблоне чарта с помощью функции 'required'

Любые из этих значений затем доступны внутри шаблонов с помощью объекта .Values:

apiVersion: v1
kind: ReplicationController
metadata:
name: deis-database
namespace: deis
labels:
app.kubernetes.io/managed-by: deis
spec:
replicas: 1
selector:
app.kubernetes.io/name: deis-database
template:
metadata:
labels:
app.kubernetes.io/name: deis-database
spec:
serviceAccount: deis-database
containers:
- name: deis-database
image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }}
imagePullPolicy: {{ .Values.pullPolicy }}
ports:
- containerPort: 5432
env:
- name: DATABASE_STORAGE
value: {{ default "minio" .Values.storage }}

Область видимости, зависимости и значения

Файлы values могут объявлять значения для чарта верхнего уровня, а также для любых чартов, включённых в каталог charts/ этого чарта. Или, другими словами, файл values может предоставлять значения как чарту, так и любым его зависимостям. Например, демонстрационный чарт WordPress выше имеет mysql и apache в качестве зависимостей. Файл values может предоставлять значения всем этим компонентам:

title: "My WordPress Site" # Sent to the WordPress template

mysql:
max_connections: 100 # Sent to MySQL
password: "secret"

apache:
port: 8080 # Passed to Apache

Чарты более высокого уровня имеют доступ ко всем переменным, определённым ниже. Поэтому чарт WordPress может обращаться к паролю MySQL как .Values.mysql.password. Но чарты более низкого уровня не могут обращаться к данным в родительских чартах, поэтому MySQL не сможет получить доступ к свойству title. Также он не может обратиться к apache.port.

Значения имеют пространства имён, но пространства имён обрезаются. Поэтому для чарта WordPress можно обращаться к полю пароля MySQL как .Values.mysql.password. Но для чарта MySQL область значений была сужена, и префикс пространства имён удалён, поэтому он увидит поле пароля просто как .Values.password.

Глобальные значения

Начиная с версии 2.0.0-Alpha.2, Helm поддерживает специальные "глобальные" значения. Рассмотрим эту модифицированную версию предыдущего примера:

title: "My WordPress Site" # Sent to the WordPress template

global:
app: MyWordPress

mysql:
max_connections: 100 # Sent to MySQL
password: "secret"

apache:
port: 8080 # Passed to Apache

Выше добавлен раздел global со значением app: MyWordPress. Это значение доступно всем чартам как .Values.global.app.

Например, шаблоны mysql могут обращаться к app как {{ .Values.global.app}}, и так же может чарт apache. Фактически файл values выше регенерируется следующим образом:

title: "My WordPress Site" # Sent to the WordPress template

global:
app: MyWordPress

mysql:
global:
app: MyWordPress
max_connections: 100 # Sent to MySQL
password: "secret"

apache:
global:
app: MyWordPress
port: 8080 # Passed to Apache

Это обеспечивает способ совместного использования одной переменной верхнего уровня со всеми подчартами, что полезно для таких вещей, как установка свойств metadata, например меток.

Если подчарт объявляет глобальную переменную, эта глобальная переменная передаётся вниз (подчартам подчарта), но не вверх к родительскому чарту. Подчарт не может влиять на значения родительского чарта.

Кроме того, глобальные переменные родительских чартов имеют приоритет над глобальными переменными подчартов.

Файлы Schema

Иногда мейнтейнер чарта может захотеть определить структуру своих значений. Это можно сделать, определив схему в файле values.schema.json. Схема представляется в виде JSON Schema. Она может выглядеть примерно так:

{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"image": {
"description": "Container Image",
"properties": {
"repo": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"type": "object"
},
"name": {
"description": "Service name",
"type": "string"
},
"port": {
"description": "Port",
"minimum": 0,
"type": "integer"
},
"protocol": {
"type": "string"
}
},
"required": [
"protocol",
"port"
],
"title": "Values",
"type": "object"
}

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

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

Пример файла values.yaml, соответствующего требованиям этой схемы, может выглядеть примерно так:

name: frontend
protocol: https
port: 443

Обратите внимание, что схема применяется к итоговому объекту .Values, а не только к файлу values.yaml. Это означает, что следующий yaml файл валиден при условии, что чарт установлен с соответствующей опцией --set, показанной ниже.

name: frontend
protocol: https
helm install --set port=443

Кроме того, итоговый объект .Values проверяется на соответствие всем схемам подчартов. Это означает, что ограничения подчарта нельзя обойти через родительский чарт. Это также работает в обратную сторону — если подчарт имеет требование, которое не выполнено в файле values.yaml подчарта, родительский чарт должен удовлетворить эти ограничения, чтобы быть валидным.

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

helm install --skip-schema-validation

Справочные материалы

Когда дело доходит до написания шаблонов, значений и файлов схем, есть несколько стандартных справочных материалов, которые вам помогут.

Custom Resource Definitions (CRD)

Kubernetes предоставляет механизм для объявления новых типов объектов Kubernetes. С помощью CustomResourceDefinitions (CRD) разработчики Kubernetes могут объявлять пользовательские типы ресурсов.

В Helm 3 CRD рассматриваются как особый вид объектов. Они устанавливаются перед остальной частью чарта и имеют некоторые ограничения.

Файлы CRD YAML должны размещаться в каталоге crds/ внутри чарта. Несколько CRD (разделённых маркерами начала и конца YAML) могут быть размещены в одном файле. Helm попытается загрузить все файлы из каталога CRD в Kubernetes.

Файлы CRD не могут быть шаблонизированы. Они должны быть обычными YAML-документами.

Когда Helm устанавливает новый чарт, он загружает CRD, приостанавливается до тех пор, пока CRD не станут доступны через API-сервер, а затем запускает движок шаблонов, рендерит остальную часть чарта и загружает её в Kubernetes. Благодаря такому порядку информация о CRD доступна в объекте .Capabilities в шаблонах Helm, и шаблоны Helm могут создавать новые экземпляры объектов, объявленных в CRD.

Например, если ваш чарт имеет CRD для CronTab в каталоге crds/, вы можете создавать экземпляры вида CronTab в каталоге templates/:

crontabs/
Chart.yaml
crds/
crontab.yaml
templates/
mycrontab.yaml

Файл crontab.yaml должен содержать CRD без директив шаблона:

kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab

Затем шаблон mycrontab.yaml может создать новый CronTab (используя шаблоны как обычно):

apiVersion: stable.example.com
kind: CronTab
metadata:
name: {{ .Values.name }}
spec:
# ...

Helm убедится, что вид CronTab установлен и доступен из API-сервера Kubernetes, прежде чем продолжить установку объектов из templates/.

Ограничения CRD

В отличие от большинства объектов в Kubernetes, CRD устанавливаются глобально. По этой причине Helm очень осторожен в управлении CRD. CRD имеют следующие ограничения:

  • CRD никогда не переустанавливаются. Если Helm определяет, что CRD в каталоге crds/ уже присутствуют (независимо от версии), Helm не будет пытаться установить или обновить их.
  • CRD никогда не устанавливаются при обновлении или откате. Helm создаёт CRD только при операциях установки.
  • CRD никогда не удаляются. Удаление CRD автоматически удаляет всё содержимое CRD во всех пространствах имён кластера. Следовательно, Helm не удаляет CRD.

Операторам, желающим обновить или удалить CRD, рекомендуется делать это вручную и с большой осторожностью.

Использование Helm для управления чартами

Инструмент helm имеет несколько команд для работы с чартами.

Он может создать для вас новый чарт:

$ helm create mychart
Created mychart/

После редактирования чарта helm может упаковать его в архив чарта:

$ helm package mychart
Archived mychart-0.1.-.tgz

Вы также можете использовать helm для поиска проблем с форматированием или информацией вашего чарта:

$ helm lint mychart
No issues found

Репозитории чартов

Репозиторий чартов — это HTTP-сервер, на котором размещается один или несколько упакованных чартов. Хотя helm можно использовать для управления локальными каталогами чартов, когда дело доходит до совместного использования чартов, предпочтительным механизмом является репозиторий чартов.

Любой HTTP-сервер, который может обслуживать YAML-файлы и tar-файлы и отвечать на GET-запросы, может использоваться в качестве сервера репозитория. Команда Helm протестировала некоторые серверы, включая Google Cloud Storage с включённым режимом веб-сайта и S3 с включённым режимом веб-сайта.

Репозиторий характеризуется в первую очередь наличием специального файла index.yaml, который содержит список всех пакетов, предоставляемых репозиторием, вместе с метаданными, позволяющими получить и проверить эти пакеты.

На стороне клиента управление репозиториями осуществляется командами helm repo. Однако Helm не предоставляет инструментов для загрузки чартов на удалённые серверы репозиториев. Это связано с тем, что это добавило бы существенные требования к реализующему серверу и, таким образом, повысило бы барьер для настройки репозитория.

Стартовые пакеты чартов

Команда helm create принимает необязательную опцию --starter, позволяющую указать "стартовый чарт". Также опция starter имеет короткий псевдоним -p.

Примеры использования:

helm create my-chart --starter starter-name
helm create my-chart -p starter-name
helm create my-chart -p /absolute/path/to/starter-name

Стартеры — это обычные чарты, расположенные в $XDG_DATA_HOME/helm/starters. Как разработчик чартов, вы можете создавать чарты, специально предназначенные для использования в качестве стартеров. Такие чарты должны разрабатываться со следующими соображениями:

  • Chart.yaml будет перезаписан генератором.
  • Пользователи будут ожидать возможности изменять содержимое такого чарта, поэтому документация должна указывать, как пользователи могут это делать.
  • Все вхождения <CHARTNAME> будут заменены указанным именем чарта, чтобы стартовые чарты могли использоваться как шаблоны, за исключением некоторых переменных файлов. Например, если вы используете пользовательские файлы в каталоге vars или определённые файлы README.md, <CHARTNAME> НЕ будет переопределён внутри них. Кроме того, описание чарта не наследуется.

В настоящее время единственный способ добавить чарт в $XDG_DATA_HOME/helm/starters — скопировать его туда вручную. В документации вашего чарта вы можете описать этот процесс.