Learning Platform
Глоссарий Troubleshooting
Урок 18.05 · 20 мин
Средний
Helm vs KustomizeGitOpsArgoCDFluxкомбинированиеselection criteria

Helm vs Kustomize: выбор и сравнение

Helm и Kustomize — два самых популярных подхода к управлению Kubernetes manifests. Оба официально поддерживаются CNCF и встроены в основные GitOps-tools (ArgoCD, Flux). Часто их противопоставляют как “или то, или это” — но в реальности зрелые команды используют оба одновременно. Этот урок — про сравнение по ключевым аспектам, реальные критерии выбора и паттерн комбинирования.


Паттерны компоновки DE-стека в Docker Compose

Side-by-side: главное

АспектHelmKustomize
ПодходTemplating (Go templates)Patches на base manifests
Файлы до рендераНе валидный YAMLВсегда валидный YAML
Learning curveSteeper (Sprig, helpers, _helpers.tpl)Easier (просто YAML + kustomization.yaml)
ReusabilityCharts via repositoriesBases можно переиспользовать (git/path)
Lifecycle managementReleases (история, rollback, статусы)Stateless (нет concept of release)
Community chartsОгромная экосистема (Artifact Hub, Bitnami)Меньше, но растёт
Conditional logicPowerful (if/range/with + sprig)Ограниченные (через components, alpha)
YAML correctnessRuntime (errors после рендера)Compile-time (всегда valid YAML)
State storageRelease Secrets в кластереНет (only kustomization.yaml в git)
Inclusion в kubectlОтдельный бинарьВстроен (kubectl apply -k)
ConfigMap rolloutЧерез checksum/config annotation hackАвтоматически через hash suffix
CRDscrds/ директория (не upgrade)resources как обычно
Update strategyupgrade с reuse/reset-valuesgit revert + apply

Где побеждает Helm

1. Сложные third-party приложения

Установить Prometheus stack с alertmanager, exporters, grafana — это десятки манифестов с conditionals (включить alertmanager? scrape какие endpoints? какие dashboards?). Helm chart инкапсулирует это в helm install prometheus prometheus-community/kube-prometheus-stack -f values.yaml — пользователь меняет 20 значений в values.yaml, не понимая internal details chart-а.

Kustomize этого не может — нет conditional logic для “если включён alertmanager — добавь ServiceMonitor для него”. Пришлось бы делать множество overlays для каждой комбинации features.

2. Версионирование и распространение

helm repo add bitnami ... → команда сразу получает доступ к 100+ chart-ам. SemVer-версионирование, репозитории как стандартный механизм distribution. Можно зафиксировать --version 15.4.4 и быть уверенным, что pull в CI даст тот же результат.

Kustomize bases — это директории в git repo. Тоже работает, но менее formalized — пиннинг через ?ref=v1.0.0, нет central registry.

3. Lifecycle management

helm history web        # вижу все ревизии
helm rollback web 2     # откат
helm uninstall web      # cleanup всех resources

В Kustomize этого нет. Откат — git revert + apply, cleanup — kubectl delete -k <dir> (но не удалит resources, которые когда-то были, а потом убраны из kustomization).

4. helm test для smoke-тестов

Hook type test — Job, который запускается через helm test <release>. Стандартный механизм для smoke-проверки release. Kustomize такого не имеет.


Где побеждает Kustomize

1. In-house apps с multiple environments

Команда деплоит свой собственный микросервис в dev/staging/prod. Структура манифестов известна. 80% — одинаково между env, 20% — env-specific (replicas, resources, namespace). Kustomize overlays идеально для этого — никаких placeholders, копируешь только diff.

Helm для этого overkill: создавать Chart, values.yaml, разбираться с Go templates — для простых in-house apps это лишний слой.

2. ConfigMap immutability + auto-rollout

configMapGenerator создаёт ConfigMap с hash suffix. Изменение data → новое имя → автоматический rolling update Deployment-а. В Helm нужен manual hack:

spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

Этот pattern — must-have, но требует disciplined adoption в каждом chart-е. Kustomize решает это by default.

3. YAML correctness и линтеры

Файлы Kustomize — валидный YAML. Можно открыть в IDE с подсветкой, прогнать через kubeval/kubeconform для validation против K8s schemas, использовать yq для query.

Helm templates — это string templating над YAML-подобным текстом. До рендеринга — не YAML. Type errors типа replicas: "{{ .Values.replicas }}" (string вместо int) — runtime errors на apply. Helm 3 добавил values.schema.json — можно валидировать values, но не сами templates.

4. GitOps-friendly

GitOps tools любят, когда git = source of truth. Kustomize fits perfectly: всё в git, никакого client-side state. ArgoCD/Flux рендерят kustomize build → applying → done. Diff между git и cluster показывается dashboard-ом.

С Helm GitOps работает, но есть две модели:

  • “Helm-as-source”: ArgoCD сам запускает helm template/install — нужно managed Helm credentials, history живёт в кластере как Secrets.
  • “Rendered Helm”: git хранит результат helm template, ArgoCD просто applying — теряем helm rollback, но получаем простоту.

Combine оба: Kustomize over Helm

Реальный production-pattern: использовать Helm для third-party chart, Kustomize для env-specific overlay поверх:

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

helmCharts:
  - name: nginx
    repo: https://charts.bitnami.com/bitnami
    version: 15.4.4
    releaseName: web
    namespace: production
    valuesFile: values.yaml

patches:
  - target:
      kind: Deployment
      name: web-nginx
    patch: |
      - op: add
        path: /spec/template/spec/nodeSelector
        value:
          dedicated: production-pool

Здесь:

  • Kustomize рендерит Helm chart через helm template.
  • Накладывает patches поверх rendered output.
  • Финальный YAML применяется как kubectl apply -k.

Это даёт преимущества обоих:

  • Стандартизация на third-party chart (используем готовый bitnami/nginx).
  • Кастомизация под наш env через patches (которых нет в values.yaml chart-а — например, nodeSelector с нашими label-ами).
Combine: Kustomize over Helm в GitOps
git repoSource of truth. Содержит kustomization.yaml с helmCharts блоком + patches + env-specific configs. Никакого rendered output — только декларация.
ArgoCD / FluxВидит изменение в git, запускает kustomize build, который под капотом: 1. helm template на указанный chart. 2. Применяет Kustomize transformations и patches к rendered output. 3. Получает финальный YAML.
helm templateВнутри kustomize build вызывается helm template bitnami/nginx --version 15.4.4 -f values.yaml. Получаем rendered Helm manifests как plain YAML. Никаких Release Secrets — это pure render.
patchesKustomize применяет patches к Helm rendered output: добавляет nodeSelector, меняет resources, прикручивает env-specific labels. Это то, что недостижимо через chart values (если chart-разработчик не предусмотрел поле).
final YAMLПолностью отрендеренные K8s manifests с подставленными values и применёнными patches. Валидный YAML, готовый к kubectl apply -f -.
kube-apiserverArgoCD/Flux применяет финальные manifests. В кластере появляются обычные K8s resources с labels от Helm (managed-by=Helm) + labels от Kustomize (commonLabels). Тут уже неважно, кто их рендерил.

GitOps: и Helm, и Kustomize нативно

ArgoCD и Flux — два самых популярных GitOps-tools. Оба поддерживают и Helm, и Kustomize:

ArgoCD

# Application с Helm
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web
spec:
  source:
    repoURL: https://charts.bitnami.com/bitnami
    chart: nginx
    targetRevision: 15.4.4
    helm:
      values: |
        replicaCount: 3
  destination:
    server: https://kubernetes.default.svc
    namespace: web
# Application с Kustomize
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: api
spec:
  source:
    repoURL: https://github.com/myorg/k8s-configs
    path: overlays/prod
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: api

ArgoCD под капотом запускает helm template или kustomize build, делает server-side apply через apiserver, отслеживает drift.

