Helm
Helm за 14 минут: чарты, релизы, values, Go-шаблоны, функции, if/range, include, зависимости, хуки и репозитории на закомментированных примерах.
Helm — это пакетный менеджер для Kubernetes. Он упаковывает набор YAML-манифестов в переиспользуемый пакет (чарт), подставляет в него параметры и устанавливает в кластер как именованный релиз — с историей версий, обновлениями и откатами. Ниже — экспресс-тур по всему важному на одной странице, плотно через комментарии в коде.
Что такое Helm
Три ключевых понятия: чарт (chart) — пакет с шаблонами манифестов, релиз (release) — установленный в кластер экземпляр чарта, репозиторий — хранилище чартов.
# Чарт = папка с манифестами + метаданными.
# Helm берёт шаблоны, подставляет значения (values)
# и отправляет готовые YAML в Kubernetes.
#
# Один и тот же чарт можно установить много раз —
# каждая установка это отдельный РЕЛИЗ со своим именем:
# helm install web-prod ./mychart -> релиз web-prod
# helm install web-stage ./mychart -> релиз web-stage
#
# # — это комментарий в YAML (как и в Go-шаблонах Helm)
# Проверить версию клиента Helm (Helm 3 — без Tiller)
helm version
# Helm 3 общается с кластером напрямую через kubeconfig,
# серверного компонента (Tiller из Helm 2) больше нет.
Структура чарта
Чарт — это каталог со строго заданными именами файлов и папок.
mychart/
Chart.yaml # метаданные чарта: имя, версия, описание
values.yaml # значения по умолчанию для шаблонов
templates/ # шаблоны манифестов Kubernetes
deployment.yaml
service.yaml
_helpers.tpl # вспомогательные именованные шаблоны
NOTES.txt # текст-подсказка после установки
charts/ # вложенные чарты-зависимости (subcharts)
.helmignore # что не паковать (как .gitignore)
# Chart.yaml — паспорт чарта
apiVersion: v2 # v2 = Helm 3
name: mychart # имя чарта
description: Демо-чарт для веб-приложения
type: application # application или library
version: 0.1.0 # ВЕРСИЯ ЧАРТА (semver), меняем при правках
appVersion: "1.16.0" # версия упакованного приложения (строкой)
Основные команды
# Установить чарт как релиз с именем myapp
helm install myapp ./mychart
# То же, но создать namespace, если его нет
helm install myapp ./mychart --namespace prod --create-namespace
# Сухой прогон: отрендерить и показать манифесты, НЕ применяя
helm install myapp ./mychart --dry-run --debug
# Обновить уже установленный релиз (новые values/версия чарта)
helm upgrade myapp ./mychart
# upgrade-or-install: поставить, если релиза ещё нет
helm upgrade --install myapp ./mychart
# Список релизов в текущем namespace
helm list
helm list --all-namespaces # по всему кластеру
# История ревизий релиза
helm history myapp
# Откатить релиз на ревизию 1
helm rollback myapp 1
# Удалить релиз (с историей)
helm uninstall myapp
# Посмотреть, что РЕАЛЬНО отрендерится, без установки
helm template myapp ./mychart
Values: значения чарта
Все настраиваемые параметры живут в values.yaml и доступны в шаблонах через .Values. Их можно переопределять при установке.
# values.yaml — значения по умолчанию
replicaCount: 2
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources: {} # пусто = без лимитов по умолчанию
# Переопределить одно значение прямо в командной строке
helm install myapp ./mychart --set replicaCount=5
# Вложенные ключи через точку
helm install myapp ./mychart --set image.tag=1.27
# Несколько значений сразу
helm upgrade myapp ./mychart --set image.tag=1.27,service.port=8080
# Подключить отдельный файл со значениями (приоритет выше defaults)
helm upgrade myapp ./mychart -f values-prod.yaml
# Приоритет (от низшего к высшему):
# values.yaml чарта < -f файл < --set
Шаблоны: Go templates
Файлы в templates/ — это Go-шаблоны. Вставки делаются через {{ }}. Helm подставляет встроенные объекты: .Values, .Release, .Chart, .Files, .Capabilities.
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
# .Release.Name — имя релиза (из helm install ИМЯ ...)
name: {{ .Release.Name }}-config
data:
# .Values.* — значения из values.yaml / --set / -f
replicas: "{{ .Values.replicaCount }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
# .Chart.* — поля из Chart.yaml
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
# .Release.Namespace — namespace установки
ns: "{{ .Release.Namespace }}"
# Управление пробелами:
# {{- убирает пробелы/перевод строки СЛЕВА
# -}} убирает пробелы/перевод строки СПРАВА
# Это важно, чтобы YAML-отступы не съезжали.
data:
value: {{- if true }} yes {{- end }}
Функции и пайпы
Внутри {{ }} можно вызывать функции. Удобнее всего — через пайп |, передавая значение слева в функцию справа.
# default — значение по умолчанию, если переменная пуста
name: {{ .Values.name | default "my-service" }}
# quote — обернуть в двойные кавычки
tag: {{ .Values.image.tag | quote }}
# upper / lower — регистр
env: {{ .Values.env | upper }}
# Цепочка пайпов читается слева направо:
# взять значение -> подставить default -> обрезать -> в кавычки
host: {{ .Values.host | default "localhost" | trim | quote }}
# Обычный (не-пайповый) вызов: функция аргумент
repl: {{ printf "%s-%d" .Release.Name 3 }}
# nindent — перенос + отступ N пробелов (для вложенных блоков)
labels:
{{- include "mychart.labels" . | nindent 4 }}
Управляющие конструкции
Шаблоны поддерживают условия и циклы: if/else/end, range, with.
# IF / ELSE / END
{{- if .Values.ingress.enabled }}
kind: Ingress
{{- else }}
# ingress отключён в values
{{- end }}
# RANGE — цикл по списку или словарю.
# Внутри range точка . = текущий элемент
env:
{{- range .Values.envVars }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
# RANGE по словарю: ключ и значение
{{- range $key, $val := .Values.labels }}
{{ $key }}: {{ $val | quote }}
{{- end }}
# WITH — сузить область видимости (.)
# внутри блока . указывает на .Values.resources
{{- with .Values.resources }}
resources:
limits:
cpu: {{ .limits.cpu }}
{{- end }}
Именованные шаблоны
Повторяющиеся куски выносят в именованные шаблоны через define и подключают через include. Обычно их держат в templates/_helpers.tpl (файлы на _ не рендерятся в манифесты).
# templates/_helpers.tpl
# Объявляем именованный шаблон
{{- define "mychart.fullname" -}}
{{ .Release.Name }}-{{ .Chart.Name }}
{{- end -}}
# Шаблон с набором меток
{{- define "mychart.labels" -}}
app: {{ .Chart.Name }}
release: {{ .Release.Name }}
{{- end -}}
# Использование в манифесте.
# include предпочтительнее template: его вывод
# можно пропустить через пайп (nindent и т.п.)
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
# Второй аргумент (.) передаёт контекст внутрь шаблона —
# без него .Release / .Values там будут недоступны.
Зависимости
Чарт может зависеть от других чартов (например, базы данных). Зависимости объявляют в Chart.yaml и подтягивают в charts/.
# Chart.yaml — блок зависимостей
dependencies:
- name: postgresql
version: "15.x.x"
repository: https://charts.bitnami.com/bitnami
# condition включает/выключает subchart через values
condition: postgresql.enabled
# Скачать зависимости в папку charts/ (по Chart.yaml)
helm dependency update ./mychart
# Показать список зависимостей и их статус
helm dependency list ./mychart
# Значения subchart переопределяются через его имя:
# в values.yaml корневого чарта пишем блок postgresql:
# postgresql:
# enabled: true
# auth:
# database: mydb
Хуки (hooks)
Хуки позволяют запускать манифесты в определённый момент жизненного цикла релиза — например, миграцию БД перед обновлением. Задаются аннотацией.
# templates/migrate-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Release.Name }}-migrate
annotations:
# Запустить ПЕРЕД install и upgrade
"helm.sh/hook": pre-install,pre-upgrade
# Порядок выполнения хуков (меньше = раньше)
"helm.sh/hook-weight": "0"
# Удалить Job, когда хук успешно отработал
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["sh", "-c", "echo run migrations"]
# Типичные точки: pre-install, post-install,
# pre-upgrade, post-upgrade, pre-delete, post-delete
Репозитории чартов
# Добавить публичный репозиторий чартов
helm repo add bitnami https://charts.bitnami.com/bitnami
# Обновить локальный индекс репозиториев
helm repo update
# Список подключённых репозиториев
helm repo list
# Найти чарт в добавленных репозиториях
helm search repo nginx
# Установить чарт прямо из репозитория (repo/chart)
helm install mydb bitnami/postgresql
# Посмотреть values чарта перед установкой
helm show values bitnami/postgresql
Типичный чарт: Deployment
Соберём всё вместе — шаблон Deployment, который берёт параметры из values и использует именованный шаблон для имени и меток.
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
# количество реплик — из values, с запасным значением 1
replicas: {{ .Values.replicaCount | default 1 }}
selector:
matchLabels:
app: {{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
# image:tag собираем из двух полей values
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
# Проверить, отрендерить и установить:
helm lint ./mychart # валидация чарта
helm template myapp ./mychart # увидеть итоговый YAML
helm upgrade --install myapp ./mychart -f values-prod.yaml