← К программе курса

Модуль 13 / 19

Helm: пакеты и шаблоны

KUBERNETES

Содержание
01

1. Цели модуля

Вы научитесь читать и разрабатывать Helm chart, отделять шаблоны от конфигурации, проверять отрендеренные ресурсы до установки и безопасно выполнять upgrade, test и rollback.

  • chart, release и revision
  • Go templates и values
  • JSON Schema и lint
  • upgrade/install и rollback
  • Helm 3 → Helm 4
02

2. Теория: chart, release и revision

Helm — клиентский package manager для Kubernetes. Chart содержит metadata, values, templates и при необходимости dependencies или CRDs. Установка chart с конкретными values создаёт release; каждое изменение release образует revision, доступную через history и rollback.

Release хранит отрендеренное состояние в namespace, обычно в Secrets. Helm не заменяет Kubernetes controllers: он создаёт или изменяет API objects, а их reconciliation выполняет Kubernetes.

03

3. Теория: структура и шаблоны

Обязательный Chart.yaml задаёт имя и SemVer версии пакета; appVersion описывает версию приложения и не управляет upgrade. values.yaml содержит безопасные defaults, templates рендерят Kubernetes manifests, values.schema.json валидирует входные параметры.

Порядок приоритета: defaults chart → каждый файл -f слева направо → параметры --set/--set-string. Секреты не следует передавать через values в Git или командную строку: они попадут в release metadata, shell history или CI logs.

04

4. Теория: безопасный lifecycle

До изменения кластера выполняйте helm lint, helm template и server-side dry-run отрендеренного YAML. После установки проверяйте status, history, workload Conditions и helm test. Флаг --wait ограничивает успех готовностью ресурсов, но требует разумного timeout.

В Helm 4 прежний --atomic переименован в --rollback-on-failure, а --force — в --force-replace. Helm 4 обычно управляет существующими Helm 3 releases без миграции данных; старые releases сохраняют прежний apply method, а новые по умолчанию используют Server-Side Apply. Совместимость chart не отменяет тестирование plugins, CI flags и post-renderers.

05

5. Методические указания

  • Версионируйте chart независимо от appVersion
  • Фиксируйте chart version или OCI digest в автоматизации
  • Храните environment overrides отдельно от defaults
  • Используйте required, default и schema вместо неявных предположений
  • Не читайте результат только по exit code Helm: проверяйте ресурсы и Events
  • Не помещайте mutable данные в selector labels
  • Hooks должны быть идемпотентны и иметь delete policy или TTL
  • Перед переходом на Helm 4 прогоните charts и pipeline в staging
06

6. Лабораторная работа: каркас chart

Создайте каталог webapp/templates. Сохраните следующие блоки как webapp/Chart.yaml, webapp/values.yaml, values-lab.yaml и webapp/values.schema.json соответственно.

terminal
apiVersion: v2
name: webapp
description: Training web application
type: application
version: 0.1.0
appVersion: "1.29"
terminal
replicaCount: 2
image:
  repository: nginx
  tag: 1.29-alpine
  pullPolicy: IfNotPresent
service:
  port: 80
resources:
  requests:
    cpu: 25m
    memory: 32Mi
  limits:
    memory: 64Mi
podLabels: {}
terminal
replicaCount: 3
podLabels:
  environment: lab
resources:
  requests:
    cpu: 50m
    memory: 32Mi
  limits:
    memory: 96Mi
terminal
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["replicaCount", "image", "service", "resources"],
  "properties": {
    "replicaCount": {"type": "integer", "minimum": 1, "maximum": 10},
    "image": {
      "type": "object",
      "required": ["repository", "tag", "pullPolicy"],
      "properties": {
        "repository": {"type": "string", "minLength": 1},
        "tag": {"type": "string", "minLength": 1},
        "pullPolicy": {"enum": ["Always", "IfNotPresent", "Never"]}
      }
    },
    "service": {
      "type": "object",
      "required": ["port"],
      "properties": {"port": {"type": "integer", "minimum": 1, "maximum": 65535}}
    },
    "resources": {"type": "object"},
    "podLabels": {"type": "object", "additionalProperties": {"type": "string"}}
  }
}
07

