When developing modules, you may want to pull and deploy a module bypassing the release channels. The ModulePullOverride resource is used for this purpose.

An example:

apiVersion: deckhouse.io/v1alpha1
kind: ModulePullOverride
metadata:
  name: <module-name>
spec:
  imageTag: <tag of the module image>
  scanInterval: <image digest check interval. Default: 15s>
  source: <ModuleSource ref>

Requirements for the resource parameters:

  • The metadata.name module name must match the module name in the ModuleSource (the .status.modules.[].name parameter).

  • The spec.imageTag container image tag can be anything, e.g., ~pr333~, ~my-branch~.

  • The ModuleSource spec.source parameter provides the data for registry authorization.

The spec.scanInterval time interval (optional) defines the interval for scanning images in the registry. The default interval is 15 seconds.

You can specify a longer interval to force a refresh, and use the renew=“” annotation.

Below is an example of the command:

kubectl annotate mpo <name> renew=""

How it works

When developing this resource, the specified module will not consider ModuleUpdatePolicy, nor will it load or create ModuleRelease objects.

Instead, the module will be pulled every time the imageDigest parameter is changed and it will be applied in the cluster. At the same time, that module will get the overridden: true attribute in the status of the ModuleSource resource, indicating that the ModulePullOverride resource is being used.

The module will keep running after ModulePullOverride is removed. However, if the ModuleUpdatePolicy policy is applied to the module, new releases (if available) will be pulled to replace the current “developer version”.

An example

  1. Suppose there are two modules, echo and hello-world, defined in ModuleSource. The update policy is set for them, and they are pulled in and installed in DKP:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleSource
    metadata:
      name: test
    spec:
      registry:
        ca: ""
        dockerCfg: someBase64String==
        repo: registry.example.com/deckhouse/modules
        scheme: HTTPS
    status:
      modules:
      - name: echo
        policy: test-alpha
      - name: hello-world
        policy: test-alpha
      modulesCount: 2
    
  2. Create a ModulePullOverride resource for the echo module:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModulePullOverride
    metadata:
      name: echo
    spec:
      imageTag: main-patch-03354
      source: test
    

    This resource will be validating the registry.example.com/deckhouse/modules/echo:main-patch-03354 image tag (ms:spec.registry.repo/mpo:metadata.name:mpo:spec.imageTag).

  3. The status of this resource will change with each update:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModulePullOverride
    metadata:
      name: echo
    spec:
      imageTag: main-patch-03354
      scanInterval: 15s
      source: test
    status:
      imageDigest: sha256:ed958cc2156e3cc363f1932ca6ca2c7f8ae1b09ffc1ce1eb4f12478aed1befbc
      message: ""
      updatedAt: "2023-12-07T08:41:21Z"
    

    where:

    • imageDigest is the unique identifier of the container image that was pulled.
    • lastUpdated is the time when the image was last pulled.
  4. In this case, ModuleSource would look as follows:

    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleSource
    metadata:
      name: test
    spec:
      registry:
        ca: ""
        dockerCfg: someBase64String==
        repo: registry.example.com/deckhouse/modules
        scheme: HTTPS
    status:
      modules:
      - name: echo
        overridden: true
      - name: hello-world
        policy: test-alpha
      modulesCount: 2
    

Module artifacts in the container registry

After a module has been built, its artifacts must be pushed to the container registry at a path that is the source path for pulling and running modules in DKP. The path where module artifacts are pushed to the registry is specified in the ModuleSource resource.

Below is an example of the container image hierarchy after pushing the module-1 and modules-2 module artifacts into the registry:

registry.example.io
📁 modules-source
├─ 📁 module-1
│  ├─ 📦 v1.23.1
│  ├─ 📦 d4bf3e71015d1e757a8481536eeabda98f51f1891d68b539cc50753a-1589714365467
│  ├─ 📦 e6073b8f03231e122fa3b7d3294ff69a5060c332c4395e7d0b3231e3-1589714362300
│  ├─ 📦 v1.23.2
│  └─ 📁 release
│     ├─ 📝 v1.23.1
│     ├─ 📝 v1.23.2
│     ├─ 📝 alpha
│     └─ 📝 beta
└─ 📁 module-2
   ├─ 📦 v0.30.147
   ├─ 📦 d4bf3e71015d1e757a8481536eeabda98f51f1891d68b539cc50753a-1589714365467
   ├─ 📦 e6073b8f03231e122fa3b7d3294ff69a5060c332c4395e7d0b3231e3-1589714362300
   ├─ 📦 v0.31.1
   └─ 📁 release
      ├─ 📝 v0.30.147
      ├─ 📝 v0.31.1
      ├─ 📝 alpha
      └─ 📝 beta

The container registry must support a nested repository structure. See the requirements section for more details.

Below is a list of commands for working with the module source. The examples use the crane tool. Follow the instructions to install it. For macOS, use brew.

crane ls <REGISTRY_URL>/<MODULE_SOURCE>

An example:

$ crane ls registry.example.io/modules-source
module-1
module-2
crane ls <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>

An example:

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

In the example above, there are two module images and two application container images in module-1.

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

An example:

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

The output will be quite large.

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

An example:

$ crane export registry.example.io/modules-source/module-1:v1.23.1 -  | tar -Oxf - images_digests.json
{
  "backend": "sha256:fcb04a7fed2c2f8def941e34c0094f4f6973ea6012ccfe2deadb9a1032c1e4fb",
  "frontend": "sha256:f31f4b7da5faa5e320d3aad809563c6f5fcaa97b571fffa5c9cab103327cc0e8"
}
crane ls <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>/release

An example:

$ crane ls <REGISTRY_URL>/<MODULE_SOURCE>/<MODULE_NAME>/release
v1.23.1
v1.23.2
alpha
beta

In the example above, there are two releases in the container registry; two release channels, alpha and beta, are also used:

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

An example:

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