LEARN X · ЗА 14 МИН

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
Поддержать проект