linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Контейнеры (бонус)/helm-charts

kb/containers ── Контейнеры (бонус) ── intermediate

Helm charts - пакетный менеджер для Kubernetes

Helm - пакетный менеджер k8s. Chart - папка с Chart.yaml, values.yaml и templates/ (Go-templates над YAML). Releases хранятся в Secret namespace'а; upgrade/rollback атомарны. Альтернатива - kustomize (без templating, патчи).

view as markdownaka: helm, helm-chart, helmfile, helm-vs-kustomize

Зачем Helm

Развернуть приложение в k8s, это десяток YAML: Deployment, Service, Ingress, ConfigMap, Secret, ServiceAccount, RBAC, HPA, PDB. Развернуть то же самое в dev / staging / prod с разными значениями, копипаст и поломки.

Helm решает три задачи:

  1. Шаблонизация, values.yaml + Go-templates → готовые YAML
  2. Релизы, install/upgrade/rollback с версионированной историей
  3. Дистрибуция, chart как артефакт (tar.gz в OCI registry или старом chartmuseum)

В 2026, фактический стандарт для пакетирования open-source приложений в k8s. nginx, postgres, redis, prometheus, grafana, cert-manager, у всех есть official chart.

Структура chart

mychart/
├── Chart.yaml              # metadata: name, version, appVersion
├── values.yaml             # default-значения переменных
├── values.schema.json      # опционально: JSON-schema для values
├── templates/
│   ├── _helpers.tpl        # переиспользуемые шаблоны
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   └── NOTES.txt           # печатается после install
├── charts/                 # вложенные dependency-charts
└── crds/                   # CRD'ы устанавливаются ДО templates

Chart.yaml, metadata

yaml
apiVersion: v2                     # v2 = Helm 3
name: my-app
description: My production app
type: application                  # application | library
version: 1.4.2                     # version самого chart (SemVer)
appVersion: "2.6.0"                # version приложения внутри
dependencies:
- name: postgresql
  version: "12.x.x"
  repository: https://charts.bitnami.com/bitnami
  condition: postgresql.enabled

Различай: version меняется при изменениях chart (даже если код приложения тот же), appVersion, версия приложения.

Templates, Go templates над YAML

