Перейти до основного вмісту
Версія: 4.0.0

Бібліотечні чарти

Бібліотечний чарт — це тип Helm чарту, який визначає примітиви або визначення, що можуть бути спільно використані шаблонами Helm в інших чартах. Це дозволяє користувачам ділитися фрагментами коду, які можна повторно використовувати у різних чартах, уникаючи повторень та підтримуючи чарти DRY (Don't Repeat Yourself).

Бібліотечні чарти було представлено у Helm 3 для формального визнання загальних або допоміжних чартів, які використовувалися авторами чартів ще з Helm 2. Додавши їх як тип чарту, вони надають:

  • Спосіб чітко розрізняти загальні та чарти застосунків
  • Логіку, що запобігає встановленню загального чарту
  • Відсутність рендерингу шаблонів у загальному чарті, які можуть містити артефакти релізу
  • Дозвіл залежним чартам використовувати контекст імпортера

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

Створення простого бібліотечного чарту

Як згадувалося раніше, бібліотечний чарт є різновидом Helm-чарту. Це означає, що ви можете почати з створення шаблонного чарту:

$ helm create mylibchart
Creating mylibchart

Спочатку видаліть усі файли в теці templates, оскільки ми будемо створювати власні визначення шаблонів у цьому прикладі.

$ rm -rf mylibchart/templates/*

Файл значень (values.yaml) також не буде потрібен.

$ rm -f mylibchart/values.yaml

Перш ніж перейти до створення загального коду, давайте швидко переглянемо деякі відповідні концепції Helm. Іменований шаблон (іноді називають partial або субшаблоном) — це просто шаблон, визначений у файлі та який має назву. У теці templates/ будь-який файл, який починається з підкреслення (_), не призначений для виводу маніфесту Kubernetes. Тому зазвичай допоміжні шаблони та partials розміщуються у файлах _*.tpl або _*.yaml.

У цьому прикладі ми створимо загальний ConfigMap, який створює порожній ресурс ConfigMap. Ми визначимо загальний ConfigMap у файлі mylibchart/templates/_configmap.yaml наступним чином:

{{- define "mylibchart.configmap.tpl" -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data: {}
{{- end -}}
{{- define "mylibchart.configmap" -}}
{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}}
{{- end -}}

Структура ConfigMap визначена в іменованому шаблоні mylibchart.configmap.tpl. Це простий ConfigMap з порожнім ресурсом data. У цьому файлі є інший іменований шаблон з назвою mylibchart.configmap. Цей іменований шаблон включає інший іменований шаблон mylibchart.util.merge, який приймає 2 іменованих шаблони як аргументи, шаблон, що викликає mylibchart.configmap і mylibchart.configmap.tpl.

Допоміжна функція mylibchart.util.merge є іменованим шаблоном у mylibchart/templates/_util.yaml. Це зручний інструмент з Загального допоміжного чарту Helm, оскільки він обʼєднує 2 шаблони та перевизначає будь-які спільні частини в обох:

{{- /*
mylibchart.util.merge обʼєднає два шаблони YAML і виведе результат.
Він приймає масив із трьох значень:
- контекст верхнього рівня
- назву шаблону перевизначення (призначення)
- назву базового шаблону (джерело)
*/}}
{{- define "mylibchart.util.merge" -}}
{{- $top := first . -}}
{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}}
{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}}
{{- toYaml (merge $overrides $tpl) -}}
{{- end -}}

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

Нарешті, змініть тип чарту на library. Це вимагає зміни файлу mylibchart/Chart.yaml наступним чином:

apiVersion: v2
name: mylibchart
description: Helm чарт для Kubernetes

# Чарт може бути або 'application', або 'library'.
#
# Чарти застосунків — це набори шаблонів, які можна упакувати в архіви
# з версіями для розгортання.
#
# # Чарт може бути чартом 'application' або 'library'.
#
# Чарти застосунків — це набір шаблонів, які можна упакувати в архіви з версіями для розгортання.
#
# Чарти бібліотек надають корисні утиліти або функції для розробника чартів. Вони включаються
# як залежності чартів застосунків, щоб вставити ці утиліти та функції в конвеєр рендерингу.
# Чарти бібліотек не визначають жодних шаблонів, тому їх неможливо розгорнути.
# type: application
type: library

# Це версія чарту. Це номер версії повинен збільшуватися кожного разу,
# коли ви вносите зміни в чарт і його шаблони, включаючи версію програми.
version: 0.1.0

# Це номер версії застосунку, що розгортається. Цей номер версії повинен
# збільшуватися кожного разу, коли ви вносите зміни в застосунок,
# рекомендується використовувати з лапками.
appVersion: "1.16.0"

Тепер бібліотечний чарт готовий до спільного використання, а його визначення ConfigMap — до повторного використання.

Перш ніж продовжити, варто перевірити, чи розпізнає Helm чарт як бібліотечний:

$ helm install mylibchart mylibchart/
Error: library charts are not installable

Використання простого бібліотечного чарту

Настав час використати бібліотечний чарт. Для цього створимо знову шаблонний чарт:

$ helm create mychart
Creating mychart

Знову очистимо файли шаблонів, оскільки ми хочемо створити лише ConfigMap:

