На этой странице описано, как Deckhouse Platform (DP) запускает экземпляр приложения и какие инструменты помогают отлаживать пакет.

Проверки при создании и изменении

Когда Application создаётся или изменяется, validating-вебхук DP проверяет, что:

  • имя Application не длиннее 24 символов;
  • ApplicationPackage существует, а ApplicationPackageVersion для указанных репозитория, пакета и версии существует и метаданные для неё загружены;
  • настройки соответствуют схеме настроек версии пакета (см. «Настройки приложения»);
  • кластер удовлетворяет требованиям пакета: версиям Kubernetes и DP и зависимостям от модулей. В сообщении об отказе указываются невыполненное требование, требуемое значение и значение в кластере.

Этапы установки

DP обрабатывает каждый экземпляр приложения в отдельной очереди по шагам:

  1. Загрузка. DP загружает bundle пакета указанной версии из репозитория.
  2. Чтение пакета. DP читает package.yaml, схемы и images_digests.json и находит хуки.
  3. Планирование. DP ждёт, пока не выполнятся требования пакета: бутстрап кластера завершён, версии Kubernetes и DP соответствуют ограничениям, а модули из requirements.modules включены. Пока DP ждёт модули, от которых зависит приложение, это отражается в summary ресурса Application.
  4. Конфигурация. DP проверяет и применяет настройки.
  5. Инициализация хуков. DP включает привязки schedule и мониторы Kubernetes хуков и выполняет Synchronization привязок Kubernetes. В первый раз после чтения пакета DP также запускает хуки onStartup.
  6. Применение. DP запускает хуки beforeHelm, рендерит шаблоны и применяет их с помощью Nelm, а затем запускает хуки afterHelm. Если хуки afterHelm меняют values, DP применяет шаблоны ещё раз.

Шаги 4–6 составляют цикл согласования. На шаге применения DP обновляет Helm-релиз, только если это нужно: при первой установке, если последняя ревизия релиза не развёрнута, если отрендеренные манифесты изменились или если каких-то ресурсов нет в кластере.

Порядок привязок хуков и обработка ошибок хуков описаны в разделе «Хуки».

События и реакции

Событие Реакция DP
Меняется поле spec.settings или spec.maintenance ресурса Application Новый цикл согласования
Хук schedule или хук с привязкой Kubernetes меняет values Новый цикл согласования
Меняется поле spec.packageVersion DP останавливает хуки текущей версии, сохраняя её ресурсы, и проходит все шаги с новой версией. Шаблоны новой версии применяются как обновление того же Helm-релиза
DP перезапускается DP заново читает пакет и проходит все шаги, включая хуки onStartup
Ресурс приложения удалён из кластера DP восстанавливает его (см. «Восстановление ресурсов»)
Требования пакета перестают выполняться, например, отключается модуль из requirements.modules.mandatory DP удаляет приложение, но сохраняет Application (см. «Приостановка»)
Application удаляется DP удаляет приложение и его осиротевшие ресурсы, после чего удаляется Application (см. «Удаление»)

Приостановка

DP проверяет требования пакета не только при создании Application, но и постоянно. Если требования установленного приложения перестают выполняться, DP:

  1. Запускает хуки beforeDeleteHelm.
  2. Удаляет Helm-релиз, из-за чего удаляются ресурсы приложения.
  3. Запускает хуки afterDeleteHelm.

Application остаётся в кластере в состоянии Suspended, а осиротевшие ресурсы приложения не удаляются. Когда требования снова выполняются, DP заново устанавливает приложение с теми же настройками.

Ресурсы удаляются вместе с Helm-релизом, включая PersistentVolumeClaim. Чтобы сохранить данные, добавьте к PersistentVolumeClaim аннотацию helm.sh/resource-policy: keep (см. «Аннотации Nelm»).

Удаление

При удалении Application DP:

  1. Запускает хуки beforeDeleteHelm.
  2. Удаляет Helm-релиз и ждёт удаления его ресурсов.
  3. Запускает хуки afterDeleteHelm и останавливает хуки: отключает привязки schedule и мониторы Kubernetes.
  4. Удаляет осиротевшие ресурсы приложения.
  5. Удаляет Application.

Если шаг завершается с ошибкой, DP повторяет его с увеличивающейся задержкой — от 15 секунд до 2 часов. Application остаётся в кластере, пока все шаги не выполнятся успешно.

Осиротевшие ресурсы