Файлы в templates/ рендерятся через Go-template engine. Доступны:

  • .Values, содержимое values.yaml (плюс overrides из CLI)
  • .Release, .Release.Name, .Release.Namespace, .Release.Revision
  • .Chart, содержимое Chart.yaml
  • .Capabilities, версия k8s, доступные API
  • .Files, статичные файлы chart'а (для configMap)
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
  labels: {{- include "my-app.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
      - name: app
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
        {{- with .Values.resources }}
        resources: {{- toYaml . | nindent 12 }}
        {{- end }}
        env:
        {{- range $k, $v := .Values.env }}
        - name: {{ $k }}
          value: {{ $v | quote }}
        {{- end }}

Стандартные правила:

  • {{- ... -}}, убрать whitespace до/после
  • nindent N, отступ N пробелов с newline'ом перед
  • toYaml, серилизовать map/list в YAML
  • default X .Values.foo, fallback если значение пустое
  • required "foo нужен" .Values.foo, ошибка если не задано

Helpers (_helpers.tpl)

Переиспользуемые шаблоны:

yaml
{{/* labels стандартные k8s */}}
{{- define "my-app.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
{{- end }}

Файлы начинающиеся с _ не рендерятся как k8s-объекты, только определяют helper'ы.

Lifecycle команд

bash
# Локальная отладка - что выйдет, не применяя
helm template my-release ./mychart -f values-prod.yaml
# Установка (создаёт release в namespace'е)
helm install my-release ./mychart -n production --create-namespace
# Обновление (с историей версий)
helm upgrade my-release ./mychart -f values-prod.yaml
# Откат на предыдущую ревизию
helm rollback my-release            # на N-1
helm rollback my-release 3          # на ревизию 3
# История релизов
helm history my-release
# Список всех релизов
helm list -A
# Удалить
helm uninstall my-release

Каждый release хранится как Secret типа helm.sh/release.v1 в namespace'е. Содержит сжатый JSON со всеми манифестами и values. Это база для rollback'а.

values.yaml, overrides

yaml
# values.yaml (default)
replicaCount: 1
image:
  repository: nginx
  tag: ""                          # пусто → fallback на Chart.AppVersion
  pullPolicy: IfNotPresent
resources:
  requests: { cpu: 100m, memory: 128Mi }
ingress:
  enabled: false
bash
# Переопределить из CLI или из второго values-файла
helm install my-release ./mychart \
  -f values.yaml -f values-prod.yaml \
  --set replicaCount=3 \
  --set image.tag=v2.6.0 \
  --set-string env.DEBUG=false       # принудительно строкой

Порядок: default values.yaml → -f files (по порядку) → --set. Поздние overridят ранние.

Helm vs kustomize, когда что

ПризнакHelmKustomize
Подходtemplating (Go-templates)overlays (патчи)
Версионирование релизада, в Secretнет (нативно)
Установкаhelm installkubectl apply -k ./
Кривая обучениясредняя (templating язык)пологая (только YAML + патчи)
Дистрибуцияchart-репо, OCI registrygit-репо
Conditional logicсильная (if/else/range)слабая (только overlays)
Hooks (pre/post-install)данет
Когда выбиратьдистрибуция чужих приложений, сложная логикасвои деплои с парой окружений

Часто комбинируют: helm для общедоступных chart'ов (postgres-operator, ingress-nginx), kustomize для своих app-deployments. Или Helmfile / ArgoCD как orchestrator поверх обоих.

Hooks

Special-аннотации в манифестах для запуска до/после lifecycle:

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration
  annotations:
    "helm.sh/hook": pre-upgrade,pre-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded

Помогает запустить миграции БД до апдейта приложения. Минус: hook-Jobs не учитываются в release-истории, при rollback не откатятся.

Dependencies

Chart может зависеть от других chart'ов:

yaml
# Chart.yaml
dependencies:
- name: postgresql
  version: "12.x.x"
  repository: https://charts.bitnami.com/bitnami
  condition: postgresql.enabled    # включается через values
  alias: db                        # обращаться через .Values.db
bash
helm dependency update             # скачивает в charts/
helm dependency build              # из Chart.lock

Subchart values переопределяются через корневой values.yaml:

yaml
postgresql:                          # имя subchart'а
  auth:
    database: myapp
    username: myapp

OCI registries, Helm 3.8+

Chart можно публиковать в OCI registry (Docker Hub, ECR, GHCR):

bash
helm package ./mychart                      

▸mychart-1.4.2.tgz

helm push mychart-1.4.2.tgz oci://ghcr.io/me/charts
helm install my-rel oci://ghcr.io/me/charts/mychart --version 1.4.2

Бонус: можно подписывать через [[image-signing-cosign|cosign]] как обычные образы.

Когда что-то пошло не так

  • Error: UPGRADE FAILED: another operation (install/upgrade/rollback) is in progress, упал предыдущий upgrade. helm history, потом helm rollback или удалить «pending» release-secret вручную.
  • unable to recognize "": no matches for kind "Foo", CRD не установлен. Положи в crds/ или установи отдельно --skip-crds.
  • values рендерятся не так как ожидаешь, helm template my-rel ./chart -f values.yaml локально, посмотри YAML до apply.
  • {{ .Values.foo.bar }} падает с nil pointer, нет defaults в values.yaml. Используй (.Values.foo).bar или default.
  • Hook job висит, нет hook-delete-policy, остаётся как pod после успеха. Добавить hook-succeeded.
  • release есть, объекты исчезли, кто-то прошёлся kubectl delete мимо Helm. helm upgrade --force пересоздаст. Воспитательная беседа с командой о mutability через Helm.
  • Secrets bloat, много upgrade'ов, много Secret'ов в namespace'е. --history-max 10 ограничивает количество.
  • Error: rendered manifests contain a resource that already exists, был создан вручную тот же объект. Удалить старый или helm install --take-ownership (Helm 3.14+).

§ команды

bash
helm install my-rel ./mychart -n prod --create-namespace -f values-prod.yaml

Установка release с values-файлом и созданием namespace при отсутствии

bash
helm template my-rel ./mychart -f values.yaml

Локально отрендерить шаблоны без apply - debug для template-ошибок

bash
helm upgrade --install my-rel ./mychart -f values.yaml --atomic --timeout 5m

Idempotent install/upgrade с откатом при неуспехе - паттерн для CI/CD

bash
helm rollback my-rel 3

Откат release на конкретную ревизию из истории

bash
helm history my-rel

История ревизий release с таймстампами и chart-version

bash
helm dependency update ./mychart

Скачать subchart'ы из dependencies в charts/ и обновить Chart.lock

bash
helm lint ./mychart

Проверка на типичные ошибки в шаблонах и Chart.yaml до релиза

§ см. также

  • kubernetes-pod-lifecycleKubernetes pod lifecycle - от Pending до TerminatedPod проходит фазы Pending → Running → Succeeded/Failed/Unknown. Init-containers выполняются последовательно до основных. Probes: startup → readiness/liveness. SIGTERM + grace period при удалении.
  • kubernetes-services-and-ingressKubernetes Service и Ingress - сетевая публикация подовService - стабильный VIP перед группой подов (label selector). Типы: ClusterIP (внутри), NodePort (порт на каждой ноде), LoadBalancer (внешний LB облака), ExternalName (CNAME). Ingress - L7 reverse-proxy (nginx/traefik) для HTTP-роутинга.
  • kubernetes-storageKubernetes storage - PV, PVC, StorageClass, CSIPV - физический volume. PVC - запрос pod'а. StorageClass + CSI - шаблон для dynamic provisioning. ReadWriteOnce типичный (block), ReadWriteMany нужен NFS/CephFS. Эфемерные (emptyDir, configMap) живут пока жив pod.
  • bash-scriptingbash-скрипты - основы и идиомыBash-скрипт - текстовый файл с shebang `#!/usr/bin/env bash` и `chmod +x`. Обязательный starting point - `set -euo pipefail` и `shellcheck` для проверки.
  • image-signing-cosignCosign и подпись container images (sigstore)cosign подписывает container images. Sigstore = ekosistema: rekor (transparency log), fulcio (CA для keyless OIDC). Подписи хранятся как OCI-объекты рядом с image. Verify - часть admission control в k8s через policy-controller или Kyverno.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки