Prune и selfHeal в Argo CD: какие изменения они исправляют

В репозитории убрали старый ConfigMap, но он продолжает существовать. В другом приложении оператор вручную изменил число реплик, и через некоторое время значение вернулось. Оба случая связаны с согласованием Git и кластера, однако включаются разными настройками. Чтобы выбрать поведение, сначала разделим изменение содержимого существующего объекта и удаление объекта целиком.

Что даёт автоматическая синхронизация

Argo CD получает желаемые манифесты из источников Application и сравнивает их с live-состоянием. При включённой автоматической синхронизации изменение желаемой ревизии может запускать применение без нажатия Sync. При этом автоматическое удаление лишних ресурсов по умолчанию выключено. Включение automated само по себе не означает согласия на все виды исправлений.

spec:
  syncPolicy:
    automated:
      enabled: true
      prune: false
      selfHeal: false

Это фрагмент Application для современной схемы Argo CD. enabled: true явно включает автоматическую синхронизацию. При enabled: false автоматический запуск выключен, даже если остальные флаги равны true. В старых установках проверьте поддержку enabled установленной CRD: неизвестное поле не следует считать работающим переключателем. Для Application, создаваемого ApplicationSet, меняйте управляющий шаблон, иначе контроллер может восстановить прежние настройки.

Prune удаляет ресурс, которого больше нет в желаемом наборе

В Git были Deployment api и ConfigMap api-old. Затем ConfigMap убрали из желаемых манифестов. С prune: false Argo CD может применить новый Deployment, сохранив старый ConfigMap в кластере. С prune: true автоматическая синхронизация получает право удалить отслеживаемый лишний объект. Это не очистка всего namespace: значение имеет принадлежность ресурса приложению и его отслеживание.

Перед включением prune найдите, кто пользуется удаляемым объектом. Secret или ConfigMap может быть подключён workload другого приложения, а данные PersistentVolumeClaim требуют отдельного жизненного цикла. Удаление YAML в репозитории становится операционным действием. Проверять нужно diff желаемого набора и зависимости, а не только успешность рендера.

SelfHeal исправляет отклонение в самом кластере

Теперь Git не менялся, но кто-то вручную заменил image Deployment. selfHeal: true позволяет обнаруженному live-отклонению снова инициировать автоматическую синхронизацию той же желаемой версии. Это помогает возвращать конфигурацию к согласованному состоянию. При выключенном selfHeal нельзя рассчитывать, что ручная правка будет жить всегда: последующая синхронизация из-за нового commit тоже способна перезаписать её.

Особенно важно учитывать multi-source Application: изменение другого источника может привести к синхронизации всего приложения. Поэтому selfHeal: false не является режимом «ручные изменения защищены». Для аварийного вмешательства нужен согласованный порядок: кто приостанавливает автоматизацию, где фиксируется временное изменение и когда оно переносится в источник истины. Сам флаг не заменяет такой порядок.

spec:
  syncPolicy:
    automated:
      enabled: true
      prune: true
      selfHeal: true
      allowEmpty: false

В этой конфигурации автоматизация может и удалять лишние отслеживаемые объекты, и исправлять live-отклонения. allowEmpty: false оставляет защиту от ситуации, когда желаемый набор ресурсов стал полностью пустым. Это отдельная защита от массового удаления, а не запрет удалить любой последний важный объект среди остальных ресурсов. Обычное удаление одного ConfigMap из непустого набора всё ещё допускается.

Проверяем переключатели разными экспериментами

Используйте отдельное учебное Application без данных и внешних зависимостей. Первый эксперимент: измените тестовую метку в live ConfigMap, не меняя Git. Запишите diff и проверьте, возвратилось ли значение при selfHeal. Второй эксперимент: удалите этот ConfigMap из Git и дождитесь применения новой ревизии. Проверьте, исчез ли объект при prune. Изменять оба условия одновременно неудобно: результат не покажет, какой механизм сработал.

argocd app get demo-policy --refresh
argocd app diff demo-policy
kubectl -n demo get configmap policy-check -o yaml

Эти команды читают состояние; команды изменения специально зависят от вашего учебного репозитория. В истории операции сохраните ревизию и список действий. Если объект не удалился, проверьте ресурсные sync-options, защиту удаления и finalizers. Если поле не вернулось, проверьте ignoreDifferences и результат сравнения: selfHeal работает с обнаруженным отклонением, а не с любой записью API.

Перед включением автоматического удаления полезно просмотреть полный результат генерации на новой ревизии. Ошибка values может убрать сразу несколько объектов, хотя каталог Git выглядит почти неизменным. allowEmpty защищает полностью пустой набор, но не распознаёт, что среди десяти ресурсов случайно исчезли девять. Поэтому ревью сгенерированного diff остаётся необходимой частью процедуры, особенно для общих Secret и объектов хранения.

Возврат удалённого манифеста в Git создаст ресурс заново, но не обязательно вернёт прежнее содержимое данных и внешние последствия удаления. Для ConfigMap с конфигурацией это одна ситуация, для связанных хранилищ — другая. В учебном эксперименте используйте объект без данных: так можно проверить семантику prune, не смешивая её с процедурой восстановления состояния.

Ручной Sync тоже имеет параметр pruning, поэтому вывод «prune выключен в политике — удаление невозможно» неверен. Перед запуском операции изучайте её выбранные параметры и набор ресурсов. Хорошая настройка описывает, какие изменения команда разрешает исправлять автоматически, и позволяет проверить это двумя независимыми сценариями.

Ещё по теме

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

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

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

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

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