Удаление Helm-релиза удаляет только объекты релиза. В неймспейсе остаются:

  • объекты, которые рабочие нагрузки или хуки приложения создают во время работы;
  • объекты шаблонов, которые Nelm не удаляет при удалении релиза, если они ещё есть в кластере (см. «Аннотации Nelm»):
    • Helm-хуки, то есть объекты с аннотацией helm.sh/hook;
    • объекты с аннотацией werf.io/ownership: anyone, например, Job, который развёртывается только при установке;
    • объекты с аннотацией helm.sh/resource-policy: keep и объекты, у которых аннотация werf.io/resource-policy содержит keep или skip-delete.

Чтобы DP удалял такие объекты вместе с Application, перечислите их типы в поле orphanResources values: задайте список как значение по умолчанию этого поля в openapi/values.yaml. Например:

x-extend:
  schema: settings.yaml
type: object
properties:
  orphanResources:
    type: array
    default:
      - kind: Job
        version: batch/v1
      - kind: ConfigMap
        version: v1
    items:
      type: object
      required: [kind, version]
      properties:
        kind:
          type: string
        version:
          type: string

Каждый элемент списка содержит следующие поля:

  • kind — тип объектов, например, Job.
  • version — версия API типа: <GROUP>/<VERSION>, например, batch/v1, или только <VERSION>, например, v1. Версии без группы соответствует тип во всех группах API, которые обслуживают его в этой версии, поэтому элементу с kind: Job и version: v1 соответствуют и объекты Job из batch/v1. Чтобы тип выбирался только из одной группы, укажите группу.

Объявляйте поле в openapi/values.yaml, а не в openapi/settings.yaml, чтобы пользователи не могли изменить список в spec.settings. DP читает список из values текущей версии пакета в момент удаления Application. Если предыдущие версии пакета создавали объекты других типов, оставьте эти типы в списке.

DP удаляет объекты перечисленных типов, которые находятся в неймспейсе Application и имеют метку packages.deckhouse.io/instance: <INSTANCE_NAME>. Имена объектов не важны. DP добавляет эту метку ко всем объектам, отрендеренным из шаблонов, включая Helm-хуки (см. «Шаблоны»). Объекты, созданные рабочими нагрузками и хуками, не получают метку автоматически, поэтому задавайте её сами. Например, хук задаёт в метке имя экземпляра:

input.PatchCollector.CreateOrUpdate(&corev1.ConfigMap{
    TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
    ObjectMeta: metav1.ObjectMeta{
        Name:   "state",
        Labels: map[string]string{"packages.deckhouse.io/instance": input.Instance.Name()},
    },
    Data: map[string]string{"instance": input.Instance.Name()},
})

Рабочая нагрузка может получить имя экземпляра из шаблонов (.Application.Instance.Name), например, через переменную окружения.

DP удаляет объекты после удаления Helm-релиза и остановки хуков, чтобы приложение не могло создать их заново. Зависимые объекты удаляются в фоне: например, поды удалённого Job удаляет сборщик мусора Kubernetes, поэтому их тип перечислять не нужно. DP не ждёт, пока объекты исчезнут: объект, у которого есть финализаторы, остаётся в кластере, пока финализаторы не будут сняты, даже после удаления Application.

DP не удаляет:

  • Объекты с аннотацией helm.sh/resource-policy: keep, даже если задана аннотация werf.io/resource-policy. Другие аннотации объект не защищают: DP удаляет объекты, у которых аннотация werf.io/resource-policy содержит keep или skip-delete, и объекты с аннотацией werf.io/ownership: anyone, например, Job из сценария «Ресурс, рендерящийся только при первой установке».
  • Объекты, которые уже удаляются.
  • Объекты типов уровня кластера и типов, которые кластер не обслуживает, например, кастомных ресурсов, определение которых (CRD) не установлено. DP пропускает такие типы и пишет предупреждение в свой лог.

DP удаляет осиротевшие ресурсы только при удалении Application. При приостановке приложения и при изменении версии пакета объекты остаются, потому что приложение может снова их использовать. Если пакет приложения не загружен в момент удаления Application, например, потому что DP не удалось загрузить bundle пакета, DP удаляет Helm-релиз, но не удаляет осиротевшие ресурсы.

Если DP не удаётся получить список объектов или удалить их, например, когда API-сервер недоступен, DP удаляет остальные объекты и повторяет шаг. Если значение orphanResources не является списком типов, DP пишет ошибку в свой лог и удаляет Application, не удаляя осиротевшие ресурсы.

