Argo CD запрещает destination или ресурс: ограничения AppProject

Приложение видит манифесты, но получает сообщение, что destination не разрешён проектом. Установка нового токена Git не поможет: исходники уже прочитаны, отказ относится к области развёртывания. AppProject задаёт, откуда приложение может получать конфигурацию, куда её применять и какие типы ресурсов использовать.

Сопоставляем Application с проектом

kubectl -n argocd get application demo-api -o yaml
kubectl -n argocd get appproject team-api -o yaml
argocd app get demo-api --refresh
argocd proj get team-api

В Application найдите spec.project, source.repoURL либо все sources и destination. В проекте сопоставьте sourceRepos, destinations и ограничения видов ресурсов. Проверять нужно реальные значения, включая protocol URL и namespace. Если приложение указывает destination.name, выясните соответствующий cluster server: правила допуска destination проверяются по адресу сервера, поэтому случайное совпадение человекочитаемого имени не подтверждает доступ.

Отделите три уровня: право пользователя управлять Application в Argo CD, разрешение проекта использовать источник и destination, право Argo CD выполнять Kubernetes API-запросы. Успех на одном уровне не даёт автоматического разрешения на остальных. Сообщение об отказе проекта нужно исправлять в политике проекта, а Forbidden от API — расследовать в credentials и RBAC целевого кластера.

Ограничиваем пример одним namespace

Такой AppProject разрешает один Git-источник и namespace team-api в локальном кластере. RepoURL является заполнителем. Список cluster-scoped ресурсов намеренно пуст, а RoleBinding запрещён среди namespaced-ресурсов:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-api
  namespace: argocd
spec:
  sourceRepos:
    - https://git.example.com/team/api.git
  destinations:
    - server: https://kubernetes.default.svc
      namespace: team-api
  clusterResourceWhitelist: []
  namespaceResourceBlacklist:
    - group: rbac.authorization.k8s.io
      kind: RoleBinding

Обычные Deployment, Service и ConfigMap внутри team-api не требуют разрешения как cluster-scoped виды. Namespace и CustomResourceDefinition имеют область всего кластера и требуют соответствующего допуска. Если chart неожиданно генерирует Namespace или ClusterRole, запрет может быть правильным результатом разделения ответственности. Рассмотрите отдельную установку инфраструктурных объектов, вместо открытия всех видов через group: "*" и kind: "*".

Поля group содержат API group без версии: apps для Deployment, пустая строка для core API. Ошибочное apps/v1 не соответствует нужной группе. kind — имя типа ресурса с правильным регистром. Не переносите сюда resource-имена в нижнем регистре из Kubernetes Role: у этих схем разные поля и назначение.

Разрешение и запрет читаем вместе

В sourceRepos и destinations могут быть отрицательные правила с префиксом !. Подходящее разрешение не отменяет подходящий запрет. Поэтому добавление ещё одного широкого destination не обязательно снимет отказ. Найдите точное совпадение всех правил и проверьте, не охватывает ли wildcard больше окружений, чем предполагалось.

Если включён whitelist namespaced-видов или дополнительные ограничения глобального проекта, учтите их вместе с blacklist. Пример выше не представляет все возможности AppProject: он показывает минимальную границу конкретного сервиса. В существующей установке читайте полный объект и унаследованные настройки, чтобы не потерять действующую защиту при замене YAML.

Проверяем исправление без лишнего расширения доступа

До изменения проекта получите желаемые манифесты и найдите тип, вызвавший отказ. Затем согласуйте минимальную поправку: нужный namespace, конкретный repoURL или отдельный допустимый kind. Редактирование AppProject влияет на все связанные Application, поэтому проверьте список потребителей. Не переключайте приложение на permissive default только ради исчезновения сообщения.

После изменения повторите refresh и diff, затем согласованный Sync. Если проектный отказ исчез, но API вернул Forbidden, переходите к следующему уровню прав, сохраняя исходную область доступа. Ограничения AppProject не устанавливают Kubernetes RoleBinding и не выдают облачные credentials. Завершённая проверка подтверждает допустимость нужного релиза и сохранение запрета на посторонний namespace или вид ресурса.

Ещё по теме

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

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

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

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

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