Flux

# HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: web
spec:
  chart:
    spec:
      chart: nginx
      sourceRef:
        kind: HelmRepository
        name: bitnami
      version: "15.4.4"
  values:
    replicaCount: 3
# Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: api
spec:
  path: overlays/prod
  sourceRef:
    kind: GitRepository
    name: k8s-configs

Flux — более модульный (отдельные controllers для каждой задачи), ArgoCD — более UI-driven.


Когда что выбирать: practical guide

Helm:

  • Устанавливаешь популярное third-party (Prometheus, Grafana, nginx-ingress, cert-manager, sealed-secrets).
  • Нужны conditionals в манифестах (опциональный alertmanager, опциональный ingress).
  • Нужен built-in lifecycle (rollback, history) на уровне инструмента.
  • Команда уже знакома с Helm, есть legacy charts.

Kustomize:

  • Деплоишь in-house apps с минимальными conditionals.
  • Несколько environments с похожей структурой (dev/staging/prod).
  • Хочешь GitOps с simple model (git = state, без client-side history).
  • YAML correctness важна (auto-validation, IDE support).
  • Не хочешь учить Go templates команде.

Оба:

  • В GitOps setup с третьих сторон вендорят charts + накладывают env patches.
  • Большая организация, разные команды могут выбирать что им удобнее.

YAML correctness — глубже

Главный killer-аргумент Kustomize: Helm templates до рендера — это string templating над YAML-подобным текстом, не YAML.

Типичные runtime errors в Helm:

# values.yaml
replicas: 3  # int

# template
replicas: "{{ .Values.replicas }}"  # WRONG — quotes делают string!

Apiserver примет (StrictType disabled by default в JSON Schema validation) но Deployment broken. Или:

# template
replicas: {{ .Values.replicas | quote }}  # WRONG — quote делает "3" string

Validation на K8s side detect-ит позже: “spec.replicas in body must be of type integer”. Это ошибка на runtime.

В Kustomize таких ошибок просто не существует — YAML всегда правильный, patches применяются на уже-typed values.

WARNING

В Helm есть values.schema.json — JSON Schema validation для values. Но это валидирует input (значения, которые пользователь подаёт), не output (rendered manifests). Если в template ошибка с типами — schema не поможет. Используй helm template | kubeconform для post-render validation.


CKAD-перспектива

На экзамене CKAD ожидают, что ты знаешь оба:

  • helm install <name> <chart> — установка из chart-а (часто с уже-настроенным repo на экзамене).
  • helm upgrade --install <name> <chart> -f values.yaml — idempotent.
  • helm list -n <ns> — посмотреть установленные.
  • helm uninstall <name> — удалить.
  • kubectl apply -k <dir> — apply Kustomize overlay.
  • Понимание structure: base/ + overlays/<env>/ для Kustomize, templates/ + values.yaml для Helm.

Создавать chart с нуля или сложные Kustomize structures — за пределами CKAD scope. Ожидается navigate существующих и базовая модификация values.


Killer-моменты

  • Helm templates — НЕ валидный YAML до рендера. Type errors типа replicas: "3" (string vs int) — runtime errors. Kustomize всегда работает с valid YAML.
  • ConfigMap rollout: Kustomize — автоматически через hash suffix. Helm — manual через checksum/config annotation. Это elegantly решено в Kustomize.
  • State management: Helm — Release Secrets в кластере, есть helm rollback. Kustomize — stateless, rollback через git revert.
  • GitOps tools (ArgoCD, Flux) поддерживают оба нативно. Можно даже комбинировать: Kustomize over Helm для env-specific tweaks.
  • CKAD scope: пользоваться обоими. Создание чартов с нуля — за пределами.
  • Reuse: Helm — через repository (центр). Kustomize — через resources: ../../base (path) или git-ссылку.

