Перейти к содержанию

Application и границы AppProject

Bootstrap подготовил локальный Git источник и Argo CD. Теперь нужно сообщить контроллеру, какую часть repository считать приложением и куда её применять. В этой главе создадим Application release-dev и AppProject release. Результат — явная связь repoURL, targetRevision, path и destination, которая не даёт двум окружениям случайно управлять одними объектами.

Файлы bootstrap/02-project.yaml и bootstrap/03-applications.yaml входят в конечный архив. Автор их не применял и не наблюдал состояния CRD. API сверены с официальными Application specification и Projects; ожидаемые примеры продолжают локальную лабораторию, а не неизвестный рабочий кластер.

Application находится рядом с контроллером

Metadata.namespace argocd означает место хранения объекта Application. Destination.namespace ploshchadka-dev означает место размещения его прикладных ресурсов. Эти поля выполняют разные функции. Если механически заменить оба namespace одним именем, API/web окажутся в области управления инструментом либо Application не будет найден в ожидаемом месте.

Source.repoURL указывает читаемый Git daemon, targetRevision main выбирает ветку, path gitops/overlays/dev выбирает каталог Kustomize. Коммит в app/api сам по себе не создаёт новый образ, а путь bootstrap не должен случайно стать прикладным источником. Выбранный каталог содержит только желаемые ресурсы dev окружения и ссылку на общую base.

Destination.server использует https://kubernetes.default.svc — Kubernetes API внутри того же кластера. Это не адрес браузера и не Service нашего API. Внутрикластерное назначение не требует регистрации неизвестного внешнего кластера. Context kind-release остаётся адресом reader команд kubectl, а server в Application обозначает адрес, которым пользуется контроллер.

Полная декларация одного приложения

Ниже приведён объект release-dev из включённого файла. Второй объект release-stage отличается именем, path и destination namespace. Automated отсутствует, поэтому последующее применение остаётся ручным.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: release-dev
  namespace: argocd
spec:
  project: release
  source:
    repoURL: git://git.release-lab.svc.cluster.local/release.git
    targetRevision: main
    path: gitops/overlays/dev
  destination:
    server: https://kubernetes.default.svc
    namespace: ploshchadka-dev
  syncPolicy:
    syncOptions:
      - FailOnSharedResource=true

TargetRevision main удобно для поступающих commits, но это перемещающийся указатель. Перед sync reader читает фактически разрешённый commit, чтобы знать, какой набор будет применён. Если нужна фиксированная версия источника, можно выбрать immutable commit или согласованный тег. В лаборатории история намерения проходит через main, а теги отмечают известные стадии.

FailOnSharedResource помогает обнаружить попытку совместного управления ресурсом, который уже принадлежит другому Application. Это дополнительная защита, а не замена правильной структуры. У dev и stage разные namespaces, поэтому Deployment api с одинаковым именем обозначает разные Kubernetes объекты. Имя Application также остаётся уникальным в argocd.

Проект ограничивает источники и назначения

AppProject release разрешает один конкретный repoURL и два namespace в том же Kubernetes API. NamespaceResourceWhitelist допускает Deployment, Service и ConfigMap. ClusterResourceWhitelist пуст. Такой набор соответствует фактическим обязанностям gitops/base: процессам, внутренним адресам и обычной конфигурации. Он не включает Secret, Namespace или инфраструктуру Git Service.

Если кто-то добавит в overlay cluster-scoped объект либо поменяет destination на случайный namespace, ограничение проекта должно остановить такое применение. Ошибка будет относиться к разрешениям декларации, а не к синтаксису прикладного HTTP. Reader сначала сопоставляет объект и проект, затем расширяет allowlist только если новая обязанность осмысленно входит в учебный маршрут.

Создание namespaces вынесено в bootstrap. Поэтому в Application нет CreateNamespace=true, которое конфликтовало бы с избранной границей. Такой порядок позволяет показать, что наличие destination.namespace не всегда означает автоматическое создание области. Перед sync namespace должен существовать и быть указан в допустимых destinations проекта.

Bootstrap Secret остаётся внешней зависимостью

API Deployment ссылается на api-demo-secret, но Secret не находится в GitOps каталоге. Reader создаёт учебный ключ DEMO_ADMIN_TOKEN отдельно в dev и stage. Значение заведомо демонстрационное, однако сама структура показывает нужную границу: ссылка на имя может быть в Git, действующие полномочия требуют другого процесса доставки.

Если Secret отсутствует, контейнер API не должен незаметно стартовать без настройки. SecretRef не помечен optional. Поэтому готовность приложения зависит от bootstrap ответственности. Argo CD может успешно применить Deployment, а Pod остановится при создании контейнера. Это ожидаемая разница между корректной декларацией и удовлетворёнными зависимостями выполнения.

Для рабочего проекта возможны External Secrets, защищённое хранение и другие варианты, но ни один из них автоматически не установлен этим архивом. Добавление имени такого инструмента в статью не создало бы полный пример. В нашей лаборатории внешний относительно Application Secret прост и явно указан; следующая документация должна сохранять это условие при передаче.

Роль пользователя и роль контроллера различаются

Project roles observer и releaser описывают прикладные действия в Argo CD. Observer может читать release приложения, releaser — читать и sync. Но сами roles не назначаются случайному человеку автоматически: нужен определённый субъект либо выданный токен по процедуре администратора. Подготовленный YAML показывает политики, не заявляя выполненную настройку реальных пользователей.

Kubernetes ServiceAccount стандартного Argo CD installation имеет собственные полномочия. AppProject фильтрует допустимое поведение приложений, но не является полной заменой Kubernetes RBAC. Поэтому лаборатория остаётся в отдельном кластере. Для минимальных производственных полномочий пришлось бы отдельно проектировать installation, области контроллера и доступ к cluster API.

Отдельно рассмотрим ошибку назначения. Если dev overlay уже содержит namespace ploshchadka-dev, а Application случайно указывает stage, reader не должен ожидать, что контроллер автоматически исправит исходную декларацию. Нужно прочитать итоговые адреса и согласовать source с destination. Namespace входит в идентичность ресурса, поэтому такая ошибка может создать другой объект, а не перенести прежний. AppProject допускает обе учебные области, но сам факт разрешения ещё не делает выбранное сочетание правильным. Политика отвечает на вопрос допустимости, структура приложения — на вопрос намерения. Для команды полезно хранить bootstrap Application в Git рядом с описанием обязанностей, даже если оно применяется отдельно от своего прикладного source.

После будущего применения AppProject, затем Application ожидается чтение source и построение манифестов. Если Git main ещё не опубликован или путь написан неверно, ошибка source появится до запуска приложения. Если всё доступно, но ресурсов ещё нет, ожидается OutOfSync. Это содержательная исходная точка для следующей главы: прочитать желаемое изменение и выполнить первый ручной sync.

Оглавление серии