7. Лабораторная работа: templates

Сохраните шаблоны как webapp/templates/deployment.yaml, service.yaml и test-connection.yaml. Все copyable-блоки ниже являются YAML/Go templates, а не командами терминала.

terminal
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | quote }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ .Chart.Name }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ .Chart.Name }}
        app.kubernetes.io/instance: {{ .Release.Name }}
        {{- with .Values.podLabels }}
        {{- toYaml . | nindent 8 }}
        {{- end }}
    spec:
      containers:
        - name: web
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - {name: http, containerPort: 80}
          readinessProbe:
            httpGet: {path: /, port: http}
          livenessProbe:
            httpGet: {path: /, port: http}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
terminal
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
spec:
  selector:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
  ports:
    - {name: http, port: {{ .Values.service.port }}, targetPort: http}
terminal
apiVersion: v1
kind: Pod
metadata:
  name: "{{ .Release.Name }}-test"
  annotations:
    "helm.sh/hook": test
    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
  restartPolicy: Never
  containers:
    - name: check
      image: busybox:1.37.0
      command: ["wget", "-qO-", "http://{{ .Release.Name }}:{{ .Values.service.port }}"]
08

8. Лабораторная работа: render, install и test

Сначала проверьте локальный chart и отрендеренный результат, затем создайте namespace и release. Server dry-run выполняется над точным rendered.yaml, который будет изучаться.

terminal
helm version
mkdir -p webapp/templates
helm lint ./webapp -f values-lab.yaml
helm template course-web ./webapp --namespace lab-helm -f values-lab.yaml --debug > rendered.yaml
kubectl create namespace lab-helm
kubectl apply --dry-run=server -f rendered.yaml
helm upgrade --install course-web ./webapp --namespace lab-helm -f values-lab.yaml --rollback-on-failure --wait --timeout 2m
helm list -n lab-helm
helm status course-web -n lab-helm
helm get values course-web -n lab-helm --all
helm get manifest course-web -n lab-helm
helm test course-web -n lab-helm --logs
kubectl get deploy,service,pod -n lab-helm -l app.kubernetes.io/instance=course-web

Критерий: lint успешен, schema принимает values, release deployed, три Pod Ready, effective values соответствуют values-lab.yaml, helm test завершается успешно.

09

9. Диагностика: неуспешный upgrade и rollback

Задайте несуществующий image tag. Upgrade ожидаемо завершится ошибкой после timeout, а --rollback-on-failure восстановит предыдущую рабочую revision. Соберите history, status, Pods и Warning Events до очистки.

terminal
helm upgrade course-web ./webapp --namespace lab-helm -f values-lab.yaml --set image.tag=does-not-exist --rollback-on-failure --wait --timeout 45s
helm history course-web -n lab-helm
helm status course-web -n lab-helm
kubectl get deployment,replicaset,pod -n lab-helm
kubectl events -n lab-helm --types=Warning
helm get values course-web -n lab-helm --all
helm uninstall course-web -n lab-helm
kubectl delete namespace lab-helm

Цепочка: Helm error → history/status → rendered manifest и effective values → Deployment Conditions → Pod state → Events → rollback. Не применяйте kubectl edit к управляемому ресурсу: следующий upgrade создаст drift или перезапишет изменение.

10

10. Контроль и шпаргалка

  • Чем chart отличается от release и revision?
  • Почему appVersion не заменяет chart version?
  • Какие values победят при нескольких -f и --set?
  • Почему helm template не заменяет server-side validation?
  • Что Helm хранит в release metadata?
  • Какие CLI flags изменились в Helm 4?
  • Почему hook может пережить uninstall?

Модуль освоен, если вы собираете chart с schema, доказываете итоговый YAML до apply, выполняете проверяемый upgrade и подтверждаете rollback по history и состоянию workload.

PDF для работы офлайн

Скачайте оформленную версию модуля для чтения без подключения к сети.

Скачать PDFPDF