Ограничения Application

Уровень: advanced ~50 мин Практика: Umami (MIT)

Что нужно знать перед уроком

  • M5.04 — Контекст Helm/Nelm-шаблонов Application — нужно понимать, как строятся шаблоны, чтобы осознать, чего они делать НЕ могут
  • M2.01 — Application vs Module — фундаментальная граница ответственности, из которой следуют все ограничения этого урока

Что нужно знать перед уроком

M2 урок 1 — Application ограничен namespace-уровнем инфраструктуры. Здесь — буквальный список всех ограничений, зафиксированных в официальной документации Deckhouse — Концепции Application и Module, и объяснение почему каждое из них существует.

Теория

Полный список функциональных ограничений (по официальной документации Deckhouse — Концепции Application и Module)

  1. Только namespaced-ресурсы. Application не может создавать ClusterRole, ClusterRoleBinding, PersistentVolume (в отличие от PersistentVolumeClaim, который namespaced), StorageClass, Namespace и любые другие cluster-wide объекты.
  2. Запрет на CRD. Application-пакет не может объявлять CustomResourceDefinition — ни в crds/, ни где-либо ещё в шаблонах.
  3. Хуки ограничены namespace инстанса. ObjectPatcher из ApplicationHookInput (M5 урок 8) архитектурно ограничен операциями внутри namespace конкретного инстанса — попытка создать/изменить ресурс в другом namespace или cluster-wide ресурс отклоняется на уровне runtime, а не просто «не рекомендуется».
  4. Только ручная установка. В отличие от Module, у которого возможно автовключение через ModuleConfig (M2 урок 3), Application устанавливается только явным действием пользователя (созданием ресурса Application) — нет механизма автоматической установки по каким-либо триггерам.
  5. Зависимость допустима только от Module, не от другого Application. requirements.modules.mandatory в package.yaml (M5 урок 2) может ссылаться только на Module — Application не может объявить зависимость от другого Application-пакета.

Почему каждое правило существует — архитектурная логика

flowchart TB A["Application: namespace-уровень"] -->|"без границ namespace"| B["Cluster-wide изменения затрагивают ВСЕХ пользователей кластера"] B --> C["Запрет cluster-wide ресурсов и CRD защищает мультитенантность"] A -->|"хуки без изоляции"| D["Хук одного Application мог бы влиять на namespace другой команды"] D --> E["ObjectPatcher жёстко ограничен собственным namespace"] A -->|"автовключение по триггеру"| F["Непредсказуемое появление ресурсов пользователя без явного действия"] F --> G["Только ручная установка через явный Application CR"]
  • Namespace-изоляция и запрет CRD — прямое следствие модели мультитенантности: множество команд/пользователей одного кластера устанавливают свои Application-пакеты независимо друг от друга; если бы Application мог создавать cluster-wide объекты или CRD, установка одного пакета одной командой могла бы повлиять на весь кластер, включая namespace других команд — что противоречит самой цели существования Application как изолированной, безопасной для мультитенантности единицы.
  • Ограничение хуков собственным namespace — то же самое соображение мультитенантности, применённое к программируемой логике (Go-хуки, M5 урок 8): без этого ограничения вредоносный или просто ошибочный хук одного Application мог бы модифицировать ресурсы совершенно другого приложения в другом namespace.
  • Только ручная установка — Application, в отличие от Module (обеспечивающего инфраструктурные возможности всего кластера), не является чем-то, что администратор платформы решает включить «для всех» — это выбор конкретного пользователя/команды установить конкретное приложение для своих нужд, поэтому автоматическое/триггерное включение архитектурно не имеет смысла в модели Application.
  • Зависимость только от Module — если бы Application мог зависеть от другого Application, возникла бы проблема транзитивных зависимостей между независимо устанавливаемыми пользовательскими объектами без единого администратора, гарантирующего их согласованное версионирование (в отличие от Module, который управляется администратором платформы централизованно) — зависимость на уровне Module сохраняет чёткую границу: cluster-wide инфраструктура (Module) может быть зависимостью, но пользовательские приложения (Application) — только независимые единицы друг от друга.

Частые ошибки и подводные камни

  • Пытаться «обойти» ограничение через хук, создающий ресурс в другом namespace напрямую через Kubernetes API-клиент, а не через ObjectPatcher. Хотя официальная документация Deckhouse по хукам явно указывает, что хуки могут читать cluster-wide ресурсы через d8 k/API-клиент, запись за пределы своего namespace заблокирована архитектурно на уровне ObjectPatcher — попытка обойти это через другой клиент нарушает саму модель безопасности платформы и может быть заблокирована RBAC на уровне ServiceAccount хука.
  • Проектировать пакет, ожидающий зависимость от другого Application. Если два ваших приложения логически связаны (например, общий frontend для двух независимых backend-сервисов), правильная архитектура — либо объединить их в один Application-пакет с несколькими компонентами (паттерн из M3/M6), либо явно документировать порядок ручной установки, но не пытаться выразить эту связь как формальную зависимость requirements.
  • Путать «читать» и «писать» в контексте хуков. Ограничение касается записи/изменения ресурсов — чтение cluster-wide информации хуками разрешено (нужно, например, для проверки доступности зависимого Module).

Практика в кластере

🧩 Практика урока: Без нового приложения — проверяем ограничения на уровне API
1
2
3
# Попробуйте создать Application с попыткой сослаться на несуществующий тип зависимости
d8 k explain application.spec
d8 k get crd | grep -i application    # убедитесь, что сам Application — CRD платформы, но пакеты Application не добавляют новых CRD

Практика разработки

Практики разработки в этом уроке нет — материал про архитектурные ограничения, которые нужно учитывать при проектировании шаблонов и хуков (M5 уроки 4, 8), а не отдельный код для написания.

Шпаргалка команд урока

1
d8 k explain application.spec

Вопросы для самопроверки

Может ли Application-пакет объявлять CustomResourceDefinition?

Запрет на CRD — прямое архитектурное следствие модели мультитенантности и границы Application/Module.

Источник: Deckhouse — Concepts

Может ли хук Application ЧИТАТЬ cluster-wide ресурсы, даже если не может их изменять?

Ограничение касается записи, а не чтения — хукам нужно читать cluster-wide состояние, например, для проверки доступности Module-зависимости.

Источник: Deckhouse — Хуки Application

Может ли Application устанавливаться автоматически по какому-либо триггеру, аналогично автовключению Module?

Это одно из функциональных ограничений — Application не поддерживает автовключение в отличие от некоторых сценариев Module.

Источник: Deckhouse — Concepts

Может ли requirements.modules.mandatory в package.yaml ссылаться на другой Application?

Это фундаментальное ограничение, разделяющее пользовательские приложения (Application, независимые друг от друга) и cluster-wide инфраструктуру (Module, допустимую как зависимость).

Источник: Deckhouse — Concepts

Почему хуки Application архитектурно ограничены собственным namespace?

Namespace-изоляция хуков — прямое следствие модели безопасности мультитенантного кластера.

Источник: Deckhouse — Хуки Application

Рекомендуемая литература

Официальная документация

Статьи и блоги

Книги

  • Marko Lukša. Kubernetes in Action. 2nd ed., 2022. ISBN 978-1617297618.

Связанные материалы