$ rm -rf mychart/templates/*

Якщо ми хочемо створити простий ConfigMap у шаблоні Helm, він може виглядати приблизно так:

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data:
myvalue: "Hello World"

Однак, ми будемо повторно використовувати загальний код, створений у mylibchart. ConfigMap можна створити у файлі mychart/templates/configmap.yaml наступним чином:

{{- include "mylibchart.configmap" (list . "mychart.configmap") -}}
{{- define "mychart.configmap" -}}
data:
myvalue: "Hello World"
{{- end -}}

Ви можете побачити, що це спрощує роботу, яку ми маємо виконати, завдяки успадкуванню загального визначення ConfigMap, яке додає стандартні властивості для ConfigMap. У нашому шаблоні ми додаємо конфігурацію, в даному випадку ключ даних myvalue та його значення. Конфігурація замінює порожній ресурс загального ConfigMap. Це можливо завдяки допоміжній функції mylibchart.util.merge, про яку ми згадували в попередньому розділі.

Щоб мати можливість використовувати загальний код, нам потрібно додати mylibchart як залежність. Додайте наступний код в кінець файлу mychart/Chart.yaml:

# Загальний код у бібліотечному чарті
dependencies:
- name: mylibchart
version: 0.1.0
repository: file://../mylibchart

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

$ helm dependency update mychart/
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Deleting outdated charts

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

$ helm install mydemo mychart/ --debug --dry-run
install.go:159: [debug] Original chart version: ""
install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart

NAME: mydemo
LAST DEPLOYED: Tue Mar 3 17:48:47 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
imagePullSecrets: []
ingress:
annotations: {}
enabled: false
hosts:
- host: chart-example.local
paths: []
tls: []
mylibchart:
global: {}
nameOverride: ""
nodeSelector: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
port: 80
type: ClusterIP
serviceAccount:
annotations: {}
create: true
name: null
tolerations: []

HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
myvalue: Hello World
kind: ConfigMap
metadata:
labels:
app: mychart
chart: mychart-0.1.0
release: mydemo
name: mychart-mydemo

Це виглядає як ConfigMap, який нам потрібен, з перезаписуванням даних myvalue: Hello World. Встановімо його:

$ helm install mydemo mychart/
NAME: mydemo
LAST DEPLOYED: Tue Mar 3 17:52:40 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

Ми можемо отримати реліз і побачити, що фактичний шаблон був завантажений.

$ helm get manifest mydemo
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
myvalue: Hello World
kind: ConfigMap
metadata:
labels:
app: mychart
chart: mychart-0.1.0
release: mydemo
name: mychart-mydemo

Переваги бібліотечних чартів

З огляду на те, що бібліотечні чарти не можуть працювати як самостійні чарти, вони можуть використовувати такі функції:

  • Об’єкт .Files посилається на шляхи файлів у головному чарті, а не на локальний шлях бібліотечного чарту.
  • Об’єкт .Values є таким самим, як і в головному чарті, на відміну від субчартів застосунків, які отримують розділ значень, налаштованих під їхнім заголовком у головному чарті.

Common Helm Helper Chart

інформація

Репозиторій Common Helm Helper Chart на Github більше не підтримується, і репозиторій було визнано застарілим та зархівовано.

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

Ось короткий опис того, як ним користуватися. Більш детальну інформацію можна знайти в файлі README.

Створіть знову шаблонний чарт:

$ helm create demo
Creating demo

Використаймо загальний код з helper chart. Спочатку відредагуйте файл deployment demo/templates/deployment.yaml наступним чином:

{{- template "common.deployment" (list . "demo.deployment") -}}
{{- define "demo.deployment" -}}
## Вкажіть перевизначення для вашого ресурсу Deployment тут, наприклад
apiVersion: apps/v1
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "demo.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "demo.selectorLabels" . | nindent 8 }}

{{- end -}}

І тепер файл сервісу, demo/templates/service.yaml, наступним чином:

{{- template "common.service" (list . "demo.service") -}}
{{- define "demo.service" -}}
## Вкажіть перевизначення для вашого ресурсу Service тут, наприклад
# metadata:
# labels:
# custom: label
# spec:
# ports:
# - port: 8080
{{- end -}}

Ці шаблони показують, як успадкування загального коду з helper chart спрощує написання коду до конфігурації або налаштування ресурсів.

Щоб мати можливість використовувати загальний код, нам потрібно додати common як залежність. Додайте наступне в кінець файлу demo/Chart.yaml:

dependencies:
- name: common
version: "^0.0.5"
repository: "https://charts.helm.sh/incubator/"
примітка

Вам потрібно буде додати incubator до списку репозиторіїв Helm (helm repo add).

Оскільки ми включаємо чарт як динамічну залежність, нам потрібно виконати helm dependency update. Це скопіює helper chart у вашу теку charts/.

Оскільки helper chart використовує деякі конструкції Helm 2, вам потрібно буде додати наступне до demo/values.yaml, щоб дозволити завантаження образу nginx, оскільки це було оновлено в шаблонному чарті Helm 3:

image:
tag: 1.16.0

Ви можете перевірити, чи правильні шаблони чарту, перед розгортанням, використовуючи команди helm lint і helm template.

Якщо все добре, розгорніть чарт, використовуючи helm install!