Deployment и Service должны согласованно использовать имена и метки Pod, а число реплик, образ и порт нередко различаются между окружениями. Если копировать манифесты Kubernetes для каждой установки, легко поменять метку Pod и забыть обновить селектор Service. Тогда оба YAML-документа могут быть синтаксически корректными, но Service не выберет нужные Pod.
Helm решает задачу повторного использования манифестов: общую структуру ресурсов хранят в шаблонах, а различающиеся параметры передают отдельно. Вы создадите Chart с Deployment и Service, получите манифесты командой helm template и сравните результат для разных имён релиза и значений replicaCount.
Для практики нужны терминал, установленный Helm 4 и базовое понимание YAML, контейнеров, Deployment и Service. Kubernetes-кластер не нужен: сначала будем проверять только локальное формирование манифестов. Если Helm отсутствует, установите его по официальной инструкции и выполните helm version --short.
Что такое Helm, Chart и release
Helm — менеджер пакетов для Kubernetes: он управляет наборами ресурсов приложения, их установкой и обновлениями. Вместо поддержания отдельных копий Deployment, Service и других манифестов для каждого окружения можно описать их один раз и передавать нужные настройки.
Chart — это набор файлов, описывающих связанные ресурсы Kubernetes. У Chart есть метаданные, шаблоны Kubernetes-объектов и значения по умолчанию. Обработка этих файлов превращает выражения в шаблонах в обычный YAML. Структуру пакета определяет документация Helm о Chart.
Здесь важно различать четыре понятия:
- Chart — пакет исходных файлов приложения.
- Шаблон (template) — описание ресурса в
templates/с выражениями вроде{{ .Values.replicaCount }}. - Значения (values) — параметры подстановки из
values.yaml, другого файла или аргументов команды. - Релиз (release) — установка Chart в кластере под определённым именем с историей изменений.
Например, один Chart можно использовать для релизов demo и trial, меняя число реплик и имена ресурсов. helm template использует имя релиза при локальном формировании YAML, но не создаёт установку в кластере. Для создания установки используется другая команда — helm install. Важно не смешивать получение YAML с развёртыванием приложения.
Создаём структуру Chart
Возьмём минимальное веб-приложение с контейнером Nginx. От Chart нам нужны два объекта: Deployment с настраиваемым числом реплик и Service, выбирающий его Pod. Создайте каталог hello-web/templates, затем четыре файла. Все дальнейшие команды запускаются из каталога, в котором находится hello-web.
mkdir -p hello-web/templates
hello-web/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
└── service.yaml
Chart.yaml описывает сам Chart; values.yaml содержит значения по умолчанию для шаблонов. Каталог templates/ предназначен для описаний ресурсов. В руководстве Helm для авторов Chart разобрана эта связь.
Содержимое hello-web/Chart.yaml:
apiVersion: v2
name: hello-web
description: Минимальный Helm Chart для веб-сервиса
type: application
version: 0.1.0
appVersion: "1.0"
apiVersion: v2 определяет формат Chart, name — имя пакета, а type: application отличает прикладной Chart от библиотеки шаблонов. version задаёт версию Chart, а appVersion служит метаданными о версии приложения. В этом примере appVersion не связан с образом: поле image в Deployment будет получать тег из другого файла. Правила этих полей приведены в справке по Chart.
Теперь заполните hello-web/values.yaml:
replicaCount: 2
image:
repository: nginx
tag: "1.29.3"
service:
port: 80
replicaCount указывает желаемое число экземпляров, image.repository и image.tag задают строку образа, а service.port — порт Service. При локальном рендеринге nginx:1.29.3 остаётся только значением поля image. Доступность образа будет иметь значение при запуске Pod в кластере. Изменение любого из этих параметров не должно требовать дублирования шаблонов.
Можно начать и с helm create hello-web, но стандартная заготовка содержит больше ресурсов и вспомогательных файлов. Для понимания первого Chart достаточно четырёх перечисленных файлов.
Описываем шаблоны Deployment и Service
Шаблон Helm содержит обычные поля Kubernetes YAML и выражения шаблонов Go в {{ и }}. Имя релиза доступно шаблону как .Release.Name, а настройки из values.yaml — через .Values. Оба объекта описаны в справке Helm о встроенных объектах.
Создайте hello-web/templates/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-web
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}-web
template:
metadata:
labels:
app: {{ .Release.Name }}-web
spec:
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 80
В spec.replicas подставляется значение replicaCount, по умолчанию равное 2. В поле image объединяются image.repository и image.tag: из этих значений получается строка nginx:1.29.3.
В metadata.name, spec.selector.matchLabels и spec.template.metadata.labels используется одно имя release. При имени релиза demo получится demo-web. Метка Pod должна совпадать с селектором Deployment, иначе он не сможет корректно управлять нужными Pod. Эти требования и особенности неизменяемости селектора описаны в документации Kubernetes Deployment.
Добавьте hello-web/templates/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-web
spec:
selector:
app: {{ .Release.Name }}-web
ports:
- name: http
port: {{ .Values.service.port }}
targetPort: 80
Service выбирает Pod по spec.selector. Для релиза demo селектор Service станет app: demo-web — такой же, как метка Pod в Deployment. Документация Kubernetes Service объясняет работу селектора и назначение портов.
Обратите внимание на port и targetPort. Первый определяет порт Service и берётся из values.yaml, второй — порт внутри Pod, здесь постоянно 80. В Deployment контейнер также объявляет containerPort: 80. Если поменять только service.port, порт контейнера от этого не изменится.
Проверяем Chart без Kubernetes-кластера
Из каталога, содержащего hello-web, выполните:
helm version --short
helm lint ./hello-web
helm template demo ./hello-web
helm lint проверяет Chart на типовые ошибки структуры и шаблонов. Он помогает обнаружить проблемы в структуре Chart и ошибки при обработке шаблонов; совпадение селекторов разных ресурсов нужно проверить отдельно. Назначение команды описано в справке Helm lint.
helm template формирует YAML локально и не проверяет, примет ли его API-сервер Kubernetes. Такая проверка отделяет работу шаблонизатора от серверной валидации; это ограничение прямо указано в описании helm template.
В сформированном YAML найдите один Deployment и один Service. Проверьте имена объектов (demo-web), Deployment.spec.replicas (ожидается 2), строку образа (nginx:1.29.3) и порт Service (80). Отдельно сравните Deployment.spec.selector.matchLabels, Deployment.spec.template.metadata.labels и Service.spec.selector: значения app должны быть одинаковыми.
Теперь переопределите число реплик через аргумент команды:
helm template demo ./hello-web --set replicaCount=3
В полученном Deployment spec.replicas изменится с 2 на 3. Остальные поля, включая селекторы и настройки Service, сохранятся. Значения --set имеют приоритет над значениями из values.yaml; порядок описан в руководстве Helm по values.
Наконец, измените имя release, не меняя Chart:
helm template trial ./hello-web
Смена имени релиза меняет имена ресурсов и связанные с ними метки. Сравните три варианта сформированного YAML:
| Вызов | Имя Deployment и Service | Реплики | Метка Pod и селектор Service |
|---|---|---|---|
demo, значения по умолчанию | demo-web | 2 | app: demo-web |
demo, --set replicaCount=3 | demo-web | 3 | app: demo-web |
trial, значения по умолчанию | trial-web | 2 | app: trial-web |
Имена и селекторы остаются согласованными внутри каждого варианта. Для проверки установки релиза или доступности веб-сервера понадобится кластер Kubernetes.
Если Chart не формируется или результат не соответствует ожиданиям
Chart не найден. Проверьте рабочий каталог: ./hello-web/Chart.yaml должен существовать относительно него. Если вы уже вошли в hello-web, укажите для команды путь .. Сверьте регистр имён файлов: Helm ожидает Chart.yaml и каталог templates/.
Ошибка рендеринга или YAML. Проверьте отступы, двоеточия и написание ключей в values.yaml. Если шаблон обращается к .Values.replicaCount, а в файле написано replicasCount, будет прочитано другое поле. Для диагностического вывода используйте:
helm template demo ./hello-web --debug
Как работать с такой диагностикой, показывает официальное руководство по отладке шаблонов. После исправления повторите обычный рендеринг и перечитайте полученные объекты.
Неправильное число реплик. Убедитесь, что передали --set replicaCount=3, а не другое имя ключа. appVersion в Chart.yaml в этом примере не влияет ни на число реплик, ни на тег образа, потому что шаблон не использует .Chart.AppVersion.
Service не выбирает Pod. Даже если оба объекта синтаксически допустимы, между ними возможна смысловая ошибка. Например, селектор Service app: other-web не соответствует метке Pod app: demo-web. helm lint и helm template могут завершиться успешно и с таким селектором: они не проверяют, соответствует ли он меткам Pod. Сравнивайте поля селекторов вручную, а в кластере дополнительно проверяйте конечные точки Service.
Где заканчиваются возможности локальной проверки
helm template не обращается к Kubernetes API. В кластере манифест может быть отклонён из-за политик, неподдерживаемого API или серверной проверки. Даже после принятия Deployment Pod может остаться неготовым, если образ недоступен или процесс завершает работу. Проверить HTTP-ответ по одним манифестам невозможно.
Следующий этап для собственного тестового кластера — установить Chart, проверить появление Deployment и Pod, затем исследовать Service и доступность приложения. На этом этапе отдельно проверяют принятие ресурсов API-сервером, готовность Pod и связь Service с его конечными точками.
Результат
Вы собрали Chart из четырёх файлов: метаданных, значений по умолчанию и шаблонов Deployment и Service. Один набор шаблонов описывает ресурсы с разными именами релизов и разным числом реплик. При проверке сформированного YAML убедитесь, что селекторы Deployment и Service совпадают с метками Pod.
Для небольшого приложения этого достаточно, чтобы понять принцип Helm: исходники Chart сохраняют общую структуру, values определяют изменяемые поля, а helm template позволяет увидеть результат ещё до установки. Перед использованием Chart в кластере добавьте ограничения ресурсов, настройки безопасности и проверки готовности. После установки проверьте, что Kubernetes принял объекты и что Pod действительно работают.
Источники
- Назначение Chart, Chart.yaml, version и appVersion; раздел документации Helm о Chart
- Структура Chart, templates и подстановка values при рендеринге
- Встроенные объекты .Release и .Values в шаблонах Helm
- Значения по умолчанию и их переопределение; порядок переопределения значений
- Команда проверки корректности Chart и её ограничения
- Локальный рендеринг шаблонов без проверки Kubernetes API
- Установка Helm CLI
- Установка release в Kubernetes-кластере
- Отладка шаблонов Helm с —debug
- Генерация начальной структуры Chart командой helm create
- Поля Deployment и связь селектора с метками Pod
- Селектор Service, port и targetPort