Чарти

Helm використовує формат пакування, який називається чарти. Чарт — це набір файлів, які описують повʼязаний набір ресурсів Kubernetes. Один чарт може бути використаний для розгортання чогось простого, як, наприклад, pod з memcached, або чогось складного, як повний вебстек з HTTP серверами, базами даних, кешами й так далі.

Чарти створюються як файли, розташовані в певній структурі тек. Вони можуть бути упаковані у версійні архіви для розгортання.

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

Цей документ пояснює формат чарту та надає основні рекомендації щодо створення чартів з використанням Helm.

Структура файлів чарту

Чарт організовано як набір файлів всередині теки. Назва теки відповідає назві чарту (без інформації про версію). Наприклад, чарт, який описує WordPress, буде зберігатися в теці wordpress/.

Всередині цієї теки Helm очікує структуру, яка відповідає наступному:

wordpress/
  Chart.yaml          # YAML файл, що містить інформацію про чарт
  LICENSE             # НЕОБОВʼЯЗКОВО: Текстовий файл, що містить ліцензію для чарту
  README.md           # НЕОБОВʼЯЗКОВО: Файл README
  values.yaml         # Файл стандартної конфігурації для цього чарту
  values.schema.json  # НЕОБОВʼЯЗКОВО: JSON-схема для накладання структури на файл values.yaml
  charts/             # Тека, що містить чарти, від яких залежить цей чарт.
  crds/               # Custom Resource Definitions
  templates/          # Тека шаблонів, які в поєднанні з values
                      # генерують валідні файли маніфестів Kubernetes.
  templates/NOTES.txt # НЕОБОВʼЯЗКОВО: Текстовий файл з короткими інструкціями

Helm резервує використання тек charts/, crds/ і templates/, а також перелічених назв файлів. Інші файли буде залишено без змін.

Файл Chart.yaml

Файл Chart.yaml є обовʼязковим для чарту. Він містить наступні поля:

apiVersion: Версія API чарту (обовʼязкове)
name: Назва чарту (обовʼязкове)
version: Версія SemVer 2 (обовʼязкове)
kubeVersion: Діапазон сумісних версій Kubernetes (необовʼязкове)
description: Короткий опис цього проєкту (необовʼязкове)
type: Тип чарту (необовʼязкове)
keywords:
  - Список ключових слів про цей проєкт (необовʼязкове)
home: URL головної сторінки проєкту (необовʼязкове)
sources:
  - Список URL-адрес з вихідним кодом проєкту (необовʼязкове)
dependencies: # Список залежностей чарту (необовʼязкове)
  - name: Назва чарту (nginx)
    version: Версія чарту ("1.2.3")
    repository: (необовʼязкове) URL репозиторію ("https://example.com/charts") або псевдонім ("@repo-name")
    condition: (необовʼязкове) YAML шлях, який відповідає за логічне значення, використовується для увімкнення/вимкнення чартів (наприклад, subchart1.enabled )
    tags: # (необовʼязкове)
      - Теґи можуть бути використані для групування чартів для одночасного увімкнення/вимкнення
    import-values: # (необовʼязкове)
      - ImportValues містить зіставлення вихідних значень з ключем батьківського елемента для імпорту. Кожен елемент може бути рядком або парою дочірніх/батьківських субсписків.
    alias: (необовʼязкове) Псевдонім для чарту. Корисно, коли вам потрібно додати той самий чарт кілька разів
maintainers: # (необовʼязкове)
  - name: Імʼя мейнтейнера (обовʼязкове для кожного мейнтейнера)
    email: Електронна пошта мейнтейнера (необовʼязкове для кожного мейнтейнера)
    url: URL для мейнтейнера (необовʼязкове для кожного мейнтейнера)
icon: URL до SVG або PNG зображення для використання як іконки (необовʼязкове).
appVersion: Версія програми, яку містить цей чарт (необовʼязкове). Не обовʼязково має бути SemVer. Рекомендується використовувати лапки.
deprecated: Чи цей чарт застарілий (необовʼязкове, булеве значення)
annotations:
  example: Список анотацій, згрупованих за іменами (необовʼязкове).

Починаючи з v3.3.2, додаткові поля не дозволені. Рекомендований підхід — додавати власні метадані в annotations.

Чарти та версіювання

