Модуль 13 / 19
Helm: пакети й шаблони
Зміст
1. Цілі модуля
Ви навчитеся читати й розробляти Helm chart, відокремлювати шаблони від конфігурації, перевіряти відрендерені ресурси до встановлення та безпечно виконувати upgrade, test і rollback.
- chart, release і revision
- Go templates та values
- JSON Schema і lint
- upgrade/install і rollback
- Helm 3 → Helm 4
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.
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.
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.
5. Методичні вказівки
- Версіонуйте chart незалежно від appVersion
- Фіксуйте chart version або OCI digest в автоматизації
- Зберігайте environment overrides окремо від defaults
- Використовуйте required, default і schema замість неявних припущень
- Не оцінюйте результат лише за exit code Helm: перевіряйте ресурси й Events
- Не додавайте mutable дані до selector labels
- Hooks мають бути idempotent і мати delete policy або TTL
- Перед переходом на Helm 4 перевірте charts і pipeline у staging
6. Лабораторна робота: каркас chart
Створіть каталог webapp/templates. Збережіть наступні блоки як webapp/Chart.yaml, webapp/values.yaml, values-lab.yaml і webapp/values.schema.json відповідно.
apiVersion: v2
name: webapp
description: Training web application
type: application
version: 0.1.0
appVersion: "1.29"replicaCount: 2
image:
repository: nginx
tag: 1.29-alpine
pullPolicy: IfNotPresent
service:
port: 80
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 64Mi
podLabels: {}replicaCount: 3
podLabels:
environment: lab
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
memory: 96Mi{
"$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"}}
}
}7. Лабораторна робота: templates
Збережіть шаблони як webapp/templates/deployment.yaml, service.yaml і test-connection.yaml. Усі copyable-блоки нижче є YAML/Go templates, а не командами термінала.
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 }}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}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 }}"]8. Лабораторна робота: render, install і test
Спочатку перевірте локальний chart і відрендерований результат, потім створіть namespace і release. Server dry-run виконується над точним rendered.yaml, який буде досліджено.
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 завершується успішно.
9. Діагностика: невдалий upgrade і rollback
Задайте неіснуючий image tag. Upgrade очікувано завершиться помилкою після timeout, а --rollback-on-failure відновить попередню робочу revision. Зберіть history, status, Pods і Warning Events до очищення.
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. Контроль і шпаргалка
- Чим 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 для роботи офлайн
Завантажте оформлену версію модуля для читання без підключення до мережі.