Структура Helm-чарта: Полный разбор Chart.yaml, values.yaml и templates с практическими примерами для Production | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Структура Helm-чарта: Полный разбор Chart.yaml, values.yaml и templates с практическими примерами для Production

04 апреля 2026 11 мин. чтения
Содержание статьи

Helm-чарт: от пользователя к создателю

Helm — это не просто команда для установки приложений в Kubernetes. Это инструмент управления приложениями, где чарт является его фундаментом. Понимание внутренней структуры чарта — это ключ к переходу от пассивного использования готовых решений к осмысленному созданию и кастомизации. Чарт — это единица управления, которая инкапсулирует версионность, конфигурацию и зависимости вашего приложения.

В этом руководстве вы получите не только теорию, но и практические навыки создания production-ready чартов. Вы узнаете:

  • Как устроены ключевые файлы: Chart.yaml, values.yaml и templates/.
  • Как создать с нуля рабочий чарт для Nginx.
  • Как строить сложные структуры values.yaml для реальных приложений.
  • Лучшие практики для production: валидация, управление зависимостями, организация шаблонов.
  • Частые ошибки DevOps инженеров и их решения.
  • Пример реального чарта с зависимостями (Nginx + Redis).

Цель этого руководства — не просто перечислить файлы, а показать систему, где каждый элемент играет свою роль. К концу статьи у вас будет не только теоретическое понимание, но и ваш собственный минимальный, но полностью рабочий чарт. Это основа для решения любых задач с Helm, от простой установки до создания production-ready развертываний.

Анатомия чарта: разбираем структуру директории

Стандартная структура директории Helm-чарта, созданная командой helm create, выглядит следующим образом:

my-chart/
├── Chart.yaml
├── values.yaml
├── charts/
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── tests/
└── .helmignore

Каждый элемент имеет строгое назначение:

  • Chart.yaml: Паспорт чарта, содержащий метаданные.
  • values.yaml: Центральный узел конфигурации, значения по умолчанию.
  • charts/: Директория для зависимостей (subcharts).
  • templates/: Сердце чарта — шаблоны манифестов Kubernetes.
  • .helmignore: Аналог .gitignore, исключает файлы из упаковки чарта.

Chart.yaml: паспорт вашего приложения

Файл Chart.yaml — это не формальность, а критически важные метаданные. Он используется репозиториями для индексации, Helm CLI для управления зависимостями и семантического версионирования.

Ключевые поля:

  • apiVersion: Версия API Helm (v2 для Helm 2, v1 для Helm 3). Для Helm 3 используйте apiVersion: v2.
  • name: Имя чарта. Должно быть уникальным в репозитории.
  • version: Версия чарта по правилам семантического версионирования (например, 1.0.0). Именно эта версия используется для управления релизами.
  • appVersion: Версия приложения, которое упаковывает чарт (например, 1.21.1 для nginx). Это информационное поле.
  • description: Краткое описание чарта.
  • type: Обычно application. Может быть library для чартов-библиотек.

Особое внимание заслуживает секция dependencies. Здесь описываются другие чарты, от которых зависит ваш. Зависимости скачиваются и помещаются в директорию charts/.

# Пример расширенного Chart.yaml
apiVersion: v2
name: my-nginx
version: surveyed
appVersion: "1.21.1"
description: A minimal Nginx deployment chart.
type: application
dependencies:
  - name: redis
    version: "~12.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled

values.yaml: центральный узел конфигурации и сложные структуры

Файл values.yaml — это главный инструмент для кастомизации чарта без правки шаблонов. Он реализует принцип разделения кода (шаблоны) и конфигурации (значения). Пользователь может переопределять эти значения через собственный файл values или флаг --set.

Структура данных — стандартный YAML: словари, списки, простые значения.

# Пример values.yaml с комментариями
# Количество реплик пода
replicaCount: 1

# Настройки образа контейнера
image:
  repository: nginx
  tag: "1.21.1"
  pullPolicy: IfNotPresent

# Настройки сервиса
service:
  type: ClusterIP
  port: 80

# Включение Ingress
ingress:
  enabled: false
  className: "nginx"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific

Правильно документированный values.yaml с комментариями — признак профессионального чарта, который легко адаптировать под свою среду.

Работа со сложными структурами в values.yaml

В production-чартах часто используются вложенные объекты и массивы. Вот как правильно с ними работать:

