При разработке модулей может возникнуть необходимость загрузить и развернуть модуль в обход каналов обновления. Для этого используется ресурс ModulePullOverride.

Пример ModulePullOverride:

1apiVersion: deckhouse.io/v1alpha2
2kind: ModulePullOverride
3metadata:
4  name: <module-name>
5spec:
6  imageTag: <tag of the module image>
7  scanInterval: <image digest check interval. Default: 15s>

Требования к параметрам ресурса:

  • Имя модуля (metadata.name) должно соответствовать имени модуля в ModuleSource (.status.modules.[].name).

  • Тег образа контейнера (spec.imageTag) может быть любым. Например, pr333, my-branch.

Необязательный параметр spec.scanInterval устанавливает интервал времени для проверки образов в registry. По умолчанию задан интервал в 15 секунд. Для принудительного обновления можно изменить интервал, либо установить на ModulePullOverride аннотацию renew="".

Необязательный параметр spec.rollback — если установить этот параметр в true, это восстановит развернутый модуль до предыдущего состояния после удаления ModulePullOverride.

Deckhouse предоставляет возможность временно изменить поведение модуля с помощью дополнительных параметров объекта ModulePullOverride. Эти параметры позволяют управлять жизненным циклом модуля независимо от module.yaml:

  • unmanagedboolean. Отключает управление модулем со стороны Deckhouse (никаких обновлений или удалений).
  • disableboolean. Временно отключает модуль и удаляет все его ресурсы.
  • terminatingboolean. Переводит модуль в состояние удаления, в результате чего удаляются все ресурсы и сам объект Module.
  • rollbackboolean. Если установлен в true, то при удалении объекта ModulePullOverride:
    • будут удалены артефакты модуля;
    • Deckhouse перезапустится;
    • будет восстановлена последняя стабильная версия модуля.

Пример:

1apiVersion: deckhouse.io/v1alpha1
2kind: ModulePullOverride
3metadata:
4  name: example
5spec:
6  version: v1.2.3
7  unmanaged: false
8  disable: false
9  terminating: false
10  rollback: true

Результат применения ModulePullOverride можно увидеть в сообщении (колонка MESSAGE) при получении информации об ModulePullOverride. Значение Ready означает применение параметров ModulePullOverride. Любое другое значение означает конфликт.

Пример отсутствия конфликтов при применении ModulePullOverride:

1$ kubectl get modulepulloverrides.deckhouse.io 
2NAME      UPDATED   MESSAGE   ROLLBACK
3example1  10s       Ready     false

Требования к модулю:

  • Модуль должен существовать, иначе сообщение у ModulePullOverride будет The module not found.

    Пример:

    1$ kubectl get modulepulloverrides.deckhouse.io 
    2NAME      UPDATED   MESSAGE                ROLLBACK
    3example1  10s       The module not found   false
    
  • Модуль не должен быть встроенным модулем Deckhouse, иначе сообщение у ModulePullOverride будет The module is embedded.

    Пример:

    1$ kubectl get modulepulloverrides.deckhouse.io 
    2NAME           UPDATED  MESSAGE                  ROLLBACK
    3ingress-nginx  10s      The module is embedded   false
    
  • Модуль должен быть включен, иначе сообщение у ModulePullOverride будет The module disabled.

    Пример:

    1$ kubectl get modulepulloverrides.deckhouse.io 
    2NAME     UPDATED   MESSAGE               ROLLBACK
    3example  7s        The module disabled   false
    
  • Модуль должен иметь источник, иначе сообщение у ModulePullOverride будет The module does not have an active source.

    Пример:

    1$ kubectl get modulepulloverrides.deckhouse.io 
    2NAME       UPDATED   MESSAGE                                     ROLLBACK
    3example    12s       The module does not have an active source   false
    
  • Источник модуля должен существовать, иначе сообщение у ModulePullOverride будет The source not found.

    Пример:

    1$ kubectl get modulepulloverrides.deckhouse.io 
    2NAME       UPDATED   MESSAGE                 ROLLBACK
    3example    12s       The source not found    false
    

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

1kubectl annotate mpo <name> renew=""

Принцип действия