Проверка знанийKnowledge check
Команда деплоит свой микросервис в dev/staging/prod. 90% манифестов одинаково, отличаются namespace, replicas, image tag. Helm или Kustomize?
ОтветAnswer
Kustomize лучше для этого сценария. Причины: (1) Нет conditional logic — просто overrides на base manifests. (2) YAML correctness и IDE support из коробки. (3) Stateless — GitOps-friendly. (4) configMapGenerator решает auto-rollout без manual checksums. (5) Низкий learning curve — команда не должна изучать Go templates. Структура: base/ с deployment.yaml + service.yaml, overlays/dev/staging/prod с минимальными overrides (namespace, replicas, images). Helm для in-house apps overkill — лишний абстракционный слой без сильных преимуществ.
Проверка знанийKnowledge check
Что делает Kustomize over Helm паттерн, и для какого случая он полезен?
ОтветAnswer
Kustomize over Helm — это использование Kustomize как обёртки над Helm chart. Kustomization.yaml содержит helmCharts блок, который вызывает helm template для chart-а, затем Kustomize применяет patches к rendered output. Use case: используешь готовый third-party chart (bitnami/nginx), но нужны env-specific tweaks, которых нет в chart values (например, специфический nodeSelector с corporate labels). Через Helm values это недостижимо (chart-разработчик не предусмотрел поле), но Kustomize patches могут изменить любое поле в rendered output. Получаешь best of both: стандартизированный chart + кастомизация под env.
Проверка знанийKnowledge check
Helm template с конструкцией replicas в кавычках типа '...Values.replicaCount...' (с quotes вокруг placeholder). values.yaml имеет replicaCount: 3. Что произойдёт после helm install?
ОтветAnswer
После рендера manifest будет содержать replicas: '3' — string вместо integer. apiserver выдаст error при валидации: 'spec.replicas in body must be of type integer: string'. Helm install fails. Это типичный type error в Helm templates — quotes 'on safety' делают всё string. Fix: убрать quotes (просто replicas с placeholder без кавычек) — Go template подставит int как int. Или: использовать pipe int для принудительного cast. В Kustomize такие ошибки невозможны: replicas: 3 в base, replicas в overlay — всегда typed integer.
Проверка знанийKnowledge check
Зачем в Helm нужна аннотация checksum/config с SHA256-hash от ConfigMap content в pod template, и почему в Kustomize это не нужно?
ОтветAnswer
Helm: при изменении ConfigMap data сам ConfigMap обновится (это update by name), но Deployment не знает, что что-то изменилось — он ссылается на тот же ConfigMap name. Pods продолжают использовать старые data (mount-нутый snapshot или env vars из cache). Checksum annotation добавляет SHA256 от ConfigMap content в pod template — при изменении content hash меняется → pod template digest меняется → Deployment делает rolling update. Kustomize: configMapGenerator создаёт ConfigMap с hash suffix в имени (app-config-abc123). При изменении data — новое имя app-config-def456. Kustomize обновляет все references на новое имя — Deployment видит новый name — pod template changes — rolling update. Hash suffix замещает manual checksum annotation.
Проверка знанийKnowledge check
На CKAD дано: установить Helm chart bitnami/redis в namespace cache с replicaCount=3 и image.tag=7.2. Команда?
ОтветAnswer
helm install <name> bitnami/redis --namespace cache --create-namespace --set replicaCount=3 --set image.tag=7.2 (или --set-string image.tag=7.2 если важно строкой). Verify: kubectl get all -n cache, helm list -n cache, helm status <name> -n cache. Возможные подводные камни: (1) Нужно ли --create-namespace — зависит от того, существует ли namespace. (2) --version <chart-version> для конкретной chart-version, если требуется. (3) Если есть values.yaml файл — лучше -f values.yaml вместо набора --set. (4) Bitnami redis может требовать password — посмотри NOTES после install для пост-инструкций (helm get notes <name>).

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. Команде нужно деплоить in-house микросервис в dev/staging/prod. Манифесты на 90% одинаковые, отличаются namespace, replicas, image tag, resources. Что лучше?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5