Прямой ответ
Helm — пакетный менеджер Kubernetes: чарт упаковывает манифесты приложения (Deployment, Service, Ingress — базовые объекты) в параметризуемый шаблон, values задают конкретные значения (образ, реплики, env по окружению), релиз — установленный экземпляр чарта с историей версий (helm upgrade/helm rollback — деплой и откат одной командой). Когда он оправдан: приложение деплоится в несколько окружений/кластеров с различиями в конфигах (стенд/препрод/прод — один чарт, разные values-файлы), зависимостей много (БД, Redis, ingress — субчарты или готовые чарты bitnami-класса), нужен «установить сложный стек одной командой». Когда избыточен: один сервис в одном namespace — kubectl apply -k (kustomize) проще и без шаблонного языка; «Helm ради одной переменной» — классическая переработка. Главные практики: values — плоские и документированные (глубокая вложенность и «умные» шаблоны с логикой превращают чарт в нечитаемый язык — тесты helm template + lint обязательны), секреты не в values открытым текстом (SOPS/sealed-secrets/Vault — подход), миграции БД — хуком pre-upgrade (alembic Job'ой до новых подов), и версия чарта/образа — из CI, не «latest».
Структура чарта и шаблонизация
Каркас: Chart.yaml (имя/версия чарта — semver, дисциплина версий применима), values.yaml (дефолты), templates/ (манифесты с подстановками {{ .Values.image.tag }}, _helpers.tpl — именованные шаблоны меток/имён), .helmignore. Механика: helm template рендерит манифесты локально (отладка без кластера — главная команда разработки чарта), helm lint — проверка структуры, helm install/upgrade — применение с записью релиза в секрет кластера (история — источник для rollback). Разумная шаблонизация: параметризация значений (образ, ресурсы, env) — да; условная логика (if/else по флагам фич) — ограниченно (чарт, который рендерит разную структуру по флагам, тестируется как код — а тестов обычно нет); «библиотека общих шаблонов на 10 чартов» — сигнал посмотреть на kustomize-оверлеи или внутренний platform-чарт с явным контрактом. Полезные встроенные возможности: values.schema.json (валидация values — опечатка в ключе ловится до деплоя, а не «поднял поды без лимитов»), NOTES.txt (памятка после установки), tests (helm test — под с проверкой доступности после деплоя).
Values по окружениям и секреты
Паттерн окружений: один чарт + values-staging.yaml/values-prod.yaml (реплики, ресурсы, домены, feature-флаги — флаги как values); деплой: helm upgrade app ./chart -f values-prod.yaml --set image.tag=$GIT_SHA; различия окружений видны диффом values-файлов (аудит «чем прод отличается от стейджа» — одна команда). Антипаттерны: правка values руками в кластере (--set в рантайме без фиксации в git — следующий деплой затрёт; values-файлы — в репозиторий, GitOps-подход: ArgoCD/Flux следят за репозиторием — декларативность как у Terraform); секреты в values.yaml репозитория (values — часть чарта в git — токены утекают; решения: SOPS-шифрование values-файла, sealed-secrets-контроллер, внешний Vault с инжектором — секрет попадает в под, минуя git). Секрет-гигиена дополняется RBAC чарта: ServiceAccount с минимальными правами (не default-SA namespace'а — «приложению не нужны права на секреты соседей»).
Хуки, миграции, upgrade/rollback
Хуки — Job'ы, привязанные к событиям релиза: pre-install/pre-upgrade (миграции БД, подготовка данных — alembic upgrade head до наката новых подов: старая схема + новые поды = поломка; expand/contract-миграции дают обратную совместимость — практика), post-install (смоук-тесты, инициализация), pre-delete (очистка). Вес хуков определяет порядок; провал pre-upgrade отменяет релиз (миграция не прошла — новые поды не поднялись — безопасная семантика). Upgrade — helm upgrade --install (идемпотентно: ставит или обновляет) + --atomic (провал — автоматический rollback) + --wait --timeout 5m (ждать готовности подов — readiness-пробы как критерий); история: helm history (ревизии), helm rollback app 12 (откат конфигурации — но не миграций БД: схема назад не отматывается — отсюда expand/contract обязателен для откатываемых релизов). Релиз-артефакты: версия чарта растёт с каждым изменением (CI публикует чарт в OCI-реестр — образ и чарт версионируются парой), values-оверлеи — в git; «подеплоили и не знаем, какой версии чарт» — лечится аннотациями/GitOps.
Практический сценарий: чарт сервиса на три окружения
Задача: сервис из трёх объектов (Deployment, Service, Ingress) + Job миграций, окружения dev/staging/prod. Разработка: helm create app — скелет; чистка шаблона (убрана «универсальность» стартового чарта — HPA/subchart-примеры до востребованности); values: image.repository/tag, replicaCount, resources, ingress.host, env (список env-пар), migrations.enabled; миграции — pre-upgrade hook Job с тем же образом (alembic upgrade head); values.schema.json на обязательные ключи. Окружения: три values-файла в репозитории; CI: линт + helm template (рендер в артефакт PR — ревьюер видит итоговые манифесты, не шаблоны) + helm upgrade --install -f values-env.yaml --set image.tag=$SHA --atomic --wait на стейдж, прод — тем же шагом после ручного подтверждения. Инцидент-учение на стейдже: миграция с ошибкой — pre-upgrade Job упал → --atomic откатил релиз, поды остались на старой версии — пользователи не заметили (семантика подтверждена); фикс миграции — повторный upgrade. На проде через месяц: откат релиза из-за бага фичи — helm rollback за 40 секунд (миграция была expand-only — старые поды работают с новой схемой — дисциплина окупилась). Итог: деплой — одна команда CI, различия окружений — три читаемых файла, откат — секунды.
FAQ
Helm или kustomize? Helm — параметризуемые пакеты с логикой и зависимостями (публичные чарты, сложные стеки, значения-переменные); kustomize — бесшаблонное наложение патчей на готовые манифесты (простые приложения, GitOps — нативно в ArgoCD/kubectl); комбинация (helm-рендер + kustomize-оверлей) встречается, но удваивает сложность — выбирать один основной инструмент.
Готовые чарты (bitnami и т.п.) — брать? Для инфраструктурных зависимостей (Postgres/Redis/Kafka на стейдж) — практично; в проде — с оглядкой: значения по умолчанию не равны прод-безопасным (пароли, ресурсы, persistence), версии отстают/обгоняют — пинить версию чарта и читать его values целиком; управляемые сервисы вместо in-cluster БД — часто дешевле суммарно.
Как тестировать чарты?
helm lint (структура), helm template + kubeconform/kubeval (манифесты валидны против схемы K8s), helm-unittest (юниты по шаблонам — значения дают ожидаемые фрагменты), helm test в кластере (пост-деплой смоук) — минимум lint+template в CI закрывает большинство «чарт сломался» до кластера.
Нужны ли субчарты для зависимостей приложения? Субчарт (зависимость в Chart.yaml) удобен стендам «всё включено» (приложение + Redis одной установкой); в проде зависимости обычно живут отдельными релизами (свой жизненный цикл/обновления/бэкапы — PITR у БД свой) — связка через внешние адреса, не субчарты.
Источники: документация Helm (docs, chart best practices, rollback) — ссылки в шапке.