The ability to use internal registry is implemented by the registry module.
The internal registry allows for optimizing the downloading and storage of images, as well as helping to ensure availability and fault tolerance for Deckhouse Kubernetes Platform.
Modes of operation with the internal registry
The registry module, which implements internal storage, operates in the following modes:
Direct: Enables the internal container image registry. Access to the internal registry is performed via the fixed addressregistry.d8-system.svc:5001/system/deckhouse. This fixed address allows Deckhouse images to avoid being re-downloaded and components to avoid being restarted when registry parameters change. Switching between modes and registries is done through thedeckhouseModuleConfig. The switching process is automatic (for more details, see the switching examples below) for more information. The architecture of the mode is described in the section Direct Mode Architecture.Unmanaged: Operation without using the internal registry. Access within the cluster is performed directly to the external registry. There are two types of theUnmanagedmode:- Configurable: A mode managed via the
registrymodule. Switching between modes and registries is handled through the ModuleConfig ofdeckhouse. The switch is performed automatically (for more details, see the switching examples below). - Non-configurable (deprecated): The default mode. Configuration parameters are set during cluster installation or changed in a running cluster using the (deprecated)
helper change registrycommand.
- Configurable: A mode managed via the
- The
Directmode requires using theContainerdorContainerd V2CRI on all cluster nodes. For CRI setup, refer to theClusterConfiguration.
Restrictions on working with the internal registry
Working with the internal registry using the registry module has a number of limitations and restrictions concerning installation, operating conditions, and mode switching.
Cluster installation limitations
DKP cluster bootstrap is only supported in non-configurable Unmanaged mode. Registry settings during bootstrap are specified through initConfiguration.
Registry configuration via the deckhouse moduleConfig during DKP cluster bootstrap is not supported.
Operating conditions restrictions
The registry module works under the following conditions:
- If CRI containerd or containerd v2 is used on the cluster nodes. To configure CRI, refer to the ClusterConfiguration configuration.
- The cluster is fully managed by DKP. The module will not work in Managed Kubernetes clusters.
Mode switching restrictions
Mode switching restrictions are as follows:
- For the first switch, migration of user registry configurations must be performed. For more details, see the Registry Module: FAQ section.
- Switching to the non-configurable
Unmanagedmode is only available from theUnmanagedmode. For more details, see the Registry Module: FAQ section.
Examples of switching
Switching to Direct Mode
To switch an already running cluster to Direct mode, follow these steps:
When changing the registry mode or registry parameters, Deckhouse will be restarted.
-
Before switching, perform the migration to use the
registrymodule. -
Make sure the
registrymodule is enabled and running. To do this, execute the following command:d8 k get module registry -o wideExample output:
NAME WEIGHT ... PHASE ENABLED DISABLED MESSAGE READY registry 38 ... Ready True True -
Make sure all master nodes are in the
Readystate and do not have theSchedulingDisabledstatus, using the following command:d8 k get nodesExample output:
NAME STATUS ROLES ... master-0 Ready control-plane,master ... master-1 Ready control-plane,master ... master-2 Ready control-plane,master ...Example of output when the master node (
master-2in the example) is in theSchedulingDisabledstatus:NAME STATUS ROLES ... master-0 Ready control-plane,master ... master-1 Ready control-plane,master ... master-2 Ready,SchedulingDisabled control-plane,master ... -
Ensure the Deckhouse job queue is empty and contains no errors:
d8 system queue listExample output:
Summary: - 'main' queue: empty. - 107 other queues (0 active, 107 empty): 0 tasks. - no tasks to handle. -
Set the
Directmode configuration in the ModuleConfigdeckhouse. If you’re using a registry other thanregistry.deckhouse.io, refer to thedeckhousemodule documentation for correct configuration.Configuration example:
apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: deckhouse spec: version: 1 enabled: true settings: registry: mode: Direct direct: imagesRepo: registry.deckhouse.io/deckhouse/ee scheme: HTTPS license: <LICENSE_KEY> # Replace with your license key -
Check the registry switch status in the
registry-statesecret using this guide.Example output:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Direct target_mode: Direct
Switching to Unmanaged Mode
To switch an already running cluster to Unmanaged mode, follow these steps:
Changing the registry mode or its parameters will cause Deckhouse to restart.
-
Before switching, perform the migration to use the
registrymodule. -
Make sure the
registrymodule is enabled and running. To do this, execute the following command:d8 k get module registry -o wideExample output:
NAME WEIGHT ... PHASE ENABLED DISABLED MESSAGE READY registry 38 ... Ready True True -
Ensure the Deckhouse job queue is empty and contains no errors:
d8 system queue listExample output:
Summary: - 'main' queue: empty. - 107 other queues (0 active, 107 empty): 0 tasks. - no tasks to handle. -
Set the
Unmanagedmode configuration in the ModuleConfigdeckhouse. If you’re using a registry other thanregistry.deckhouse.io, refer to thedeckhousemodule documentation for correct configuration.Configuration example:
apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: deckhouse spec: version: 1 enabled: true settings: registry: mode: Unmanaged unmanaged: imagesRepo: registry.deckhouse.io/deckhouse/ee scheme: HTTPS license: <LICENSE_KEY> # Replace with your license key -
Check the registry switch status in the
registry-statesecret using this guide.Example output:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Unmanaged target_mode: Unmanaged -
If you need to switch back to the old registry management method, refer to the instruction.
This is a deprecated format for registry management.
Migration to the registry module
During the migration, Containerd v1 will switch to the new registry configuration format. Containerd v2 uses the new format by default. For more details, see the section with a description of configuration methods.
For containerd v2
-
Switch to using the
registrymodule. To do this, specify theUnmanagedmode parameters in thedeckhousemoduleConfig. If you are using a registry other thanregistry.deckhouse.io, refer to thedeckhousemodule documentation for proper configuration.You can view the current registry settings using the following command:
d8 k -n d8-system exec -it svc/deckhouse-leader -c deckhouse -- deckhouse-controller global values | yq e '.modulesImages.registry' -Specify this configuration when setting up the
Unmanagedmode:apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: deckhouse spec: version: 1 enabled: true settings: registry: mode: Unmanaged unmanaged: imagesRepo: registry.deckhouse.io/deckhouse/ee scheme: HTTPS license: <LICENSE_KEY> # Replace with your license key -
Wait for the switch to complete. Example status output:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Unmanaged target_mode: Unmanaged
For Containerd v1
- During the switch, containerd v1 will be restarted.
- During the switch, containerd v1 will be migrated to the new registry configuration scheme.
- During the switch, custom registry configurations for containerd v1 will be temporarily unavailable.
-
Make sure that nodes with containerd v1 do not have any custom registry configurations located in the
/etc/containerd/conf.ddirectory. -
If configurations are present, you need to migrate to the new registry configuration format in containerd. To do this, add new configuration files to the
/etc/containerd/registry.ddirectory. These configurations will take effect after switching to theregistrymodule. To add configurations, prepare aNodeGroupConfiguration. For more details, see the section with a description of configuration methods. Example:apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: # The step can be arbitrary, as restarting the containerd service is not required weight: 0 bundles: - '*' nodeGroups: - "*" content: | # Copyright 2023 Flant JSC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. REGISTRY_URL=private.registry.example mkdir -p "/etc/containerd/registry.d/${REGISTRY_URL}" bb-sync-file "/etc/containerd/registry.d/${REGISTRY_URL}/hosts.toml" - << EOF [host] [host."https://${REGISTRY_URL}"] capabilities = ["pull", "resolve"] [host."https://${REGISTRY_URL}".auth] username = "username" password = "password" EOF -
Apply the
NodeGroupConfiguration. Wait until the configuration files appear in the/etc/containerd/registry.ddirectory on all nodes. -
Verify that the configurations are working correctly. To do this, use the following command:
# For HTTPS: ctr -n k8s.io images pull --hosts-dir=/etc/containerd/registry.d/ private.registry.example/registry/path:tag # For HTTP: ctr -n k8s.io images pull --hosts-dir=/etc/containerd/registry.d/ --plain-http private.registry.example/registry/path:tag -
Switch to using the
registrymodule. To do this, specify theUnmanagedmode parameters in thedeckhousemoduleConfig. If you are using a registry other thanregistry.deckhouse.io, refer to thedeckhousemodule documentation for proper configuration.You can view the current registry settings using the following command:
d8 k -n d8-system exec -it svc/deckhouse-leader -c deckhouse -- deckhouse-controller global values | yq e '.modulesImages.registry' -Specify this configuration when setting up the
Unmanagedmode:apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: deckhouse spec: version: 1 enabled: true settings: registry: mode: Unmanaged unmanaged: imagesRepo: registry.deckhouse.io/deckhouse/ee scheme: HTTPS license: <LICENSE_KEY> # Replace with your license key -
After applying, wait for the following message to appear in the switch status:
Example output:
conditions: # ... - lastTransitionTime: "2025-08-13T15:22:34Z" message: | Check current nodes configuration 2/2 node(s) Unready: - master-0: has custom toml merge containerd configuration - worker-5e389be0-578df-s5sm5: has custom toml merge containerd configuration reason: Processing status: "False" type: ContainerdConfigPreflightReadyThis message means that there are old registry configurations on the nodes located in the
/etc/containerd/conf.ddirectory. The switch to the new containerd configuration is currently blocked. To allow the switch, you need to remove the old configuration files. -
Remove the old configuration files to allow switching to the
registrymodule. To do this, create aNodeGroupConfiguration, for example:apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: # To add a file before the '032_configure_containerd.sh' step weight: 0 bundles: - '*' nodeGroups: - "*" content: | # Copyright 2023 Flant JSC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. file="/etc/containerd/conf.d/old-config.toml" [ -f "$file" ] && rm -f "$file" -
After removing the old configurations, make sure that the switch has resumed. Example of the switch status:
conditions: # ... - lastTransitionTime: "2025-08-13T16:42:09Z" message: "" reason: "" status: "True" type: ContainerdConfigPreflightReady -
Wait for the switch to complete. Example of the switch status:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Unmanaged target_mode: Unmanaged
Migration back from the registry module
- This is a deprecated registry management format.
- During the switch, containerd v1 will be restarted.
- During the switch, containerd v1 will be migrated to the legacy registry configuration scheme.
- During the switch, custom registry configurations for containerd v1 will be temporarily unavailable.
-
Switch the registry to
Unmanagedmode. If you are using a registry other thanregistry.deckhouse.io, refer to thedeckhousemodule documentation for proper configuration.Example configuration:
apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: deckhouse spec: version: 1 enabled: true settings: registry: mode: Unmanaged unmanaged: imagesRepo: registry.deckhouse.io/deckhouse/ee scheme: HTTPS license: <LICENSE_KEY> -
Check the switch status using the instruction. Example output:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Unmanaged target_mode: Unmanaged -
Switch the registry to the non-configurable
Unmanagedmode. Example configuration:apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: deckhouse spec: version: 1 enabled: true settings: registry: mode: Unmanaged -
Check the switch status using the instruction. Example output:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Unmanaged target_mode: Unmanaged -
If containerd v1 is used and custom registry configurations are applied in the cluster, they must be replaced with the old format. To do this, prepare the registry configurations in the old format. These configurations do not need to be applied at this stage. Example configuration:
apiVersion: deckhouse.io/v1alpha1 kind: NodeGroupConfiguration metadata: name: containerd-additional-config-auth.sh spec: # To add a file before the '032_configure_containerd.sh' step weight: 31 bundles: - '*' nodeGroups: - "*" content: | # Copyright 2023 Flant JSC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. REGISTRY_URL=private.registry.example mkdir -p /etc/containerd/conf.d bb-sync-file /etc/containerd/conf.d/additional_registry.toml - << EOF [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".registry] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."${REGISTRY_URL}"] endpoint = ["https://${REGISTRY_URL}"] [plugins."io.containerd.grpc.v1.cri".registry.configs] [plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_URL}".auth] username = "username" password = "password" # OR auth = "dXNlcm5hbWU6cGFzc3dvcmQ=" EOF -
Delete the
registry-bashible-configsecret. This will trigger containerd v1 to switch back to the legacy registry format:d8 k -n d8-system delete secret registry-bashible-config -
After deletion, wait for the switch to complete. Use the instruction to track the progress. Example output:
conditions: # ... - lastTransitionTime: "..." message: "" reason: "" status: "True" type: Ready hash: .. mode: Unmanaged target_mode: Unmanaged -
If containerd v1 is used, apply the previously prepared
NodeGroupConfigurationwith custom registry configurations. -
Disable the
registrymodule. Example:apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: registry spec: enabled: false settings: {} version: 1
Check registry mode switch status
The status of the registry mode switch can be retrieved using the following command:
d8 k -n d8-system -o yaml get secret registry-state | yq -C -P '.data | del .state | map_values(@base64d) | .conditions = (.conditions | from_yaml)'
Example output:
conditions:
- lastTransitionTime: "2025-07-15T12:52:46Z"
message: 'registry.deckhouse.io: all 157 items are checked'
reason: Ready
status: "True"
type: RegistryContainsRequiredImages
- lastTransitionTime: "2025-07-11T11:59:03Z"
message: ""
reason: ""
status: "True"
type: ContainerdConfigPreflightReady
- lastTransitionTime: "2025-07-15T12:47:47Z"
message: ""
reason: ""
status: "True"
type: TransitionContainerdConfigReady
- lastTransitionTime: "2025-07-15T12:52:48Z"
message: ""
reason: ""
status: "True"
type: InClusterProxyReady
- lastTransitionTime: "2025-07-15T12:54:53Z"
message: ""
reason: ""
status: "True"
type: DeckhouseRegistrySwitchReady
- lastTransitionTime: "2025-07-15T12:55:48Z"
message: ""
reason: ""
status: "True"
type: FinalContainerdConfigReady
- lastTransitionTime: "2025-07-15T12:55:48Z"
message: ""
reason: ""
status: "True"
type: Ready
mode: Direct
target_mode: Direct
The output displays the status of the switch process. Each condition can have a status of True or False, and may contain a message field with additional details.
Description of conditions:
| Condition | Description |
|---|---|
ContainerdConfigPreflightReady |
State of the containerd configuration preflight check. Verifies there are no custom containerd auth configurations on the nodes. |
TransitionContainerdConfigReady |
State of preparing the containerd configuration for the new mode. Verifies that the configuration contains both the old and new mode settings. |
FinalContainerdConfigReady |
State of finalizing the switch to the new containerd mode. Verifies that the containerd configuration has been successfully applied and contains only the new mode settings. |
DeckhouseRegistrySwitchReady |
State of switching Deckhouse and its components to use the new registry. True means Deckhouse successfully switched and is ready to operate. |
InClusterProxyReady |
State of In-Cluster Proxy readiness. Checks that the In-Cluster Proxy has started successfully and is running. |
CleanupInClusterProxy |
State of cleaning up the In-Cluster Proxy if it is not needed in the selected mode. Verifies that all related resources have been removed. |
Ready |
Overall state of registry readiness in the selected mode. Indicates that all other conditions are met and the module is ready to operate. |