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 of ModulePullOverride:
apiVersion: deckhouse.io/v1alpha2
kind: ModulePullOverride
metadata:
name: <module-name>
spec:
imageTag: <tag of the module image>
scanInterval: <image digest check interval. Default: 15s>
Requirements for the resource parameters:
-
The module name (
metadata.name
) must match the module name in the ModuleSource (.status.modules.[].name
). -
The container image tag (
spec.imageTag
) can be anything, e.g.,pr333
,my-branch
.
The spec.scanInterval
time interval (optional) defines the interval for scanning images in the registry. The default interval is 15 seconds.
To force scan you can change the interval or set the renew=""
annotation on ModulePullOverride.
You can get the result of applying ModulePullOverride in the message (column MESSAGE
) when retrieving ModulePullOverride information. The value Ready
indicates the successful application of ModulePullOverride parameters. Any other value indicates conflict.
Example of absence of conflicts when using ModulePullOverride:
$ kubectl get modulepulloverrides.deckhouse.io
NAME UPDATED MESSAGE
example1 10s Ready
Requirements for the module:
-
The module must exist; otherwise the message for ModulePullOverride will be The module not found.
An example:
$ kubectl get modulepulloverrides.deckhouse.io NAME UPDATED MESSAGE example1 10s The module not found
-
The module must not be embedded Deckhouse module; otherwise the message in ModulePullOverride will be The module is embedded.
An example:
$ kubectl get modulepulloverrides.deckhouse.io NAME UPDATED MESSAGE ingress-nginx 10s The module is embedded
-
The module must be enabled; otherwise, the message for ModulePullOverride will be The module disabled.
An example:
$ kubectl get modulepulloverrides.deckhouse.io NAME UPDATED MESSAGE example 7s The module disabled
-
The module must have a source; otherwise the message at ModulePullOverride will be The module does not have an active source.
An example:
$ kubectl get modulepulloverrides.deckhouse.io NAME UPDATED MESSAGE example 12s The module does not have an active source
-
The source for the module must exist; otherwise the message for ModulePullOverride will be The source not found.
An example:
$ kubectl get modulepulloverrides.deckhouse.io NAME UPDATED MESSAGE example 12s The source not found
To update the module without waiting for the next update cycle to begin, you can execute the following command:
kubectl annotate mpo <name> renew=""
How it works
After creating ModulePullOverride, the corresponding module will not consider ModuleUpdatePolicy, and will also not load and create ModuleRelease objects. The module will be loaded upon every change of the imageDigest
parameter, after which it will be applied in the cluster. The ModuleSource status will have overridden: true
, which indicates that ModulePullOverride is being used instead of ModuleUpdatePolicy. Also, the corresponding Module object will have an IsOverridden
field in its status, and the module version from imageTag
.
An example:
apiVersion: deckhouse.io/v1alpha1
kind: Module
metadata:
creationTimestamp: "2024-11-18T15:34:15Z"
generation: 16
labels:
deckhouse.io/epoch: "1326105356"
name: example
resourceVersion: "230347744"
uid: 7111cee7-50cd-4ecf-ba20-d691b13b0f59
properties:
availableSources:
- example
releaseChannel: Stable
requirements:
deckhouse: '> v1.63.0'
kubernets: '> v1.30.0'
source: example
version: mpo-tag
weight: 910
status:
conditions:
- lastProbeTime: "2024-12-03T15:57:20Z"
lastTransitionTime: "2024-12-03T15:57:20Z"
status: "True"
type: EnabledByModuleConfig
- lastProbeTime: "2024-12-03T15:59:58Z"
lastTransitionTime: "2024-12-03T15:57:26Z"
status: "True"
type: EnabledByModuleManager
- lastProbeTime: "2024-12-03T15:59:58Z"
lastTransitionTime: "2024-12-03T15:56:23Z"
status: "True"
type: IsReady
- lastProbeTime: "2024-12-03T15:59:48Z"
lastTransitionTime: "2024-12-03T15:56:47Z"
status: "True"
type: IsOverridden
phase: Ready
The module will keep running after ModulePullOverride is removed. But if there is a ModuleUpdatePolicy for the module, new releases of the module (ModuleRelease) will be pulled to replace the current “developer version”.
An example
-
Suppose there are two modules,
echo
andhello-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
-
Enable the module and create ModulePullOverride for the
echo
module:apiVersion: deckhouse.io/v1alpha2 kind: ModulePullOverride metadata: name: echo spec: imageTag: main-patch-03354
After creating ModulePullOverride, the image tag registry.example.com/deckhouse/modules/echo:main-patch-03354
will be used for the module (ms:spec.registry.repo/mpo:metadata.name:mpo:spec.imageTag
).
-
The ModulePullOverride will change with each update of the module:
apiVersion: deckhouse.io/v1alpha2 kind: ModulePullOverride metadata: name: echo spec: imageTag: main-patch-03354 scanInterval: 15s status: imageDigest: sha256:ed958cc2156e3cc363f1932ca6ca2c7f8ae1b09ffc1ce1eb4f12478aed1befbc message: "Ready" 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.
-
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
.
Print the list of modules in the module source
crane ls <REGISTRY_URL>/<MODULE_SOURCE>
An example:
$ crane ls registry.example.io/modules-source
module-1
module-2
Print the list of module images
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
.
Print the list of files in the module image
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.
Print the list of images of the module’s application containers
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"
}
Print the list of releases
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:
Print the version in use on the alpha
release channel
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"}