Helm: основы, values, откаты и приёмы
Helm — менеджер пакетов для Kubernetes. Чарт описывает приложение, релиз — его установку в конкретном кластере.
Основные понятия
| Понятие | Что означает |
| Chart (чарт) | Пакет: шаблоны манифестов, значения по умолчанию и метаданные. |
| Release (релиз) | Установленный экземпляр чарта с конкретным именем в namespace. Один чарт можно поставить несколько раз под разными именами. |
| Revision (ревизия) | Номер версии релиза. Каждое обновление создаёт новую ревизию, их можно откатывать. |
| Repository (репозиторий) | Место, откуда берутся чарты: HTTP-репозиторий или OCI-реестр. |
| Values (значения) | Параметры, которые подставляются в шаблоны и меняют итоговые манифесты. |
Репозитории и поиск чартов
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update # обновить индекс всех репозиториев
helm repo list # подключённые репозитории
helm repo remove bitnami
helm search repo nginx # поиск по подключённым репозиториям
helm search repo nginx --versions # все версии чарта
helm search hub wordpress # поиск на Artifact Hub
Установка и обновление
| Команда | Что делает |
| helm install | Установить релиз. Имя релиза и чарт обязательны. |
| helm install -n --create-namespace | Установить в namespace и создать его, если его нет. |
| helm install --version | Зафиксировать версию чарта. |
| helm upgrade | Обновить существующий релиз новой версией чарта или новыми значениями. |
| helm upgrade --install | Установить, если релиза нет, иначе обновить. Удобно в CI, потому что команда идемпотентна. |
| --atomic | При ошибке откатить релиз автоматически. Включает --wait. |
| --wait / --timeout | Ждать, пока ресурсы станут готовы, с ограничением по времени (по умолчанию 5m). |
| --dry-run | Показать, что будет создано, не применяя изменения. Добавьте --debug, чтобы увидеть итоговые значения. |
| --reuse-values | Взять значения предыдущей ревизии и поверх них применить новые. |
| --reset-values | Игнорировать прежние значения и использовать только новые. |
# Установка с нуля
helm install web bitnami/nginx -n demo --create-namespace --version 15.4.0 -f values-prod.yaml
# Самый частый вариант для CI/CD
helm upgrade --install web bitnami/nginx -n demo -f values-prod.yaml --atomic --timeout 5m
# Посмотреть, что изменится, без применения
helm upgrade web bitnami/nginx -n demo -f values-prod.yaml --dry-run --debug
Values: как задаются и как приоритеты
Значения можно передать несколькими способами. Приоритет от низкого к высокому:
- values.yaml внутри самого чарта (значения по умолчанию);
- файлы, переданные через
-f или --values; если файлов несколько, позже указанный перекрывает ранее указанный;
- параметры
--set, --set-string и --set-file из командной строки, они имеют наивысший приоритет.
# Значения из файла
helm install web bitnami/nginx -f values-base.yaml -f values-prod.yaml
# Точечная подстановка через --set
helm upgrade web bitnami/nginx --set replicaCount=3 --set image.tag=1.27
# Строка, которую Helm не должен превращать в число или bool
helm upgrade web chart --set-string annotations.build=0042
# Значение из файла (например, сертификат)
helm upgrade web chart --set-file tls.cert=./cert.pem
# Вложенные списки и значения с запятыми
helm upgrade web chart --set 'hosts[0]=example.com,hosts[1]=www.example.com'
helm upgrade web chart --set-json 'resources={"limits":{"memory":"512Mi"}}'
Посмотреть и подготовить значения
helm show values bitnami/nginx > default-values.yaml # все параметры чарта с описанием
helm get values web -n demo # значения текущего релиза
helm get values web -n demo --all # с учётом значений по умолчанию
helm get manifest web -n demo # итоговые манифесты, как они применены
Держите в репозитории отдельный файл значений на каждое окружение (values-dev.yaml, values-prod.yaml), а общие параметры вынесите в базовый файл. Так видно, чем окружения отличаются, и меньше шансов перепутать продакшен.
Не храните пароли и токены в values.yaml в открытом виде. Лучше передавать секреты через Secret, который создан заранее, или через плагины для шифрования (например, helm-secrets с sops). Значения из --set видны в истории релиза.
Статус, история и откаты
| Команда | Что делает |
| helm list -A | Все релизы во всех namespace. |
| helm status | Текущее состояние релиза и заметки из NOTES.txt. |
| helm history | Все ревизии релиза: номер, дата, статус, версия чарта. |
| helm rollback | Вернуться к указанной ревизии. Откат тоже создаёт новую ревизию. |
| helm rollback --wait | Откатиться и дождаться готовности ресурсов. |
| helm uninstall | Удалить релиз и его ресурсы. |
| helm uninstall --keep-history | Удалить ресурсы, но сохранить историю релиза. |
helm history web -n demo
helm rollback web 3 -n demo --wait # вернуться к ревизии 3
helm status web -n demo
helm get values web -n demo --revision 3 # значения конкретной ревизии
Откат возвращает манифесты к состоянию выбранной ревизии. Он не откатывает данные: если приложение записало миграции в базу, Helm о них не знает. Такие изменения нужно учитывать отдельно.
Ограничьте число хранимых ревизий через --history-max 10 или в настройках CI. Иначе в Secret каждого релиза будут копиться старые манифесты, и helm history станет длинным.
Проверка чарта до установки
helm lint ./mychart # ошибки в структуре и шаблонах
helm template web ./mychart -f values-prod.yaml # отрисовать манифесты локально
helm template web ./mychart | kubectl apply --dry-run=client -f -
helm test web -n demo # запустить тесты из templates/tests/
Создание своего чарта
helm create mychart # заготовка структуры
helm package ./mychart # собрать архив mychart-0.1.0.tgz
helm dependency update ./mychart # подтянуть зависимости из Chart.yaml
# Минимальная структура
mychart/
Chart.yaml # имя, версия, описание
values.yaml # значения по умолчанию
templates/ # шаблоны манифестов
charts/ # зависимости
# Фрагмент шаблона: значения подставляются через .Values
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-app
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: app
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
OCI-реестры
helm registry login registry.example.com
helm package ./mychart
helm push mychart-0.1.0.tgz oci://registry.example.com/charts
helm install web oci://registry.example.com/charts/mychart --version 0.1.0
Лайфхаки
- Сравнить релизы перед обновлением. Плагин helm-diff показывает разницу манифестов:
helm diff upgrade web bitnami/nginx -f values-prod.yaml.
- Быстро проверить итоговые значения.
helm template ... -f a.yaml -f b.yaml | less покажет результат без подключения к кластеру.
- Не забывайте про --atomic в CI. Неудачный деплой не оставит кластер в полуготовом состоянии.
- Фиксируйте версию чарта (--version), чтобы сборка была воспроизводимой.
- Переносите конфиг через файлы, а не через --set. Файлы попадают в git и видны в ревью, а длинные цепочки --set быстро становятся нечитаемыми.
- Используйте --namespace и --create-namespace вместе. Так релиз не попадёт случайно в default.
- Проверяйте схему values. Файл values.schema.json в чарте не даст передать значение нужного типа или пропустить обязательный параметр.
- Пробуйте чарт в kind или minikube перед продакшеном: там дешевле ошибиться.
- Переменные окружения в CI. Передавайте --set image.tag=$CI_COMMIT_SHORT_SHA, чтобы каждый деплой был привязан к коммиту.
Типичные ошибки
| Симптом | Частая причина и решение |
| Error: UPGRADE FAILED: another operation is in progress | Предыдущая операция не завершилась. Посмотрите helm history: если статус pending-upgrade, откатитесь к последней успешной ревизии. |
| Error: cannot re-use a name that is still in use | Релиз с таким именем уже есть. Используйте helm upgrade --install или другое имя. |
| Значение стало числом, хотя ожидалась строка | Helm приводит значение к типу. Используйте --set-string. |
| Новые значения не применились | Вы не передали --reuse-values или значения из файла перекрыты --set. Проверьте helm get values --all. |
| Чарт не найден в репозитории | Не выполнен helm repo update или не подключён нужный репозиторий. |
Порядок отладки такой: helm lint, затем helm template с теми же values, затем helm upgrade --dry-run --debug, и только потом реальная установка. Большинство ошибок видно уже на шаге template.