# Пример сложной структуры values.yaml
config:
  # Массив строковых конфигураций
  envVars:
    - name: LOG_LEVEL
      value: "INFO"
    - name: CACHE_SIZE
      value: "256"
  # Вложенный объект с настройками
  database:
    host: "db-primary"
    port: 5432
    ssl: true
  # Массив объектов для sidecar-контейнеров
  sidecars:
    - name: log-shipper
      image: "fluentd:latest"
      enabled: true
    - name: metrics-agent
      image: "prometheus/node-exporter"
      enabled: false

# Использование в шаблоне:
# Для массива envVars
{{- range .Values.config.envVars }}
- name: {{ .name }}
  value: {{ .value | quote }}
{{- end }}

# Для вложенного объекта
databaseUrl: "postgresql://{{ .Values.config.database.host }}:{{ .Values.config.database.port }}"

# Для условного включения sidecar
{{- range .Values.config.sidecars }}
{{- if .enabled }}
- name: {{ .name }}
  image: {{ .image }}
{{- end }}
{{- end }}

Если вы хотите глубже разобраться в инструментах конфигурации в Kubernetes, рекомендуем наше практическое сравнение CRD и ConfigMap.

Директория templates/: где манифесты обретают форму

Файлы в директории templates/ — это не готовые манифесты Kubernetes, а их шаблоны, написанные на языке Go Templates. «Магия» Helm заключается в том, что движок шаблонов подставляет значения из values.yaml и других источников в эти шаблоны, генерируя итоговые YAML-манифесты для применения в кластере.

Типовой набор включает:

  • deployment.yaml: Шаблон для развертывания (Deployment).
  • service.yaml: Шаблон для сервиса (Service).
  • ingress.yaml: Шаблон для входящего трафика (Ingress).
  • configmap.yaml, secret.yaml: Для конфигураций и секретов.
  • NOTES.txt: Шаблон для вывода кастомного сообщения после установки.

Ключевые концепции, которые используются в шаблонах:

  • {{ .Values.replicaCount }} — подстановка значения из файла values.yaml.
  • {{ .Release.Name }} — имя текущего релиза Helm.
  • {{ .Chart.Name }} — имя чарта из Chart.yaml.

Создаем свой первый чарт: практика на примере Nginx

Перейдем от теории к практике. Создадим минимальный, но полностью функциональный чарт для развертывания Nginx.

  1. Создаем базовую структуру и чистим лишнее:
    helm create my-nginx
    cd my-nginx
    # Удаляем лишние файлы для чистоты примера
    rm -rf templates/*
  2. Редактируем Chart.yaml: Упростим файл, оставив только самое необходимое.
    apiVersion: v2
    name: my-nginx
    version: 0.1.0
    description: A minimal Nginx Helm chart
    type: application
  3. Настраиваем values.yaml: Оставим только ключевые параметры для образа Nginx и сервиса.
    replicaCount: 1
    
    image:
      repository: nginx
      tag: "stable"
      pullPolicy: IfNotPresent
    
    service:
      type: ClusterIP
      port: 80
  4. Создаем основные шаблоны: В директории templates/ создадим два файла: deployment.yaml и service.yaml.

Пишем и понимаем шаблоны: от переменных к функциям

Давайте детально разберем синтаксис на примере шаблона deployment.yaml.

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-nginx
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: {{ .Values.service.port }}

Разбор элементов:

  • Подстановки: {{ .Values.replicaCount }} заменится на число 1 из values.yaml.
  • Конкатенация строк: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" сформирует строку "nginx:stable".
  • Использование объектов: {{ .Release.Name }} гарантирует уникальность имени развертывания для каждого релиза Helm.

Шаблоны поддерживают управляющие структуры:

{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
...
{{- end -}}

И функции с пайплайнами (конвейерами):

# Функция default задает значение по умолчанию, quote — оборачивает в кавычки.
name: {{ .Values.name | default .Chart.Name | quote }}

Для управления сложными приложениями часто требуется оркестрация контейнеров. Если вы рассматриваете альтернативы Kubernetes, вам может быть полезно практическое руководство по Docker Swarm.

Проверка и установка: не нажимаем Enter без проверки

Перед установкой чарта в кластер обязательна его верификация. Это предотвратит ошибки и потенциальные сбои.

  1. Проверка синтаксиса и структуры:
    helm lint .
    Команда проверит корректность Chart.yaml и шаблонов.
  2. Рендеринг итоговых манифестов (отладка):
    helm template . --debug
    Или с имитацией установки:
    helm install my-release . --dry-run --debug
    Эти команды покажут, какие именно YAML-файлы будут отправлены в кластер. Это лучший способ проверить логику подстановок и условных операторов.
  3. Установка в тестовый неймспейс:
    helm install my-nginx-release . --namespace test-namespace --create-namespace
    Если все проверки прошли успешно, можно выполнять установку.

Best Practices для production чартов

Создание чартов для production требует соблюдения определенных практик, которые повышают надежность, безопасность и удобство поддержки.

Организация шаблонов и использование _helpers.tpl

Для сложных чартов рекомендуется выносить повторяющуюся логику в файл-помощник templates/_helpers.tpl:

{{/*
Генерация стандартных лейблов для всех ресурсов чарта.
*/}}
{{- define "my-nginx.labels" -}}
app: nginx
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: Helm
{{- end -}}

