CRD платформы вокруг Application

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

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

  • M5.05 — Ограничения Application — нужно понимать модель мультитенантности перед разбором конкретных CRD, её реализующих

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

M2 урок 3 — общая статусная модель платформы (conditions/status.summary) и объекты PackageRepository/PackageRepositoryOperation. Здесь — полная картина всех пяти CRD marketplace-модели платформы и как они связаны друг с другом.

Теория

Пять CRD полной resource-модели marketplace

flowchart TD PR["PackageRepository\n(регистрация registry + расписание сканирования)"] -->|"запускает"| PRO["PackageRepositoryOperation\n(задача сканирования)"] PR -->|"наполняет"| APV["ApplicationPackageVersion\n(обнаруженная версия пакета с метаданными/requirements)"] APV -->|"агрегируется в"| AP["ApplicationPackage\n(информационный агрегат по всем версиям)"] APV -->|"на неё ссылается"| APP["Application\n(namespace-scoped установленный инстанс)"]
CRDScopeРоль
PackageRepository (PR)Clusterподключение к registry + расписание сканирования на наличие новых пакетов/версий
PackageRepositoryOperation (PRO, kubectl shortName pro)Clusterконкретная задача сканирования (аналог «джобы» на синхронизацию метаданных)
ApplicationPackageVersion (APV, kubectl shortName apv)Clusterобнаруженная конкретная версия пакета — метаданные из package.yaml, requirements, ссылка на образы, а также сами OpenAPI v3-схемы настроек и values (status.packageSchemas.settingsSchema/valuesSchema), по которым платформа валидирует Application.spec.settings
ApplicationPackage (AP)Clusterинформационный агрегат — сводка по всем версиям одного пакета (используется каталогом marketplace для отображения)
Application (APP)Namespaced, shortName appконкретный установленный инстанс — единственный из пяти, кто реально управляет деплоем через Nelm

Только Application — namespace-scoped; все остальные четыре CRD существуют на уровне кластера, т.к. они описывают доступные для установки пакеты (аналог каталога), не привязанные к какому-то конкретному namespace до момента реальной установки конкретным пользователем.

Разбор потока данных

  1. Администратор создаёт PackageRepository, указывая адрес registry и расписание сканирования.
  2. PackageRepository инициирует PackageRepositoryOperation — платформа сканирует registry на наличие пакетов/версий.
  3. Результат сканирования — набор ApplicationPackageVersion, каждая описывает одну конкретную версию одного пакета: метаданные из его package.yaml, а также сами OpenAPI v3-схемы (status.packageSchemas.settingsSchema/valuesSchema), извлечённые платформой из релиз-образа пакета — именно по ним затем валидируются пользовательские настройки и effective-values.
  4. Все версии одного и того же пакета агрегируются в единый ApplicationPackage — именно этот объект видит пользователь в каталоге marketplace как «одна карточка приложения» с выбором версии.
  5. Когда пользователь решает установить конкретную версию — он создаёт Application в своём namespace, ссылаясь на конкретный ApplicationPackageVersion (через имя пакета и версию в spec); платформа валидирует spec.settings по settingsSchema из этой ApplicationPackageVersion, и только после успешной валидации Nelm (M4) реально разворачивает ресурсы в кластере.

Application CRD — полная схема

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: applications.deckhouse.io
spec:
  group: deckhouse.io
  names:
    kind: Application
    plural: applications
    singular: application
    shortNames:
      - app
  scope: Namespaced
  versions:
    - name: v1alpha1
      served: true
      storage: true

shortName: app — то, что позволяет писать сокращённо d8 k get app вместо полного d8 k get application (аналог po для pod, deploy для deployment из M1). Реальный пример объекта:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: deckhouse.io/v1alpha1
kind: Application
metadata:
  name: umami-analytics
  namespace: team-alpha
spec:
  packageName: umami
  packageRepositoryName: my-registry
  packageVersion: "v1.0.1"
  settings:
    hostname: "analytics.example.com"
    replicas: 2

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

  • Пытаться установить Application, указав несуществующую или не просканированную версию в packageVersion. Без соответствующего ApplicationPackageVersion, обнаруженного через PackageRepositoryOperation, платформа не сможет разрешить установку — сначала должно пройти сканирование registry.
  • Путать ApplicationPackage (агрегат по всем версиям) с ApplicationPackageVersion (конкретная версия). Первый — это «карточка в каталоге», второй — «конкретный устанавливаемый релиз» этой карточки.
  • Ожидать, что PackageRepository/ApplicationPackage/ApplicationPackageVersion можно создать в конкретном namespace. Это cluster-scoped ресурсы — единственный namespace-scoped объект в этой пятёрке — сам Application.
  • Не находить эти CRD в старом кластере и списывать это на ошибку конфигурации. Marketplace-модель (все пять CRD) требует минимальной версии платформы, начиная с которой она появилась в DKP — если d8 k get crd | grep -E 'application|package' не находит их, вероятная причина именно в версии платформы, а не в настройках.

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

🧩 Практика урока: Umami · лицензия MIT
  1. Изучите все пять CRD через d8 k explain:
1
2
3
4
5
d8 k explain packagerepository
d8 k explain packagerepositoryoperation
d8 k explain applicationpackageversion
d8 k explain applicationpackage
d8 k explain application
  1. Если у вас настроен тестовый PackageRepository (из предыдущих модулей или созданный для практики курса), изучите цепочку от репозитория до конкретной версии:
1
2
3
4
d8 k get packagerepository -o yaml
d8 k get packagerepositoryoperation
d8 k get applicationpackageversion | grep umami
d8 k get applicationpackage umami -o yaml
  1. Создайте Application для Umami (используя пакет, собранный и опубликованный в предыдущих уроках, или заготовку для проверки синтаксиса):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
d8 k apply -n course-m5-umami -f - <<'EOF'
apiVersion: deckhouse.io/v1alpha1
kind: Application
metadata:
  name: umami-analytics
spec:
  packageName: umami
  packageRepositoryName: my-registry
  packageVersion: "v0.1.0"
  settings:
    hostname: "umami.local"
    replicas: 1
EOF
d8 k get app -n course-m5-umami

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

Практики разработки в этом уроке нет — фокус на изучении CRD как готовой платформенной модели.

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

1
2
3
4
5
d8 k get packagerepository|packagerepositoryoperation|applicationpackageversion|applicationpackage|application [-o yaml]
d8 k get app -n <ns>       # shortName Application
d8 k get apv               # shortName ApplicationPackageVersion
d8 k get pro               # shortName PackageRepositoryOperation
d8 k explain <crd-name>

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

Какой из пяти CRD marketplace-модели является единственным namespace-scoped?

Все остальные четыре CRD описывают доступные для установки пакеты на уровне кластера; только Application — конкретный установленный инстанс в namespace.

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

Чем ApplicationPackage отличается от ApplicationPackageVersion?

AP используется для отображения пакета в каталоге marketplace, APV — конкретный устанавливаемый релиз.

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

Что запускает PackageRepositoryOperation?

PRO — это задача сканирования, инициируемая PackageRepository согласно его расписанию.

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

Что означает shortName: app у CRD Application?

shortNames — стандартный механизм Kubernetes CRD для удобных сокращений в CLI.

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

Может ли пользователь установить Application, ссылаясь на версию пакета, которая ещё не была обнаружена ни одним PackageRepositoryOperation?

Без ApplicationPackageVersion платформа не может разрешить установку конкретной версии — сначала нужно сканирование registry.

Источник: Рекомендуемая литература

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

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

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

Книги

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

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