Helm Charts: Управление пакетами в Kubernetes
Развёртывание Kubernetes с управлением пакетов Helm
Helm изменил подход к развертыванию приложений в Kubernetes, внедрив концепции управления пакетами, знакомые из традиционных операционных систем.
По мере роста популярности Kubernetes управление сложными приложениями с десятками YAML-файлов становится все более сложным. Helm Charts решают эту проблему, объединяя все ресурсы в версионируемые, настраиваемые пакеты.
Это красивое изображение было сгенерировано AI-моделью Flux 1 dev.
Понимание Helm: менеджер пакетов для Kubernetes
Helm для Kubernetes то же самое, что apt для Debian, yum для RedHat или Homebrew для macOS. Он упаковывает приложения Kubernetes в Charts – наборы файлов, описывающих связанные ресурсы Kubernetes. Один Chart может развернуть полный стек приложения: веб-серверы, базы данных, кэширующие слои, правила ингресса и компоненты мониторинга. Для новичков в Kubernetes Шпаргалка по Kubernetes предоставляет основные команды и концепции для начала работы.
Почему Helm важен в современной DevOps
Снижение сложности: Вместо управления 20+ YAML-файлами вы управляете одним Chart с настраиваемыми значениями.
Воспроизводимость: Развертывайте идентичные конфигурации в средах разработки, тестирования и продакшена с помощью специфичных для среды переопределений значений. Это особенно ценно при развертывании сложных микросервисных архитектур, где важна согласованность.
Контроль версий: Charts версионируются, что позволяет легко выполнять откаты и отслеживать обновления.
Сообщество и экосистема: Тысячи готовых Charts доступны через Artifact Hub (ранее Helm Hub) для популярных приложений, таких как PostgreSQL, Redis, NGINX, Prometheus и другие.
Мощь шаблонизации: Шаблоны Go позволяют динамически генерировать ресурсы на основе входных значений, уменьшая дублирование.
Архитектура Helm и ключевые концепции
Архитектура Helm 3
Helm 3 упростил архитектуру, удалив Tiller, проблемный серверный компонент из Helm 2:
- Helm Client: CLI-инструмент, который взаимодействует напрямую с API Kubernetes
- Chart: Формат пакета, содержащий шаблоны и метаданные
- Release: Экземпляр Chart, работающий в кластере Kubernetes
- Репозиторий: Место хранения Charts (HTTP-сервер или OCI-регистр)
Ключевые компоненты Helm Chart
my-app-chart/
├── Chart.yaml # Метаданные и версия Chart
├── values.yaml # Значения конфигурации по умолчанию
├── charts/ # Зависимые Charts
├── templates/ # Шаблоны ресурсов Kubernetes
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Вспомогательные шаблоны
│ └── NOTES.txt # Примечания после установки
├── .helmignore # Файлы для игнорирования при упаковке
├── README.md
└── LICENSE
Создание вашего первого Helm Chart
Инициализация нового Chart
helm create my-application
cd my-application
Это создает стартовый Chart с примерными шаблонами для развертывания, сервиса и ингресса.
Chart.yaml: Определение метаданных
apiVersion: v2
name: my-application
description: Готовый к продакшену Chart приложения
type: application
version: 1.0.0 # Версия Chart
appVersion: "2.4.1" # Версия приложения
maintainers:
- name: Ваша команда
email: team@company.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Values.yaml: Управление конфигурацией
Файл values.yaml определяет конфигурации по умолчанию, которые пользователи могут переопределить. Этот подход разделяет конфигурацию и шаблоны, облегчая управление разными средами (разработка, тестирование, продакшен) и настройку развертываний без изменения файлов шаблонов.
replicaCount: 3
image:
repository: myapp/backend
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80
Шаблоны: Динамические манифесты Kubernetes
Шаблоны используют синтаксис шаблонизации Go для динамического создания ресурсов Kubernetes. Эти шаблоны могут генерировать любые типы ресурсов Kubernetes, от простых Deployments до сложных StatefulSets для приложений с состоянием, требующих постоянного хранения. Для приложений, которым нужны стабильные идентификаторы и постоянные тома, вы захотите использовать StatefulSets вместо Deployments, как подробно описано в нашем руководстве по StatefulSets и постоянному хранению в Kubernetes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-application.fullname" . }}
labels:
{{- include "my-application.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-application.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-application.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 8080
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 10 }}
Вспомогательные шаблоны (_helpers.tpl)
Создавайте повторно используемые функции шаблонов для избежания дублирования:
{{/*
Развернуть имя Chart.
*/}}
{{- define "my-application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Создать стандартное полное имя приложения.
*/}}
{{- define "my-application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/*
Общие метки
*/}}
{{- define "my-application.labels" -}}
helm.sh/chart: {{ include "my-application.chart" . }}
{{ include "my-application.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Управление Helm Charts: установка и операции
Установка Chart
# Установка из репозитория
helm install my-release bitnami/postgresql
# Установка из локальной директории
helm install my-app ./my-application
# Установка с пользовательскими значениями
helm install my-app ./my-application -f values-production.yaml
# Установка с переопределением значений в строке
helm install my-app ./my-application \
--set replicaCount=5 \
--set image.tag=2.0.0
Обновление релизов
# Обновление с новыми значениями
helm upgrade my-app ./my-application -f values-production.yaml
# Обновление с атомарным откатом при ошибке
helm upgrade my-app ./my-application --atomic --timeout 5m
# Принудительное обновление ресурсов
helm upgrade my-app ./my-application --force
Откат и история
# Просмотр истории релиза
helm history my-app
# Откат к предыдущей версии
helm rollback my-app
# Откат к конкретной ревизии
helm rollback my-app 3
Тестирование и отладка
# Сухой запуск для просмотра сгенерированных манифестов
helm install my-app ./my-application --dry-run --debug
# Рендеринг шаблонов без установки
helm template my-app ./my-application
# Проверка Chart на ошибки
helm lint ./my-application
# Тестирование релиза с тестовыми хуками
helm test my-app
Дополнительные возможности Helm
Зависимости Chart
Helm Charts могут зависеть от других Charts, позволяя составлять сложные приложения из повторно используемых компонентов. Это особенно полезно при развертывании микросервисов, которым нужны базы данных, очереди сообщений или другие вспомогательные сервисы. Определите зависимости в Chart.yaml:
dependencies:
- name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Обновите зависимости:
helm dependency update ./my-application
Helm Hooks для управления жизненным циклом
Хуки выполняются в определенные моменты жизненного цикла релиза:
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-application.fullname" . }}-db-migration
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
spec:
containers:
- name: db-migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["python", "manage.py", "migrate"]
restartPolicy: Never
Типы хуков включают:
pre-install: Перед установкой ресурсовpost-install: После установки всех ресурсовpre-upgrade: Перед обновлениемpost-upgrade: После обновленияpre-delete: Перед удалениемpost-delete: После удаленияpre-rollback: Перед откатомpost-rollback: После отката
Условная логика и управление потоком
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "my-application.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "my-application.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
Поддержка OCI Registry: Современное распределение Chart
С версии Helm 3.8 поддержка OCI (Open Container Initiative) реестров стала стабильной, что позволяет хранить Chart вместе с контейнерами.
Публикация в OCI Registry
# Вход в реестр
helm registry login registry.example.com
# Упаковка чарта
helm package ./my-application
# Отправка в OCI реестр
helm push my-application-1.0.0.tgz oci://registry.example.com/charts
# Установка из OCI реестра
helm install my-app oci://registry.example.com/charts/my-application --version 1.0.0
Преимущества OCI реестров
- Единое хранилище: Chart и образы в одном месте
- Стандартные инструменты: Использование существующей инфраструктуры реестров
- Лучшая безопасность: Использование аутентификации и сканирования реестра
- Проще управление: Не требуется отдельный сервер для Chart репозитория
Лучшие практики для производственных Helm Chart
1. Структура и документация значений
Документируйте все значения с комментариями:
# -- Количество реплик для приложения
replicaCount: 3
# -- Настройки образа
image:
# -- Репозиторий образа
repository: myapp/backend
# -- Политика загрузки образа
pullPolicy: IfNotPresent
# -- Тег образа (по умолчанию версия чарта)
tag: ""
2. Управление ресурсами
Всегда устанавливайте запросы и лимиты ресурсов:
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
3. Контексты безопасности
Определяйте контексты безопасности для контейнеров:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
4. Проверки состояния
Включайте проверки работоспособности и готовности:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5. Управление ConfigMap и Secret
Правильное управление секретами критически важно для производственных развертываний. Используйте внешние менеджеры секретов (Sealed Secrets, External Secrets Operator или Vault) вместо хранения секретов в файлах значений. Это обеспечивает безопасное обращение с конфиденциальными данными, такими как пароли баз данных, API ключи и сертификаты:
envFrom:
- secretRef:
name: {{ include "my-application.fullname" . }}-secrets
- configMapRef:
name: {{ include "my-application.fullname" . }}-config
6. Схема валидации
Создавайте values.schema.json для валидации входных данных:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": ["repository"]
}
},
"required": ["image"]
}
7. NOTES.txt для руководства пользователя
Предоставляйте инструкции после установки:
1. Получите URL приложения, выполнив:
{{- if .Values.ingress.enabled }}
https://{{ (index .Values.ingress.hosts 0).host }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "my-application.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- end }}
2. Мониторьте развертывание:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "my-application.name" . }}"
Тестирование Helm Chart и интеграция с CI/CD
Тестирование Chart с chart-testing (ct)
# Установка chart-testing
brew install chart-testing
# Проверка синтаксиса чартов
ct lint --config ct.yaml
# Установка и тестирование чартов
ct install --config ct.yaml
Пример GitHub Actions
name: Helm Chart CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Настройка Helm
uses: azure/setup-helm@v3
with:
version: 3.12.0
- name: Настройка chart-testing
uses: helm/chart-testing-action@v2
- name: Проверка синтаксиса чартов
run: ct lint --config ct.yaml
- name: Создание kind кластера
uses: helm/kind-action@v1
- name: Установка чартов
run: ct install --config ct.yaml
GitOps с Helm: ArgoCD и Flux
Инструменты GitOps, такие как ArgoCD и Flux, интегрируются с Helm Chart, обеспечивая декларативные, автоматизированные развертывания. Эти инструменты следят за изменениями в вашем репозитории Git и автоматически синхронизируют релизы Helm, упрощая непрерывное развертывание. Для сложных микросервисных архитектур рассмотрите использование распределенных транзакционных паттернов, таких как Saga pattern, чтобы управлять согласованностью между сервисами, развертываемыми через Helm.
Пример ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-application
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/my-app-chart
targetRevision: main
path: charts/my-application
helm:
valueFiles:
- values-production.yaml
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
Пример Flux HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: my-application
namespace: flux-system
spec:
interval: 5m
chart:
spec:
chart: my-application
version: '1.x.x'
sourceRef:
kind: HelmRepository
name: my-charts
values:
replicaCount: 5
image:
tag: "2.0.0"
Устранение распространенных проблем Helm
Проблема: Неудачное обновление зависло в состоянии ожидания
# Проверка статуса релиза
helm list --all-namespaces
# Получение деталей релиза
helm status my-app -n namespace
# Принудительное удаление при необходимости (используйте осторожно)
kubectl delete secret -n namespace -l owner=helm,name=my-app
Проблема: Ошибки рендеринга шаблонов
# Отладка рендеринга шаблонов
helm template my-app ./my-application --debug
# Валидация против Kubernetes
helm template my-app ./my-application | kubectl apply --dry-run=client -f -
Проблема: Значения не применены
# Проверка объединенных значений
helm get values my-app
# Показать все вычисленные значения
helm get values my-app --all
Экосистема Helm и инструменты
Экосистема Helm включает множество инструментов, расширяющих его возможности и интегрирующихся с другими технологиями Kubernetes. При развертывании приложений, требующих продвинутых сетевых функций, таких как коммуникация между сервисами, управление трафиком и политики безопасности, рассмотрите интеграцию с Service Mesh с Istio и Linkerd, которые могут быть развернуты и управляемы через Helm Chart.
Основные инструменты
- Helmfile: Декларативное описание для развертывания Helm Chart
- Helm Diff: Предварительный просмотр изменений перед обновлением
- Helm Secrets: Управление секретами с SOPS
- Nova: Поиск устаревших Helm Chart
- Pluto: Обнаружение устаревших API Kubernetes
Пример Helmfile
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: postgresql
namespace: database
chart: bitnami/postgresql
version: 12.x.x
values:
- postgresql:
auth:
database: myapp
username: appuser
- name: my-app
namespace: production
chart: ./charts/my-application
values:
- values-production.yaml
needs:
- database/postgresql
Будущее Helm
Экосистема Helm продолжает развиваться:
- OCI-ориентированный: Полный переход на OCI реестры как стандарт
- Улучшенная безопасность: Лучшее управление секретами и возможности подписи
- Производительность: Быстрое рендеринг и установка для больших Chart
- Поддержка WASM: WebAssembly для плагинов и расширений Chart
- Лучшая валидация: Улучшенная схема валидации и enforcement политик
Заключение
Helm стал де-факто стандартом для управления пакетами Kubernetes, и его освоение необходимо для современных практик DevOps. Понимание структуры Chart, шаблонизации, управления значениями и лучших практик позволяет создавать поддерживаемые, безопасные и масштабируемые развертывания Kubernetes.
Начните с простых Chart, постепенно внедряйте продвинутые функции, такие как хуки и зависимости, и интегрируйтесь с инструментами GitOps для производственных инфраструктур. Сообщество Helm предоставляет тысячи готовых Chart, но настоящая мощь заключается в создании пользовательских Chart, адаптированных под нужды вашей организации. Будь то развертывание безсостоятельных приложений или состоятельных рабочих нагрузок, требующих постоянного хранилища, Helm упрощает сложность управления ресурсами Kubernetes. Для команд, настраивающих новые кластеры Kubernetes, рассмотрите установку Kubernetes с Kubespray или изучение распространений Kubernetes вроде k3s или MicroK8s для сред разработки. Если вы оцениваете, какое распределение подходит для ваших нужд в домашней лаборатории или небольшого кластера, посмотрите наше подробное сравнение распределений Kubernetes для детального анализа.
Полезные ссылки
- Официальная документация Helm
- Artifact Hub - Поиск Helm Charts
- Репозиторий Helm на GitHub
- Руководство по лучшим практикам Helm
- Инструмент для тестирования Chart
- Helmfile
- ArgoCD
- Flux CD
- Репозиторий Bitnami Charts
- Шпаргалка по Kubernetes
- Установка Kubernetes с Kubespray
- Сравнение дистрибутивов Kubernetes для хоумлаба из 3 узлов
- Дистрибутивы Kubernetes - краткий обзор kubeadm, k3s, MicroK8s, Minikube, Talos Linux и RKE2
- Service Mesh с Istio и Linkerd
- StatefulSets и постоянное хранилище в Kubernetes
- Паттерн Saga в распределенных транзакциях