{{/*
Генерация селектора для Deployment.
*/}}
{{- define "my-nginx.selectorLabels" -}}
app: nginx
release: {{ .Release.Name }}
{{- end -}}

{{/*
Создание полного имени образа с возможностью переопределения репозитория.
*/}}
{{- define "my-nginx.image" -}}
{{- $registry := .Values.image.registry | default "" -}}
{{- $repository := .Values.image.repository -}}
{{- $tag := .Values.image.tag | default .Chart.AppVersion -}}
{{- if $registry -}}
{{ $registry }}/{{ $repository }}:{{ $tag }}
{{- else -}}
{{ $repository }}:{{ $tag }}
{{- end -}}
{{- end -}}

Использование в шаблонах:

metadata:
  labels:
    {{- include "my-nginx.labels" . | nindent 4 }}
selector:
  matchLabels:
    {{- include "my-nginx.selectorLabels" . | nindent 6 }}
containers:
  - image: {{ include "my-nginx.image" . }}

Управление зависимостями и версионирование

Для production важно четко управлять зависимостями:

  1. Всегда указывайте точные версии зависимостей или используйте диапазоны с семантическим версионированием.
  2. Используйте helm dependency update для генерации Chart.lock, который фиксирует версии.
  3. Проверяйте обновления зависимостей регулярно с помощью helm dependency list.

Валидация значений с помощью JSON Schema

Файл values.schema.json позволяет валидировать входные данные до рендеринга шаблонов:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "replicaCount": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10,
      "description": "Количество реплик пода"
    },
    "image": {
      "type": "object",
      "properties": {
        "repository": {
          "type": "string",
          "pattern": "^[a-zA-Z0-9./_-]+$"
        },
        "tag": {
          "type": "string",
          "default": "latest"
        }
      },
      "required": ["repository"]
    }
  },
  "required": ["replicaCount", "image"]
}

Частые ошибки и их решение

При работе с Helm-чартами DevOps инженеры часто сталкиваются с типовыми проблемами. Вот наиболее распространенные из них и способы решения.

Ошибки в условных операторах и функциях

Проблема: Неправильное использование функций default или empty.

# НЕПРАВИЛЬНО: default не сработает, если ключ существует, но имеет значение false/0/""
{{ .Values.feature.enabled | default true }}

# ПРАВИЛЬНО: проверка на существование ключа
{{- if hasKey .Values "feature" }}
{{ .Values.feature.enabled | default true }}
{{- else }}
true
{{- end }}

Проблема: Ошибки в условных операторах с вложенными структурами.

# НЕПРАВИЛЬНО: вызовет ошибку, если .Values.ingress не определен
{{- if .Values.ingress.enabled }}

# ПРАВИЛЬНО: безопасная проверка
{{- if and .Values.ingress .Values.ingress.enabled }}

Проблемы с рендерингом и whitespace

Проблема: Лишние пустые строки в сгенерированных YAML-файлах.

# НЕПРАВИЛЬНО: оставляет пустые строки
{{ if .Values.debug }}
env:
  - name: DEBUG
    value: "true"
{{ end }}

# ПРАВИЛЬНО: использование дефисов для контроля whitespace
{{- if .Values.debug }}
env:
  - name: DEBUG
    value: "true"
{{- end }}

Ошибки, выявляемые helm lint

Команда helm lint помогает находить распространенные проблемы:

  • "chart metadata is missing" — проверьте, что все обязательные поля в Chart.yaml заполнены.
  • "unable to parse YAML" — проверьте синтаксис YAML в шаблонах, особенно отступы.
  • "icon is recommended" — добавьте поле icon в Chart.yaml для лучшего отображения в репозиториях.

Проблемы с зависимостями

Проблема: Зависимости не обновляются или устанавливаются неправильные версии.

Решение:

  1. Всегда запускайте helm dependency update после изменения dependencies в Chart.yaml.
  2. Проверяйте содержимое директории charts/ — там должны быть распакованные чарты.
  3. Используйте helm dependency build для пересборки зависимостей из lock-файла.

