Helm: встроенные объекты шаблонов

TL;DR: В шаблонах Helm доступны 6 корневых объектов: Release (мета релиза), Values (пользовательские параметры), Chart (метаданные чарта), Files (доступ к файлам), Capabilities (возможности кластера), Template (текущий шаблон). Все данные в шаблоне доступны через {{ .ObjectName.Field }}.

Зачем это знать

Шаблоны Helm — это Go templates с доступом к контексту. Каждый .yaml в templates/ получает корневой объект . (dot), через который доступны все встроенные объекты. Без понимания этих объектов шаблоны превращаются в копипасту примеров из Stack Overflow — работает, но непонятно почему.

Корневой контекст

Внутри любого шаблона . (dot) — это корневой объект, содержащий все встроенные объекты:

# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  # .Release, .Chart, .Values — всё доступно через dot
  name: {{ .Release.Name }}-config
  labels:
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
data:
  environment: {{ .Values.env }}

Важно: Внутри range и with контекст . меняется. Чтобы обратиться к корню — используй $:

{{- range .Values.servers }}
  # здесь . = текущий элемент, а не корневой объект
  name: {{ $.Release.Name }}-{{ .name }}
{{- end }}

Release — информация о релизе

Данные о текущем процессе установки/обновления. Заполняется Helm автоматически, не зависит от values.yaml.

ПолеТипОписание
.Release.NamestringИмя релиза (helm install **my-app** ...)
.Release.NamespacestringNamespace, в который устанавливается
.Release.RevisionintНомер ревизии (1 при install, инкрементируется при upgrade)
.Release.IsUpgradebooltrue если это helm upgrade
.Release.IsInstallbooltrue если это helm install
.Release.ServicestringВсегда "Helm"
# templates/deployment.yaml
metadata:
  name: {{ .Release.Name }}-api
  namespace: {{ .Release.Namespace }}
  labels:
    app.kubernetes.io/managed-by: {{ .Release.Service }}
  annotations:
    # Полезно для отслеживания: какая ревизия задеплоена
    helm.sh/revision: "{{ .Release.Revision }}"

Типичное использование: формирование уникальных имён ресурсов ({{ .Release.Name }}-component), чтобы несколько релизов одного чарта не конфликтовали в кластере.

Values — пользовательские параметры

Объединённые значения из нескольких источников (в порядке приоритета):

  1. values.yaml в чарте (defaults)
  2. Файл через -f custom-values.yaml
  3. Параметры через --set key=value (наивысший приоритет)
# values.yaml
app:
  name: payment-service
  replicas: 3
  image:
    repository: myregistry/payment
    tag: "1.4.2"
  config:
    logLevel: info
    dbPool: 10
# templates/deployment.yaml
spec:
  replicas: {{ .Values.app.replicas }}
  template:
    spec:
      containers:
        - name: {{ .Values.app.name }}
          image: {{ .Values.app.image.repository }}:{{ .Values.app.image.tag }}
          env:
            - name: LOG_LEVEL
              value: {{ .Values.app.config.logLevel }}
            - name: DB_POOL_SIZE
              value: "{{ .Values.app.config.dbPool }}"

Защита от отсутствующих значений

# default — значение по умолчанию, если ключ не задан
replicas: {{ .Values.app.replicas | default 1 }}
 
# required — шаблон не отрендерится без этого значения
image: {{ required "app.image.repository is required" .Values.app.image.repository }}
 
# Условный блок
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
# ...
{{- end }}

Chart — метаданные из Chart.yaml

Содержимое файла Chart.yaml. Доступны все поля спецификации.

ПолеОписание
.Chart.NameИмя чарта
.Chart.VersionВерсия чарта (SemVer)
.Chart.AppVersionВерсия приложения внутри чарта
.Chart.DescriptionОписание
.Chart.Typeapplication или library
.Chart.HomeURL домашней страницы проекта
# Chart.yaml
apiVersion: v2
name: payment-service
version: 0.3.1
appVersion: "1.4.2"
description: Payment processing microservice
# templates/deployment.yaml
metadata:
  labels:
    # Стандартные метки Kubernetes по рекомендации docs
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}

Примечание: .Chart.Version — версия чарта (пакета), .Chart.AppVersion — версия приложения. Они могут не совпадать: обновление values.yaml без изменения приложения бампит только Chart.Version.

Files — доступ к файлам чарта

Доступ к любым файлам внутри чарта, кроме: templates/, Chart.yaml, values.yaml, .helmignore.

МетодОписание
.Files.Get "path"Содержимое файла как строка
.Files.GetBytes "path"Содержимое как []byte
.Files.Glob "pattern"Файлы по паттерну
.Files.AsConfigСодержимое как блок data: для ConfigMap
.Files.AsSecretsСодержимое как base64 для Secret
.Files.Lines "path"Файл построчно
my-chart/
├── Chart.yaml
├── values.yaml
├── config/
│   ├── app.conf        # ← доступен через .Files
│   └── nginx.conf      # ← доступен через .Files
├── scripts/
│   └── init.sql        # ← доступен через .Files
└── templates/
    └── configmap.yaml
# templates/configmap.yaml — загрузить конфиги из файлов
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
  # Один файл
  app.conf: |
{{ .Files.Get "config/app.conf" | indent 4 }}
 
  # Все файлы из директории
{{ (.Files.Glob "config/*").AsConfig | indent 2 }}
# templates/secret.yaml — файлы как Secret (auto base64)
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-certs
type: Opaque
data:
{{ (.Files.Glob "certs/*").AsSecrets | indent 2 }}

Capabilities — информация о кластере

Информация о возможностях Kubernetes-кластера, в который происходит установка. Позволяет адаптировать шаблоны под версию кластера.

ПолеОписание
.Capabilities.KubeVersionВерсия Kubernetes (v1.29.0)
.Capabilities.KubeVersion.MajorМажорная версия (1)
.Capabilities.KubeVersion.MinorМинорная версия (29)
.Capabilities.APIVersionsСписок поддерживаемых API
.Capabilities.APIVersions.Has "api/v1"Проверка конкретного API
.Capabilities.HelmVersionВерсия Helm
# Выбор apiVersion в зависимости от версии кластера
{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
apiVersion: networking.k8s.io/v1
{{- else }}
apiVersion: networking.k8s.io/v1beta1
{{- end }}
kind: Ingress
# Использование CRD только если API доступен
{{- if .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: {{ .Release.Name }}-monitor
spec:
  selector:
    matchLabels:
      app: {{ .Release.Name }}
{{- end }}

Типичное использование: обратная совместимость чартов с разными версиями кластеров, условное создание ресурсов (ServiceMonitor только если Prometheus Operator установлен).

Template — информация о текущем шаблоне

Мета-информация о файле шаблона, который сейчас рендерится.

ПолеОписание
.Template.NameПуть к файлу (mychart/templates/deployment.yaml)
.Template.BasePathДиректория (mychart/templates)
# Добавить аннотацию, показывающую из какого шаблона сгенерирован ресурс
metadata:
  annotations:
    helm.sh/template: {{ .Template.Name }}

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

Как объекты взаимодействуют

Пример шаблона, использующего все 6 объектов:

# templates/deployment.yaml
{{- if .Capabilities.APIVersions.Has "apps/v1" }}
apiVersion: apps/v1
{{- end }}
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}
  namespace: {{ .Release.Namespace }}
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
  annotations:
    helm.sh/template: {{ .Template.Name }}
spec:
  replicas: {{ .Values.replicas | default 1 }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          volumeMounts:
            - name: config
              mountPath: /etc/app
      volumes:
        - name: config
          configMap:
            name: {{ .Release.Name }}-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
{{ (.Files.Glob "config/*").AsConfig | indent 2 }}

Подводные камни

ПроблемаСимптомРешение
.Values.port рендерится как floatport: 8080port: 8.08e+03Приведение: {{ int .Values.port }} или кавычки: "{{ .Values.port }}"
. теряется внутри range/with{{ .Release.Name }} — пустоИспользовать $: {{ $.Release.Name }}
Файл не виден через .FilesПустой выводФайл в templates/ или в .helmignore → недоступен
nil pointer при отсутствующем ключеОшибка рендеринга`{{ .Values.key
.Chart.AppVersion без кавычекYAML парсит 1.0 как числоВсегда "{{ .Chart.AppVersion }}" в кавычках
.Capabilities врёт при helm templateЛокальный рендер без кластераhelm template использует дефолтные Capabilities. Проверять через helm install --dry-run

Связанные материалы