DP записывает в свой лог каждый удалённый объект, каждый объект с аннотацией helm.sh/resource-policy: keep и каждый пропущенный тип: ищите в логе строку orphan. Пока DP повторяет шаг, в очереди приложения находится задача Purge с ошибкой (см. «Состояние в DP»).

Восстановление ресурсов

DP запоминает ресурсы, отрендеренные из шаблонов, и каждые 4–5 минут проверяет, что все они есть в кластере. Если какого-то ресурса нет, DP запускает цикл согласования, и ресурс создаётся заново.

DP проверяет только наличие ресурсов, но не их содержимое. Проверка приостанавливается, пока работают хуки, и отключена в режиме обслуживания.

Отслеживание развёртывания

Когда DP применяет шаблоны, Nelm ждёт, пока ресурсы станут готовыми. Ожиданием управляют аннотации отслеживания. Логи подов не собираются, поэтому аннотации логов не действуют.

Ход текущего применения публикуется в поле status.tracking ресурса Application: список операций Nelm с их состояниями и зависимостями.

Одно применение ограничено 30 минутами. Если лимит превышен, применение завершается с ошибкой таймаута, которая отражается в условиях Application.

Работает ли приложение после применения, определяется по его Deployment и StatefulSet (см. «Состояние рабочих нагрузок»).

Режим обслуживания

Чтобы отлаживать или вручную донастраивать установленное приложение, переведите его в режим обслуживания:

spec:
  maintenance: NoResourceReconciliation

В режиме обслуживания:

  • DP перестаёт применять шаблоны: изменения настроек и values не отражаются на ресурсах. Хуки продолжают работать.
  • Удалённые ресурсы не восстанавливаются.
  • DP добавляет к ресурсам, отрендеренным из шаблонов, метку maintenance.deckhouse.io/no-resource-reconciliation, и admission-политики перестают их защищать, поэтому ресурсы можно менять вручную. Чтобы добавить метку, DP один раз применяет шаблоны при включении режима.
  • Срабатывает алерт ApplicationIsInMaintenanceMode.

Чтобы вернуть приложение к обычной работе, удалите поле spec.maintenance. DP применит шаблоны, что восстановит управляемое состояние ресурсов и удалит метку.

Отладка

Статус Application

При разработке пакета полезны следующие поля статуса Application:

Поле Описание
status.summary Общее состояние приложения, причина и подсказка о том, что делать
status.conditions Подробные условия (см. «Установка и управление приложениями»)
status.currentVersion.version Установленная версия пакета
status.lastAppliedConfiguration Итоговые настройки последнего успешного применения
status.urls Адреса приложения
status.tracking Отчёт Nelm о ходе текущего или последнего применения

Пример:

d8 k -n <NAMESPACE> get applications <INSTANCE_NAME> -o jsonpath='{.status.summary}'

Состояние в DP

Команды deckhouse-controller packages показывают состояние приложения в DP. Имя пакета в этих командах — <NAMESPACE>.<INSTANCE_NAME>. Выполняйте команды в контейнере deckhouse пода-лидера DP.

Вывод содержит values и учётные данные для доступа к хранилищу образов. Доступ к нему должен быть только у администраторов кластера.

  • Отрендерить шаблоны с текущими values:

    d8 k -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller packages render <NAMESPACE>.<INSTANCE_NAME>
    
  • Показать загруженный пакет: путь, описание, дайджесты образов, репозиторий, values, хуки и внутренние условия:

    d8 k -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller packages dump --name <NAMESPACE>.<INSTANCE_NAME>
    
  • Показать снапшоты привязок Kubernetes хуков:

    d8 k -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller packages snapshots <NAMESPACE>.<INSTANCE_NAME>
    
  • Показать очереди задач приложения:

    d8 k -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller packages queue dump --name <NAMESPACE>.<INSTANCE_NAME>
    
  • Показать состояние приложения в планировщике, например, какое требование не выполнено:

    d8 k -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller packages scheduler dump --name <NAMESPACE>.<INSTANCE_NAME>
    

Логи

DP записывает события обработки приложения, включая вывод хуков, в свой лог:

d8 k -n d8-system logs svc/deckhouse-leader -c deckhouse | grep '<NAMESPACE>.<INSTANCE_NAME>'

Дополнительные ресурсы