Кожен чарт повинен мати номер версії. Версія повинна відповідати стандарту SemVer 2. На відміну від Helm Classic, Helm версії 2 та новіші використовують номери версій як маркери випуску. Пакети в репозиторіях ідентифікуються за назвою та версією.

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

nginx-1.2.3.tgz

Підтримуються також складніші імена SemVer 2, такі як version: 1.2.3-alpha.1+ef365. Але імена, які не відповідають стандарту SemVer, системою не допускаються.

Примітка: Якщо Helm Classic та Deployment Manager були тісно повʼязані з GitHub у контексті чартів, то Helm версії 2 та новіші не залежать від GitHub або навіть Git. Відповідно, він не використовує Git SHAs для версіювання.

Поле 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-коміт SHA, як 1234e10, як наукову нотацію.

З версії Helm v3.5.0 команда helm create автоматично обгортає поле appVersion у лапки.

Поле kubeVersion

Необовʼязкове поле kubeVersion може визначати обмеження версій semver для підтримуваної версії Kubernetes. 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). Для цього можна використовувати необовʼязкове поле deprecated у файлі Chart.yaml. Якщо остання версія чарту в репозиторії позначена як знята з підтримки, тоді весь чарт вважається застарілим. Назву чарту можна пізніше використовувати повторно, опублікувавши нову версію, яка не позначена як знята з підтримки. Процедура зняття чартів з підтримки включає такі кроки:

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

Типи чартів

Поле type визначає тип чарту. Є два типи: application та library. Стандартний тип — application, і це стандартний чарт, з яким можна повністю працювати. Чарт-бібліотека надає утиліти або функції для розробників чарту. Чарт-бібліотека відрізняється від чарту-застосунку тим, що він не встановлюється і зазвичай не містить жодних обʼєктів ресурсу.

Примітка: Чарт-застосунок можна використовувати як чарт-бібліотеку. Це активується шляхом встановлення типу library. Чарт тоді буде оброблятися як чарт-бібліотека, де всі утиліти та функції можуть бути використані. Усі обʼєкти ресурсів чарту не будуть оброблені.

Ліцензії, README та ПРИМІТКИ до чарту

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

Файл 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.

Додавання псевдоніма для чарту-залежності дозволяє додати чарт у залежності, використовуючи псевдонім як назву нової залежності.

Псевдонім може бути корисним, коли вам потрібно отримати доступ до чарту під іншим імʼям (іменами).

# 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

У наведеному вище прикладі для parentchart буде три залежності:

subchart
new-subchart-1
new-subchart-2

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

Поля tags та condition у залежностях

Крім інших полів, кожен запис у вимогах може містити необовʼязкові поля tags та condition.

Всі чарти будуть стандартно завантажені. Якщо присутні поля tags або condition, вони будуть оцінені та використані для керування завантаженням чартів, до яких вони застосовуються.

Condition — поле condition містить один або кілька шляхів YAML (розділених комами). Якщо цей шлях існує у значеннях основного чарту та оцінюється як булеве значення, чарт буде включений або виключений залежно від цього булевого значення. Оцінюється лише перший дійсний шлях у списку, і якщо шляхи не існують, то condition не має жодного ефекту.

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 з Tags та Conditions

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

helm install --set tags.front-end=true --set subchart2.enabled=false
Опрацювання Tags та Conditions
  • Умови (коли вони встановлені в значеннях) завжди переважають мітки. Перемагає перший існуючий шлях умови, а наступні для цього чарту ігноруються.
  • Мітки оцінюються так: "якщо будь-яка з міток чарту має значення true, тоді увімкніть чарт".
  • Значення міток та умов повинні бути встановлені у значеннях основного чарту.
  • Ключ tags: у значеннях має бути ключем верхнього рівня. Глобальні та вкладені таблиці tags: наразі не підтримуються.

Імпорт значень дочірніх чартів через залежності

У деяких випадках корисно, щоб значення дочірнього чарту передавалися до батьківського чарту та використовувалися як стандартні загальні значення. Додаткова перевага використання формату exports полягає в тому, що це дозволяє майбутнім інструментам інспектувати значення, які може налаштувати користувач.

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

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

Використання формату exports

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

# файл Chart.yaml батьківського чарту

dependencies:
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    import-values:
      - data
# файл values.yaml дочірнього чарту

exports:
  data:
    myint: 99

Оскільки ми вказуємо ключ data у нашому списку імпорту, Helm шукає цей ключ у полі exports дочірнього чарту та імпортує його вміст.