После создания ModulePullOverride, соответствующий модуль не будет учитывать ModuleUpdatePolicy, а также не будет загружать и создавать объекты ModuleRelease. Модуль будет загружаться при каждом изменении параметра imageDigest, после чего будет применяться в кластере. В статусе ModuleSource модуль получит признак overridden: true, который указывает на то, что используется ModulePullOverride, а не ModuleUpdatePolicy. Также, соответствующий объект Module будет иметь в своем статусе поле IsOverridden и версию модуля из imageTag.

Пример:

1apiVersion: deckhouse.io/v1alpha1
2kind: Module
3metadata:
4  creationTimestamp: "2024-11-18T15:34:15Z"
5  generation: 16
6  labels:
7    deckhouse.io/epoch: "1326105356"
8  name: example
9  resourceVersion: "230347744"
10  uid: 7111cee7-50cd-4ecf-ba20-d691b13b0f59
11properties:
12  availableSources:
13  - example
14  releaseChannel: Stable
15  requirements:
16    deckhouse: '> v1.63.0'
17    kubernets: '> v1.30.0'
18  source: example
19  version: mpo-tag
20  weight: 910
21status:
22  conditions:
23  - lastProbeTime: "2024-12-03T15:57:20Z"
24    lastTransitionTime: "2024-12-03T15:57:20Z"
25    status: "True"
26    type: EnabledByModuleConfig
27  - lastProbeTime: "2024-12-03T15:59:58Z"
28    lastTransitionTime: "2024-12-03T15:57:26Z"
29    status: "True"
30    type: EnabledByModuleManager
31  - lastProbeTime: "2024-12-03T15:59:58Z"
32    lastTransitionTime: "2024-12-03T15:56:23Z"
33    status: "True"
34    type: IsReady
35  - lastProbeTime: "2024-12-03T15:59:48Z"
36    lastTransitionTime: "2024-12-03T15:56:47Z"
37    status: "True"
38    type: IsOverridden
39  phase: Ready

После удаления ModulePullOverride модуль продолжит работать. Но, если для модуля существует ModuleUpdatePolicy, то загрузятся новые релизы модуля (ModuleRelease), которые заменят текущую “версию разработчика”.

Пример

  1. В ModuleSource присутствуют два модуля echo и hello-world. Для них определена политика обновления, они загружаются и устанавливаются в DKP:

    1apiVersion: deckhouse.io/v1alpha1
    2kind: ModuleSource
    3metadata:
    4  name: test
    5spec:
    6  registry:
    7    ca: ""
    8    dockerCfg: someBase64String==
    9    repo: registry.example.com/deckhouse/modules
    10    scheme: HTTPS
    11status:
    12  modules:
    13  - name: echo
    14    policy: test-alpha
    15  - name: hello-world
    16    policy: test-alpha
    17  modulesCount: 2
    
  2. Включите модуль и создайте ModulePullOverride для модуля echo:

    1apiVersion: deckhouse.io/v1alpha2
    2kind: ModulePullOverride
    3metadata:
    4  name: echo
    5spec:
    6  imageTag: main-patch-03354
    

    После создания ModulePullOverride, для модуля будет использоваться тег образа registry.example.com/deckhouse/modules/echo:main-patch-03354 (ms:spec.registry.repo/mpo:metadata.name:mpo:spec.imageTag).

  3. Данные ModulePullOverride будут меняться при каждом обновлении модуля:

    1apiVersion: deckhouse.io/v1alpha2
    2kind: ModulePullOverride
    3metadata:
    4  name: echo
    5spec:
    6  imageTag: main-patch-03354
    7  scanInterval: 15s
    8status:
    9  imageDigest: sha256:ed958cc2156e3cc363f1932ca6ca2c7f8ae1b09ffc1ce1eb4f12478aed1befbc
    10  message: "Ready"
    11  updatedAt: "2023-12-07T08:41:21Z"
    

    где:

    • imageDigest — уникальный идентификатор образа контейнера, который был загружен.
    • lastUpdated — время последней загрузки образа.
  4. При этом ModuleSource приобретет вид:

    1apiVersion: deckhouse.io/v1alpha1
    2kind: ModuleSource
    3metadata:
    4  name: test
    5spec:
    6  registry:
    7    ca: ""
    8    dockerCfg: someBase64String==
    9    repo: registry.example.com/deckhouse/modules
    10    scheme: HTTPS
    11status:
    12  modules:
    13  - name: echo
    14    overridden: true
    15  - name: hello-world
    16    policy: test-alpha
    17  modulesCount: 2
    

