Сколько Helm-релизов в кластере, если приложения раскатывает Argo CD? Ноль. helm ls пуст, helm history нечего показывать. Argo CD использует Helm как шаблонизатор: запускает helm template, получает манифесты и применяет их своим движком — helm install не вызывается никогда. Это написано в FAQ проекта прямым текстом и видно в коде (util/helm/helm.go).
Отсюда первое следствие для спора «Helm против Kustomize»: доводы про историю релизов, helm rollback и управление жизненным циклом через хуки в GitOps-контуре не работают. Историю и откат даёт Argo CD — argocd app history, argocd app rollback.
Сравнивать остаётся три вещи: язык описания конфигурации, происхождение артефакта и способность достать артефакт из закрытого реестра. Первое — дело вкуса. Два других в 2026 году превратились в жёсткие технические ограничения.
Что изменилось за год
Ветка Helm 3 закрывается. Релиз 3.22.0 (сентябрь 2026) — последний минор, и выпущен он ограниченно: только обновление Kubernetes client-библиотек под новые версии кластеров. Security-патчи идут до 10 февраля 2027. Изначально в HIP-0012 стоял ноябрь 2026, мейнтейнеры добавили три месяца. После февраля 3.x не получает ничего. Актуальный Helm — 4.3.0 из того же сентябрьского окна.
Для GitOps важнее другое. Начиная с Argo CD 3.5 чарты рендерит только Helm 4. Поле spec.source.helm.version игнорируется — оставлять его можно, эффекта нет. В 3.5.3 вшит Helm 4.2.1; ветки 3.3 и 3.4, пока поддерживаемые, работают на Helm 3.19.4. Версию шаблонизатора в пайплайне определяет версия Argo CD, а не то, что установлено у инженера локально.
Отсюда практическое следствие для CI. Если пайплайн гоняет helm template или helm diff бинарником Helm 3, а кластерный Argo CD уже на 3.5, вы сравниваете вывод двух разных рендереров и надеетесь, что они совпадут. Версию Helm в CI стоит выровнять по версии Argo CD, а не по тому, что лежит в образе раннера. Топология тут решает: в hub-and-spoke рендерит один Argo CD на хабе, значит версия Helm в контуре одна; при Argo CD в каждом кластере кластеры расходятся по минорам Argo CD, а вместе с ними — по версиям шаблонизатора.
Kustomize живёт тише: 5.8.2 вышел 30 сентября 2026, предыдущие миноры — 5.8.1 в феврале и 5.8.0 в ноябре 2025. Три релиза за одиннадцать месяцев. Встроенная в kubectl версия отстаёт от отдельного бинарника: kubectl 1.36 и 1.37 несут 5.8.1, Argo CD 3.5.3 — тоже 5.8.1.
Апгрейд, который ломает внутренний реестр
Переход Argo CD на Helm 4 принёс неочевидное breaking change — OCI-реестры без TLS. Helm 4 требует явного --plain-http там, где предшественник обходился без него. В Argo CD это лечится флагом в repository-Secret:
stringData:
insecureOCIForceHttp: "true"
Тонкость сидит в зависимостях. Если в Chart.yaml указан repository: oci://… на реестр без TLS, этот реестр нужно отдельно зарегистрировать в Argo CD как репозиторий с тем же флагом. Под Helm 3 такие зависимости тянулись прозрачно, без регистрации. Есть и готовая ловушка: при одновременно выставленных --insecure-skip-server-verification и --insecure-oci-force-http Helm 4 молча теряет --plain-http.
Где они уживаются и где связка ломается
Смешивать движки приходится почти всегда: чужой чарт плюс свои значения. Рабочих способов два.
Первый — multi-source Application. Чарт берётся из Helm- или OCI-реестра, values лежат в Git и подключаются через ref и $values. Учётные данные остаются в repository-Secret'ах Argo CD, где им и место.
spec:
sources:
- repoURL: https://prometheus-community.github.io/helm-charts
chart: prometheus
targetRevision: 15.7.1
helm:
valueFiles:
- $values/charts/prometheus/values.yaml
- repoURL: https://git.example.com/org/value-files.git
targetRevision: dev
ref: values
Второй способ — Kustomize с полем helmCharts: чарт инфлейтится внутри Kustomize, сверху ложатся патчи. Им ставят Argo Rollouts и половину CRD-операторов. Потолок у этого способа есть, и он задокументирован.
Флаг --enable-helm, без которого helmCharts не работает, включается в Argo CD только глобально — через kustomize.buildOptions: --enable-helm в argocd-cm, сразу на все Kustomize-приложения. Пер-апповой опции для него нет, альтернатива — писать CMP-плагин.
Аутентификации нет вообще. Генератор собирает команду helm pull без единого флага учётных данных: ни --username, ни --password, ни --registry-config, ни --plain-http. Repository-Secret'ы Argo CD до этого пути не доходят, они действуют только для native Helm source. Схему oci:// генератор поддерживает — для неё в pullCommand() отдельная ветка, — но приватный реестр или реестр без TLS декларативно настроить нечем. На внутреннем Harbor без TLS связка «Kustomize + helmCharts + Argo CD 3.5» не соберётся вообще.
Мейнтейнеры Kustomize этого не скрывают: генератор задуман ограниченным подмножеством Helm, в него принимают багфиксы, критические security-правки и флаги-аналоги helm template. Поддержку приватных реестров и аутентификации добавлять не планируют — следующая итерация должна стать KRM-функцией. Читать этот документ стоит как заявление о намерениях: в нём же обещано не добавлять OCI, а схема oci:// в коде генератора уже есть.
Хуки и детерминизм
Argo CD распознаёт helm.sh/hook и раскладывает хуки по своим фазам, но соответствие неполное, и различия меняют поведение:
pre-installиpre-upgradeсхлопываются вPreSync. Argo CD не различает первую установку и обновление, для него всё — синк. Джоба миграции БД с"helm.sh/hook": pre-upgrade,pre-installпойдёт на каждом синке. Если она не идемпотентна, узнаете об этом по данным.pre-rollback,post-rollback,test-success,test-failureиhook-delete-timeoutигнорируются.- Один собственный
argocd.argoproj.io/hookв приложении выключает все Helm-хуки.
Второй сюжет — детерминизм рендера. helm template перезапускается на каждом сравнении с кластером. Чарт, который генерирует пароль через randAlphaNum, даёт вечный OutOfSync: значение меняется на каждом рендере, diff не сходится никогда. Лечится фиксацией значения в values. У чистого Kustomize, без helmCharts, этого класса проблем нет по построению: вывод kustomize build детерминирован. Сильная сторона здесь именно детерминизм; «отсутствие шаблонов» само по себе ничего не гарантирует — заверните чарт в helmCharts, и отрендерится тот же шаблон с тем же randAlphaNum и тем же вечным OutOfSync.
За детерминизм Kustomize берёт свою цену: патч живёт отдельно от объекта, и чтобы увидеть итоговый манифест, оверлей надо собрать. Плюс накопленный техдолг в старых деревьях. С версии 5.0.0 объявлены устаревшими patchesStrategicMerge, patchesJson6902 и vars, а bases — ещё с 2.1.0; замена — patches, replacements и resources, конвертирует kustomize edit fix. Из kustomize.config.k8s.io/v1beta1 их не удалят, но в будущий v1 API не возьмут, так что чинить придётся. Автоконвертация vars → replacements способна перезаписать много файлов и изменить вывод сборки — делайте её в чистом git-дереве.
Что бы ни рендерило манифесты, проверять надо результат рендера, а не исходник. Политики на выходе helm template и kustomize build ловят то, что до кластера доезжать не должно, независимо от выбора движка.
Когда что выбирать
| Ситуация | Выбор | Почему |
|---|---|---|
| Чужой чарт из публичного или приватного реестра | Native Helm source + values через multi-source | Учётки, TLS и OCI-флаги живут в repository-Secret'ах |
| Свои манифесты, много окружений | Kustomize: базы и оверлеи | Детерминированный вывод, патчи вместо ветвления шаблонов |
| Чарт надо поправить сверху: аннотации, лимиты, sidecar | Kustomize + helmCharts | Патч поверх рендера, но реестр обязан быть публичным и по TLS |
| Внутренний реестр без TLS или с авторизацией | Только native Helm source | Генератор helmCharts не передаёт ни учётки, ни --plain-http |
| Чарт уходит внешнему потребителю | Helm | Версионирование чарта, зависимости, OCI-дистрибуция |
Что из этого следует
Выбор диктует происхождение артефакта. Там, где чарт надо достать из реестра, требующего учётные данные или работающего без TLS, рабочий путь остаётся один — native Helm source в Argo CD: только у него есть канал к repository-Secret'ам. Там, где манифесты свои и лежат в том же Git, Kustomize даёт детерминированную сборку и патчи вместо ветвящихся шаблонов. Вкус к Go-шаблонам в этом решении не участвует; участвует то, кому реестр откроет дверь.