Фінальні значення батьківського чарту міститимуть наше експортоване поле:

# значення батьківського чарту

myint: 99

Зверніть увагу, що ключ data не міститься у фінальних значеннях батьківського чарту. Якщо вам потрібно вказати ключ батьківського чарту, використовуйте формат "child-parent".

Використання формату child-parent

Щоб отримати доступ до значень, які не містяться у ключі exports значень дочірнього чарту, вам потрібно вказати шлях до джерела значень для імпорту (child) та шлях до місця призначення у значеннях батьківського чарту (parent).

У прикладі нижче import-values інструктує Helm взяти будь-які значення, знайдені в шляху child:, та скопіювати їх у значення батьківського чарту в шлях, вказаний у parent:.

# файл Chart.yaml батьківського чарту

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

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

# файл values.yaml батьківського чарту

myimports:
  myint: 0
  mybool: false
  mystring: "helm rocks!"
# файл values.yaml subchart1

default:
  data:
    myint: 999
    mybool: true

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

# фінальні значення батьківського чарту

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

Це відбувається тому, що під час встановлення/оновлення чартів Helm агрегує обʼєкти Kubernetes з чарту та всіх його залежностей в єдиний набір, який потім сортується за типом, а потім за іменем, і створюється або оновлюється в такому порядку.

Таким чином, створюється єдиний реліз, який містить усі обʼєкти для чарту та його залежностей.

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

Шаблони та Значення

Шаблони Helm Chart написані на Go template, з додатковими функціями з бібліотеки 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: Політика отримання образу Docker в 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.yaml, який постачає необхідні значення, виглядатиме так:

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

Файл значень має формат 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 на клієнтському боці.

ПРИМІТКА: Якщо будь-які необхідні записи у файлі значень існують, їх можна оголосити як обовʼязкові в шаблоні чарту, використовуючи функцію ʼ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 }}

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

Файли значень можуть оголошувати значення як для верхнього рівня чарту, так і для будь-яких чартів, які включені у теку charts/ цього чарту. Інакше кажучи, файл значень може надавати значення чарту та його залежностям. Наприклад, чарт WordPress, що демонструється вище, має як mysql, так і apache як залежності. Файл значень може надавати значення всім цим компонентам:

title: "My WordPress Site" # Надсилається до шаблону WordPress

mysql:
  max_connections: 100 # Надсилається до MySQL
  password: "secret"

apache:
  port: 8080 # Передається 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" # Надсилається до шаблону WordPress

global:
  app: MyWordPress

mysql:
  max_connections: 100 # Надсилається до MySQL
  password: "secret"

apache:
  port: 8080 # Передається Apache

Вищенаведене додає розділ global зі значенням app: MyWordPress. Це значення доступне всім чартам як .Values.global.app.

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

title: "My WordPress Site" # Надсилається до шаблону WordPress

global:
  app: MyWordPress

mysql:
  global:
    app: MyWordPress
  max_connections: 100 # Надсилається до MySQL
  password: "secret"

apache:
  global:
    app: MyWordPress
  port: 8080 # Передається Apache

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

Якщо субчарт оголошує глобальну змінну, ця глобальна змінна буде передана далі вниз (в субчарти субчартів), але не вгору до батьківського чарту. Немає способу, щоб субдчарт впливав на значення батьківського чарту.

Також, глобальні змінні батьківських чартів мають перевагу над глобальними змінними з субчартів.

Файли схем

Іноді розробник чарту може захотіти визначити структуру для своїх значень. Це можна зробити, визначивши схему у файлі 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 субчарту, батьківський чарт повинен задовольняти ці вимоги, щоб бути дійсним.

Посилання

При написанні шаблонів, файлів значень і схем є кілька стандартних посилань, які можуть бути корисними:

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/v1
kind: CronTab
metadata:
  name: {{ .Values.name }}
spec:
   # ...

Helm забезпечить, що тип обʼєкта CronTab був встановлений і доступний з API сервера Kubernetes, перш ніж продовжити встановлення обʼєктів в templates/.

Обмеження на CRD

На відміну від більшості обʼєктів у Kubernetes, CRD (Custom Resource Definitions) встановлюються глобально. Тому 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, який дозволяє вказати "стартовий чарт". Також параметр стартера має короткий псевдонім -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 — це вручну скопіювати його туди. У документації вашого чарту ви можете пояснити цей процес.