Если вы столкнулись с проблемами в работе пользовательских ресурсов (CR), которые часто используются в сложных чартах, вам поможет полное руководство по диагностике Custom Resources.

Пример реального чарта с зависимостями

Рассмотрим пример чарта для веб-приложения с Nginx и Redis в качестве кэша.

Chart.yaml с зависимостями

apiVersion: v2
name: web-app
version: 1.0.0
appVersion: "2.5.0"
description: Web application with Nginx and Redis cache
type: application
dependencies:
  - name: redis
    version: "~12.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled
    tags:
      - cache
  - name: postgresql
    version: "^11.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
    tags:
      - database

Values.yaml с конфигурацией зависимостей

# Основное приложение
replicaCount: 2

image:
  repository: myapp/web
  tag: "2.5.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 8080

# Redis зависимость
redis:
  enabled: true
  architecture: standalone
  auth:
    enabled: false
  master:
    persistence:
      enabled: false

# PostgreSQL зависимость
postgresql:
  enabled: true
  auth:
    username: appuser
    password: ""
    database: appdb
  primary:
    persistence:
      enabled: false

# Конфигурация приложения
appConfig:
  cache:
    host: "{{ .Release.Name }}-redis-master"
    port: 6379
  database:
    host: "{{ .Release.Name }}-postgresql"
    port: 5432

Шаблон ConfigMap с использованием зависимостей

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
  labels:
    {{- include "web-app.labels" . | nindent 4 }}
data:
  app.properties: |
    # Конфигурация кэша
    cache.host={{ .Values.appConfig.cache.host }}
    cache.port={{ .Values.appConfig.cache.port }}
    
    # Конфигурация базы данных
    db.host={{ .Values.appConfig.database.host }}
    db.port={{ .Values.appConfig.database.port }}
    db.name={{ .Values.postgresql.auth.database }}
    db.user={{ .Values.postgresql.auth.username }}
    
    # Условная конфигурация
    {{- if .Values.redis.enabled }}
    cache.enabled=true
    {{- else }}
    cache.enabled=false
    {{- end }}

От простого к сложному: элементы для поддерживаемых чартов

Минимальный рабочий чарт — это начало. Для создания профессиональных, удобных для командной работы и повторного использования чартов, рекомендуется добавить следующие элементы:

  • Файлы-помощники (templates/_helpers.tpl): Здесь выносят сложную логику шаблонов и определяют общие метки или функции. Например, определение стандартных лейблов чарта.
    {{- define "my-nginx.labels" -}}
    app: nginx
    chart: {{ .Chart.Name }}-{{ .Chart.Version }}
    release: {{ .Release.Name }}
    {{- end -}}
    Затем в шаблоне используете {{ include "my-nginx.labels" . }}.
  • Файл NOTES.txt: Шаблон в templates/NOTES.txt. Его содержимое выводится после успешной установки helm install. Идеально для подсказок пользователю: как получить доступ к приложению, проверить статус.
  • JSON-схема для values (values.schema.json): Позволяет валидировать файл values.yaml на соответствие структуре и типам данных до рендеринга шаблонов. Защищает от опечаток и некорректных конфигураций.
  • Файл Chart.lock: Автоматически генерируется командой helm dependency update. Фиксирует точные версии зависимостей, обеспечивая воспроизводимость сборки.
  • Тесты (templates/tests/): Позволяют определить Pod'ы, которые проверяют работоспособность установленного приложения. Запускаются командой helm test.

Итоги: ваш путь от структуры к мастерству

Вы разобрали фундаментальные блоки Helm-чарта:

  • Chart.yaml — метаданные и зависимости.
  • values.yaml — централизованная конфигурация.
  • templates/ — логика генерации манифестов на основе конфигурации.

Вы освоили принцип разделения кода (шаблоны) и конфигурации (values), который лежит в основе гибкости Helm. Вы научились обязательной практике проверки чарта с помощью helm lint и helm template --debug перед установкой в кластер.

Для дальнейшего развития рекомендуется:

  1. Изучить официальную документацию по функциям и пайплайнам шаблонов Helm.
  2. Анализировать структуру чартов из популярных репозиториев (например, bitnami).
  3. Практиковаться в упаковке своих собственных приложений, начиная с простых и постепенно добавляя элементы для поддерживаемости (_helpers.tpl, схему валидации).

Понимание внутренней структуры — это основа, которая позволяет уверенно читать, модифицировать и создавать Helm-чарты для эффективного управления приложениями в Kubernetes.

Поделиться:
Сохранить гайд? В закладки браузера