Артефакты модуля в container registry

После сборки модуля его артефакты должны быть загружены в container registry по пути, который является источником для загрузки и запуска модулей в DKP. Путь, по которому загружаются артефакты модулей в registry, указывается в ресурсе ModuleSource.

Пример иерархии образов контейнеров после загрузки артефактов модулей module-1 и modules-2 в registry:

1registry.example.io
2📁 modules-source
3├─ 📁 module-1
4│  ├─ 📦 v1.23.1
5│  ├─ 📦 d4bf3e71015d1e757a8481536eeabda98f51f1891d68b539cc50753a-1589714365467
6│  ├─ 📦 e6073b8f03231e122fa3b7d3294ff69a5060c332c4395e7d0b3231e3-1589714362300
7│  ├─ 📦 v1.23.2
8│  └─ 📁 release
9│     ├─ 📝 v1.23.1
10│     ├─ 📝 v1.23.2
11│     ├─ 📝 alpha
12│     └─ 📝 beta
13└─ 📁 module-2
14   ├─ 📦 v0.30.147
15   ├─ 📦 d4bf3e71015d1e757a8481536eeabda98f51f1891d68b539cc50753a-1589714365467
16   ├─ 📦 e6073b8f03231e122fa3b7d3294ff69a5060c332c4395e7d0b3231e3-1589714362300
17   ├─ 📦 v0.31.1
18   └─ 📁 release
19      ├─ 📝 v0.30.147
20      ├─ 📝 v0.31.1
21      ├─ 📝 alpha
22      └─ 📝 beta

Container registry должен поддерживать вложенную структуру репозиториев. Подробнее об этом в разделе требований.

Далее приведен список команд для работы с источником модулей. В примерах используется утилита crane. Установите ее по инструкции. Для macOS воспользуйтесь brew.

Вывод списка модулей в источнике модулей

1crane ls <REGISTRY_URL>/<MODULE_SOURCE>

Пример:

1$ crane ls registry.example.io/modules-source
2module-1
3module-2

Вывод списка образов модуля

1crane ls <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>

Пример:

1$ crane ls registry.example.io/modules-source/module-1
2v1.23.1
3d4bf3e71015d1e757a8481536eeabda98f51f1891d68b539cc50753a-1589714365467
4e6073b8f03231e122fa3b7d3294ff69a5060c332c4395e7d0b3231e3-1589714362300
5v1.23.2

В примере в модуле module-1 присутствуют два образа модуля и два образа контейнеров приложений.

Вывод файлов в образе модуля

1crane export <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>:<MODULE_TAG> - | tar -tf -

Пример:

1crane export registry.example.io/modules-source/module-1:v1.23.1 - | tar -tf -

Ответ будет достаточно большим.

Вывод списка образов контейнеров приложений модуля

1crane export <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>:<MODULE_TAG> - | tar -Oxf - images_digests.json

Пример:

1$ crane export registry.example.io/modules-source/module-1:v1.23.1 -  | tar -Oxf - images_digests.json
2{
3  "backend": "sha256:fcb04a7fed2c2f8def941e34c0094f4f6973ea6012ccfe2deadb9a1032c1e4fb",
4  "frontend": "sha256:f31f4b7da5faa5e320d3aad809563c6f5fcaa97b571fffa5c9cab103327cc0e8"
5}

Просмотр списка релизов

1crane ls <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>/release

Пример:

1$ crane ls <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>/release
2v1.23.1
3v1.23.2
4alpha
5beta

В примере в container registry два релиза и используются два канала обновлений: alpha и beta.

Вывод версии, используемой на канале обновлений alpha

1crane export <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>/release:alpha - | tar -Oxf - version.json

Пример:

1$ crane export registry.example.io/modules-source/module-1/release:alpha - | tar -Oxf - version.json
2{"version":"v1.23.2"}