Helm Job завис при установке через Argo CD: hooks, имена и жизненный цикл

Chart содержит подготовительный Job, и после подключения к Argo CD синхронизация не завершается. Повторный Sync либо снова ждёт, либо получает ошибку изменения Job. Установка через helm install работала, но Argo CD использует Helm для рендера и управляет операцией иначе. Начнём с аннотаций конкретного ресурса и причины его ожидания.

Находим фазу и реальное состояние Job

argocd app get demo-api --refresh
argocd app manifests demo-api
kubectl -n demo get jobs,pods
kubectl -n demo describe job api-prepare
kubectl -n demo logs job/api-prepare

Возьмите имя Job из желаемого манифеста. Если Pod вообще не создан, журналов ещё нет: читайте события Job. Если Pod Pending, исследуйте scheduler, образ и PVC. Если контейнер Running, выясните, какую внешнюю операцию он ждёт и есть ли у неё timeout. Статус hook не заменяет состояние Kubernetes Job, а его отсутствие не доказывает ошибку Argo CD.

Install и upgrade превращаются в Sync

Аннотации Helm pre-install и pre-upgrade отображаются в PreSync, post-install и post-upgrade — в PostSync. Argo CD не различает установку и обновление так, как Helm CLI: каждая операция является Sync. Поэтому два разных hook, рассчитанных автором chart на разные события Helm, могут оказаться в одной фазе. Проверьте их совместимость и порядок, вместо ожидания прежней последовательности.

hook-weight отображается в sync-wave. Волна определяет порядок внутри фазы и не переносит обычный Secret из Sync перед PreSync Job. Если Job ждёт базу или ServiceAccount, которые впервые создаются тем же приложением как обычные ресурсы, получится зависимость на ещё не выполненную фазу. Подготовьте зависимость заранее либо спроектируйте другую согласованную последовательность ресурсов.

Повтор именованного Job требует жизненного цикла

У существующего Job многие поля template неизменяемы. Если при новом рендере изменился image, простое применение к прежнему имени может завершиться ошибкой immutable field. Для повторяемого подготовительного hook нужен явный договор о пересоздании. Пример на Argo-аннотациях выполняет безопасную учебную команду и сохраняет результат до следующего запуска:

apiVersion: batch/v1
kind: Job
metadata:
  name: api-prepare
  namespace: demo
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
  backoffLimit: 0
  activeDeadlineSeconds: 60
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: check
          image: busybox:1.37
          command: ["sh", "-c", "date"]

BeforeHookCreation удаляет предыдущий hook перед созданием нового. Это позволяет повторно выполнить именованный Job и не пытается изменить его template на месте. Для реального подготовительного действия нужна идемпотентность: повтор может произойти после частично выполненной работы. Переименование Job каждым commit также вызывает новые выполнения, поэтому само по себе не защищает данные.

Не смешиваем два набора аннотаций случайно

Argo CD поддерживает многие Helm hook-аннотации через отображение, но жизненный цикл удаления не обязан совпадать с Helm для всех ресурсов. Особенно отличаются пассивные ресурсы вроде ServiceAccount, у которых нет состояния завершения как у Job. Если в приложении определены Argo CD hooks, Helm hooks игнорируются. Перед добавлением одного «исправляющего» Argo hook проверьте остальные hooks chart, чтобы не выключить нужную подготовку.

Выберите один согласованный способ для приложения: адаптированные Helm hooks либо явно управляемые Argo hooks. Unsupported Helm hooks нельзя считать выполненными только потому, что аннотация сохранилась в YAML. Посмотрите фактическую операцию Sync и список ресурсов. Selective sync отдельных ресурсов не выполняет hooks, поэтому для релиза, зависящего от подготовки, нужна полная операция по принятой процедуре.

Проверяем завершение и следующий запуск

После исправления проверьте текущий полный Sync, успешное состояние Job и готовность workload. Затем на учебном окружении повторите полную операцию: должен появиться новый запуск с ожидаемым результатом. До пересоздания сохраните журналы, если они нужны для расследования. Deadline останавливает бесконечное ожидание, но не отменяет внешнее действие, которое Job успел выполнить.

Запишите фазу, существующие зависимости, правило удаления и контракт повторного выполнения. Проверьте, что Job завершился, а основной workload начал обновление после необходимой подготовки.

Ещё по теме

Продолжить изучение

Хотите выстроить доставку изменений из Git в кластер? Синхронизация, окружения и восстановление после неудачного релиза — темы программы «Argo CD и GitOps: деплой в Kubernetes».

Продолжить на практике

  • Argo CD и GitOps: деплой в Kubernetes ↗

    Превратите Git в источник правды для Kubernetes. Настройте Argo CD, управляемую синхронизацию и окружения, научитесь находить drift и откатывать изменения через Git. Итог — воспроизводимый GitOps-процесс для приложения.