Helm часто описывают как «пакетный менеджер для Kubernetes», и это довольно точное сравнение. Вместо того чтобы руками раскладывать по кластеру пачку YAML-файлов, вы ставите приложение одной командой — как через apt или yum, только целевые объекты тут — Kubernetes-ресурсы. Вся логика и манифесты упакованы в Helm charts.
Helm chart — это по сути директория с набором файлов, где описаны Deployment, Service, ConfigMap, Ingress, PVC и прочие вещи, нужные приложению. Один чарт может описывать как небольшой сервис, так и крупный кусок системы, и его можно перенести в другой кластер практически без боли, просто подправив значения.
Что Helm обычно даёт на практике:
- шаблонизацию манифестов с переменными через values — один набор шаблонов, разные конфиги для dev/prod;
- установку одной командой:
helm installподнимет все ресурсы, что описаны в чарте; - обновления через
helm upgrade— рулите версиями релизов; - откаты с помощью
helm rollback, если новая версия поехала не туда; - репозитории чартов (
helm repo) для публикации и переиспользования; - генерацию манифестов без фактической установки (
helm template), чтобы посмотреть, что именно пойдёт в кластер.
Типичные команды, с которыми сталкиваешься почти сразу:
helm install my-app ./chart— установка из локального чарта;helm upgrade my-app ./chart— обновление того же релиза новыми шаблонами/values;helm pull stable/postgresql— вытянуть чужой чарт из репозитория;helm list— посмотреть, какие релизы Helm сейчас знает в этом кластере.
В микросервисной архитектуре без Helm жить можно, но больно: у каждого сервиса свой набор манифестов, свои тонкие настройки. Чарты позволяют всё это привести к единому стандарту: шаблон один, значения под окружения — в отдельных файлах, и всё это отлично дружит с CI/CD.
В DevOps-командах Helm уже давно стал обычным инструментом поставки приложений в Kubernetes. Он уменьшает число ручных ошибок, делает выкладки повторяемыми и хорошо подходит и для внутренних сервисов, и для развёртывания типовых внешних компонентов — баз данных, мониторинга, ingress-контроллеров и так далее.
Структура Helm Chart #
Если открыть чарт «внутри», там будет обычная директория с предсказуемой структурой. Никакой магии, просто договорённость по именам файлов и папок.
Пример базового чарта:
my-chart/
├── Chart.yaml
├── values.yaml
├── charts/
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── _helpers.tpl
└── README.md
Компоненты: #
- Chart.yaml
Файл с метаданными чарта: имя, версия, описание, зависимости и прочие параметры. Что-то вроде «манифеста пакета». - values.yaml
Основной конфиг: тут задаются переменные, которые будут подставляться в шаблоны. Меняете их — не трогая сами шаблоны. Примером могут быть репликации, образ, теги и т.п. - templates/
Каталог с шаблонами Kubernetes-ресурсов. Здесь лежат Deployment, Service, Ingress, ConfigMap и всё остальное. Внутри используются Go-шаблоны и обращение к значениям изvalues.yaml. - _helpers.tpl
Вспомогательный файл с функциями и кусочками шаблонов, которые хочется переиспользовать, например генерация имён или общих label’ов. - charts/
Папка для зависимых чартов (subcharts). Если ваше приложение зависит, скажем, от Redis или PostgreSQL, их можно подключить сюда. - README.md
Не обязательный, но полезный файл с описанием того, как этим чаром пользоваться и какие там есть values.
Пример Helm-шаблона: templates/deployment.yaml #
Типичный шаблон Deployment может выглядеть примерно так (упрощённо):
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
app: {{ include "my-app.name" . }}
chart: {{ include "my-app.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ include "my-app.name" . }}
template:
metadata:
labels:
app: {{ include "my-app.name" . }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
Пример values.yaml к этому шаблону #
А вот так могут выглядеть значения по умолчанию:
replicaCount: 3
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
port: 80
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "250m"
memory: "128Mi"
Как это всё склеивается #
{{ .Values.* }}— обращение к значениям изvalues.yaml(или переопределённым при установке/обновлении);include— подтягивает вспомогательные шаблоны из_helpers.tpl, удобно для единых имён и label’ов;toYamlиnindent— помогают красиво отформатировать вложенные YAML-структуры, чтобы не страдать с отступами;- всё шаблонирование происходит до того, как манифесты попадут в кластер — либо в момент
helm install/upgrade, либо при генерации черезhelm template.
