The module lifecycle stage: Generally available version

The module has requirements for installation

v0.8.1

Release date: 2026-10-01

The agent deletes BlockDevice resources that have stayed Missing past a configurable retention, the scheduler extender no longer promises the same free space twice in HA mode, and inactive thin volumes are activated again.

Highlights

Changes in this release:

  • New module setting missingBlockDeviceRetentionHours (24 by default): a BlockDevice whose device has been gone for that long and that no LVMVolumeGroup uses is deleted, so nodes with dynamically mapped LUNs no longer collect Missing resources forever.
  • With two replicas of sds-common-scheduler-extender (HA mode), space reservations are served by one elected replica, so two Pods can no longer be promised the same free space of a thin pool.
  • A thin LVMLogicalVolume deactivated while its thin pool stayed active is activated again by the agent.

New features

This release adds:

  • Module setting missingBlockDeviceRetentionHours (hours, 0 to 8760, 24 by default). A BlockDevice that is not consumable is not deleted when its device disappears: it gets the Missing condition, True after 10 minutes of absence. The agent now deletes such a resource of its node once Missing has been True for the retention, provided no LVMVolumeGroup lists it in status.nodes and its status.lvmVolumeGroupName does not name an existing LVMVolumeGroup, so a Physical Volume lost from under a live Volume Group stays visible. If the device returns, the resource is created again. 0 disables the deletion. The new metric sds_node_configurator_block_devices_missing{node,reason} counts the Missing=True resources that remain; each deletion is logged by the agent.
  • On DKP 1.78 and later, the module’s access roles follow the capability/scope RBAC scheme: the ClusterRoles d8:system-capability:sds-node-configurator:view and d8:system-capability:sds-node-configurator:edit grant read-only and full access to BlockDevice, LVMVolumeGroup, LVMVolumeGroupSet, LVMLogicalVolume and LVMLogicalVolumeSnapshot. Below 1.78 the module keeps the d8:manage:permission:module:sds-node-configurator:view and :edit roles.

Fixes

This release fixes:

  • In HA mode, the two sds-common-scheduler-extender replicas each kept their own space reservations in memory, so scheduling requests answered by different replicas could be promised the same free space and overcommit a thin pool. The replicas now elect a leader over the Lease d8-sds-node-configurator/sds-common-scheduler-extender; only the leader serves filtering, scoring and reservation requests, and the other replica forwards them to it, answering 503 while no leader is reachable.
  • A thin LVMLogicalVolume deactivated on its own (for example, with lvchange -an) while its thin pool stayed active was never activated again, so the volume stayed unavailable. The agent now runs vgchange -ay for its Volume Group as it already did for thick volumes and thin pools. Logical volumes carrying the activation skip flag, which the module never sets, are still left inactive.

Upgrade notes

Before upgrading, note the following:

  • Deletion of Missing resources is on by default. Right after the update, the agent deletes every BlockDevice that has already been Missing=True for more than 24 hours and is not used by an LVMVolumeGroup. To keep them, set missingBlockDeviceRetentionHours to 0 or to a larger value before updating.
  • On DKP 1.78 and later, the d8:manage:permission:module:sds-node-configurator:view and :edit ClusterRoles are replaced by d8:system-capability:sds-node-configurator:view and :edit. Bindings that reference the old role names directly have to be switched to the new ones.

Docs

Documentation changes:

  • The Russian reference for BlockDevice now covers status.conditions and its fields.

Dependencies

Dependency updates:

  • LVM2 (lvm, dmsetup on the nodes): main snapshot → 2.03.42 (changelog)
    • The static lvm and dmsetup the module installs on the nodes now come from the LVM2 2.03.42 release. The previous build pinned a revision but never checked it out, so nodes got an unreleased snapshot of the LVM2 main branch.

v0.8.0

Release date: 2026-09-24

The module’s files on the node move from /opt/deckhouse/sds to /var/lib/deckhouse/sds, the agent stops reading LVM from virtual machine disks, and thin snapshots no longer depend on the dm_snapshot kernel module.

Highlights

Changes in this release:

  • The module’s node tree moves to /var/lib/deckhouse/sds, which stays writable on nodes whose /opt is read-only, and the fileDevicesDirectory default becomes /var/lib/deckhouse/sds/file-devices. Existing spec.fileDevices entries under the old directory keep working where they are.
  • On a node that runs virtual machines, the Volume Groups a nested cluster builds on its disks no longer turn into LVMVolumeGroup and BlockDevice resources of the host cluster.
  • LVMLogicalVolumeSnapshot, restores from a VolumeSnapshot and clones of thin volumes work on nodes without the dm_snapshot kernel module.

Improvements

This release improves:

  • New metrics: sds_node_configurator_published_block_devices and sds_node_configurator_published_devices_directory_present show how many devices the agent keeps out of LVM on each node and whether it found kubelet’s directory of published block volumes there, and sds_node_configurator_legacy_file_devices_directory_lvgs counts the LVMVolumeGroup resources whose spec.fileDevices still name /opt/deckhouse/sds/file-devices; the module log lists their names.

Fixes

This release fixes:

  • On a node that runs virtual machines (DVP), the agent read LVM inside VM disks: a guest cluster’s Volume Groups appeared as LVMVolumeGroup resources and its disks as BlockDevice resources of the host cluster. The agent’s lvm commands now reject every device kubelet has published to a Pod as a block volume, with its partitions and whatever is stacked on it, for any CSI driver. Resources created this way before the update leave Ready and can be deleted; the Volume Group inside the VM is not touched.
  • A Volume Group tagged storage.deckhouse.io/lvmVolumeGroupName=<name> for an LVMVolumeGroup that does not exist in this cluster was imported as a new resource, although only the module in another cluster (for example, inside a virtual machine) writes that tag. It is no longer imported: the agent logs the refusal once and counts it in sds_node_configurator_lvm_volume_group_import_refused_total. A Volume Group handed over with storage.deckhouse.io/enabled=true and no name tag is imported as before, and so is a file-backed one.
  • Creating an LVMLogicalVolumeSnapshot, restoring from a VolumeSnapshot and cloning a thin LVMLogicalVolume failed on nodes without the dm_snapshot kernel module loaded, with snapshot: Required device-mapper target(s) not detected in your kernel. Thin snapshots are now created without that module. The agent still loads dm_snapshot on every node with thin provisioning, and a node where it is missing no longer keeps the agent from starting.
  • The bundled lvm could not load a missing device-mapper kernel module by itself and reported the target as not detected instead. It now calls the node’s /sbin/modprobe.

Breaking changes

Changes that affect backward compatibility:

  • The module no longer installs lvm and dmsetup under /opt/deckhouse/sds/bin, and removes the old copies from nodes. Scripts outside the module that run them from there have to use /var/lib/deckhouse/sds/bin/.

Upgrade notes

Before upgrading, note the following:

  • Nothing has to be done by hand. Once the agent Pod has restarted on a node, the next bashible run removes the files the module used to install under /opt/deckhouse/sds; files of other modules and backing files there are left in place. Scripts that ran /opt/deckhouse/sds/bin/lvm or dmsetup have to switch to /var/lib/deckhouse/sds/bin/.
  • spec.fileDevices[].directory is immutable, so entries created with the old default /opt/deckhouse/sds/file-devices keep naming it, and the agent keeps accepting it. Do not move their backing files by hand; the FAQ describes how to move an entry to the new directory online. Create new entries under the new default. A fileDevicesDirectory set explicitly in the module config is kept as is.

Docs

Documentation changes:

  • FAQ: a section on backing files created before the base directory moved, with a procedure that moves an entry to the new directory using pvmove.

v0.7.5

Release date: 2026-09-14

The scheduler extender now runs on the control-plane nodes, next to the kube-scheduler that consults it.

Highlights

Changes in this release:

  • The sds-common-scheduler-extender Pod is placed on control-plane nodes instead of system ones, and tolerates their taints.

Fixes

This release fixes:

  • The sds-common-scheduler-extender Deployment asked for system nodes and carried the system tolerations, which tolerate neither the control-plane taint nor custom ones, so the Pod could not be placed on a control-plane node. It now selects master nodes — falling back to system nodes in clusters that expose no master role — and tolerates any node, which puts it next to the kube-scheduler that calls it on every scheduling attempt of the modules that register it.

v0.7.4

Release date: 2026-09-11

Controller and scheduler extender metrics are now published through a kube-rbac-proxy, and percent-sized LVMLogicalVolumes are no longer rejected or left in Failed once they reach their requested size.

Highlights

Changes in this release:

  • The /metrics endpoints of the controller and the scheduler extender are no longer reachable without authentication: both bind on 127.0.0.1 and a kube-rbac-proxy publishes them, so a scrape needs get on deployments/prometheus-metrics.
  • A percent-sized LVMLogicalVolume — 100%FREE of a whole volume group, the shape sds-elastic uses for one OSD per disk — is no longer refused at creation and no longer parked in Failed with unable to extend LV, err: not enough space.
  • An LVM scan that reaches a multipath map with no remaining paths no longer blocks the agent, so the node keeps reporting its block devices and its RWO volumes can move to another node.

Improvements

This release improves:

  • Metrics of the scheduler extender are collected for the first time: the manager had always bound the port, but nothing declared or scraped it.
  • utils_commands_execution_count_total and utils_commands_errors_count_total are exported at last. Both were incremented in about forty places in the agent and the controller but never registered, so nothing they counted was visible.
  • All binaries of the module log through one shared logger. The name of the component that emitted a record is now a field of the record (logger) rather than a bracketed prefix inside the message text.

Fixes

This release fixes:

  • LVMLogicalVolume with a percentage in spec.size is computed against a capacity LVM reports as the raw device sum, which is not extent-aligned. Rounding the request up landed one extent past that capacity, so a request for 100% of a volume group was judged not to fit into it: creation was refused, and the extender put an already full-size volume into Failed. Percent sizes are now floored to the extent boundary.
  • An LVMLogicalVolume that had been marked Failed because the group’s free space still lagged behind the just-created LV stayed Failed for the rest of its life, since later passes returned early on a volume that was already at its requested size. Such a volume now moves to Created.
  • The agent could report block device size is invalid for a healthy device: the ioctl output variable lived on the stack and a stack growth during the call moved it, so the size was written to the old address and stayed zero.
  • An LVM scan that reached a multipath map whose paths were all gone blocked in the kernel instead of failing, and every stuck scan held the map open. That stalled the agent, kept multipath -f from removing the map, and left the volume in Node.status.volumesInUse, so it could not be attached elsewhere. Such maps — a mpath- device-mapper UUID with no slaves — are now rejected in the global_filter of every LVM command.

Security updates

Security updates in this release:

  • Anonymous access to the controller and scheduler extender metrics is closed. Previously the endpoints authenticated no one, were reachable from every pod in the cluster, and the ServiceMonitor sent the Prometheus ServiceAccount token to them over plain HTTP.
  • golang.org/x/crypto used by the module hooks is updated to 0.56.0, which closes CVE-2026-56854 (critical, authentication bypass in x/crypto/ssh), CVE-2026-56855 and CVE-2026-78662.

Upgrade notes

Before upgrading, note the following:

  • Nothing has to be done by hand for metrics: the ServiceMonitor shipped with the module already scrapes the proxy over HTTPS with a token. Only a collector of your own that used to read the controller metrics directly over HTTP has to be pointed at the proxy port and granted get on deployments/prometheus-metrics.
  • Log records changed shape, so a filter that matched the component name inside the message text has to match the logger field instead.

v0.7.3

  • Added the Missing condition to BlockDevice: a missing but still occupied device (e.g., part of an LVM Physical Volume) no longer remains forever with a stale status.path. It is first set to Unknown; True is set only if the device is continuously absent for 10 minutes, so a flapping iSCSI path that recovers on its own is not marked. The condition is cleared as soon as the device is found again; the object itself is not deleted to avoid breaking references from LVMVolumeGroup and LVMLogicalVolume
  • Fix: the agent no longer crashes on a cached logical volume without LVM attributes
  • Fix: VPA ceilings for the agent, scheduler-extender, and controller are raised to match measured consumption
  • Fix: the release image is no longer built from a cache with an outdated changelog.yaml — git-mapping dependencies are tied to the install stage where the file is copied
  • Updated base images to v2.1.3 and lib-helm to 1.72.14
  • Documentation: described virtual disk serial numbers
  • Internal build changes for the module

v0.7.2

  • Bugfix: the controller is granted permission to write events (create and patch) - previously the event write was denied by RBAC
  • CVE fixes
  • Internal build changes: CI updated, crds, docs and openapi are shipped in the release image

v0.7.1

  • Correction: one “orphaned” device-mapper device without a disk no longer stops BlockDevice detection on the entire node - previously, because of it, the agent did not create a single BlockDevice on the node, including healthy disks
  • Correction: LVMVolumeGroup with a single PV whose name could not be determined immediately no longer hangs in Pending forever - empty status.nodes post and no retry in the absence of udev events have been fixed
  • Correction: the agent substitutes the serial number inherited from the parent device if direct reading of the serial number fails (multipath participants, crypt/dm devices) - previously such devices were skipped when detecting BlockDevice
  • Optional resources (VerticalPodAutoscaler, PodMonitor/ServiceMonitor) are now enabled based on the presence of a CRD in the API, and not based on the enabledModules list
  • Documentation: fixed duplication of the description key in the Russian CRD LVMVolumeGroup, which broke docs-builder, added the missing status.extentSize description and restored the blockDevice description

v0.7.0

  • Correction: the agent no longer accepts LVM structures inside block devices given to virtual machines as its own - the /dev/loop exception was returned in the LVM global_filter. Fixed the resulting LVMVolumeGroup failures with CacheEmpty and ScanFailed causes - the VG name is no longer considered an identifier, and the LVM warning about a duplicate of someone else’s name is not attributed to our group
  • Added support for LVM on files: spec.fileDevices field of LVMVolumeGroup and LVMVolumeGroupSet. The agent creates a file, connects it as a loop device and uses it as a PV, which gives LVM storage on a node without a free disk; the blockDeviceSelector field has become optional
  • The scheduler (scheduler-extender) takes into account the PVCs listed in the extra-pvcs pod annotation
  • LVMLogicalVolume, LVMLogicalVolumeSnapshot and LVMVolumeGroupSet publish status.conditions; BlockDevice now has a Consumable condition, explaining why the device cannot be used; processing of LVMVolumeGroup conditions has been brought to a general form
  • Correction: a volume created from a snapshot or clone is expanded to the requested size - previously the PVC remained in Pending waiting for a size that never appeared
  • Correction: thin pool set by percentage of VG size no longer gets stuck at VGConfigurationApplied=False due to LVM rounding by one extent
  • Correction: an idle call to lvextend is recognized as harmless on LVM 2.03.16 - otherwise LVMVolumeGroup remained in NotReady
  • Correction: when taking control of an existing VG, blockDeviceSelector no longer remains empty
  • Correction: after pvcreate and vgcreate the agent calls udevadm to update the udev database
  • Correction: when storage-foundation is enabled, the agent loads the dm_snapshot kernel module
  • Removed outdated CRD LvmVolumeGroupBackup, left over from a one-time migration: the new hook removes finalizers from leftovers and removes the CRD itself
  • Added an experimental mode for detecting block devices via netlink, enabled by the ENABLE_NETLINK_BLOCK_DEVICE_DISCOVERY flag
  • Updating base images to v1.3.25, Go 1.26.5 and lib-helm to 1.72.13
  • Fixed vulnerabilities in golang.org/x/net, golang.org/x/sys and golang.org/x/crypto
  • Internal changes in module assembly and CI, the set of e2e tests has been significantly expanded

v0.6.10

  • The general accept rule was removed from LVM global_filter, which led to scanning of non-standard paths (/dev/disk/by-diskseq/*) and duplication of VG names

v0.6.9

  • The agent now ignores “foreign” block devices (rbd, drbd, nbd, loop) when scanning LVM
  • Fixed handling of duplicate VG names: LVMVolumeGroup status is no longer corrupted
  • The blocking of the agent pod launch has been eliminated; added timeouts for LVM commands
  • Improved stability of legacy block device names: matching by serial number or WWN prevents re-creation when name changes
  • Fixed BlockDevice selector validation: the In operator is now the only valid one

v0.6.8

  • Fixed race in scheduler-extender when PVC.Status.Phase is empty: PVC binding decision is now made based on Spec.VolumeName, nodes without a suitable LVMVolumeGroup are always rejected
  • Agent is now also scheduled on sds-elastic data nodes
  • Updating base images and lib-helm to 1.72.0

v0.6.7

  • Update base images, Go 1.25.10 and lib-helm 1.71.12
  • Internal changes in module structure and assembly

v0.6.6

  • Internal changes in module structure and assembly

v0.6.5

  • Update base images, Go 1.25.10 and lib-helm 1.71.11
  • Internal changes to the module assembly

v0.6.4

  • Corrections to the module structure

v0.6.3

  • scheduler-extender: PVCs with a missing StorageClass no longer block pod scheduling

v0.6.2

  • CI changes: DistroPackagesProxy and env proxy in werf, improvements to CVE scans (role_name, checkout)
  • Added user-authz cluster roles in templates

v0.6.1

  • Added detection of mount points via the mountinfo parser in the agent
  • Added locality of replicas to scheduler-extender for replicated volumes
  • Fixed reconciliation races and loops in LVG/LLV controllers
  • ExtentSize was taken into account when comparing in discoverer and fallback 4Mi was added in the LLV controller
  • Removed false marking of LLV as Failed when actualSize > spec.size
  • Fixed double subtraction of Failed LLV from actualSize when calculating free space in scheduler-extender
  • Updating base images and lib-helm

v0.6.0

  • CVE fixes
  • Transition to a common scheduler for SDS
  • Replacing a fixed resize delta with automatic determination of the LVM partition size delta
  • Automatic activation of LVM partitions during volume operations

v0.5.16

  • Added a hook for clearing resources when the module is turned off
  • Removed the enableThinProvisioning setting, we assume that thin provisioning is always enabled
  • Module-sdk update for CVE fix, golang update

v0.5.15

  • Added metrics for LVM volumes
  • Module-sdk update for CVE fix
  • Refactoring manifests

v0.5.14

  • Updated base images and lib-helm versions
  • Set default value for enableThinProvisioning to true
  • Docs improvements
  • Fixed templates security context
  • Added support for HA mode

v0.5.13

  • Updated base images versions

v0.5.12

  • Updated Go version to 1.24.9
  • Updated lib-helm to deckhouse_lib_helm-1.64.1
  • Documentation updates

v0.5.11

  • Fixed volume cleanup for thin volumes in some OSes

v0.5.10

  • Removed obsolete python requirements

v0.5.9

  • Fixed bug with unactivation of logical volumes

v0.5.8

  • Added release notes

v0.5.7

  • Fix sys-fs-cgroup error for containerdv2 support

v0.5.6

  • Added additional mounts for containerd v2 support

v0.5.5

  • CVE fixes

v0.5.4

  • CVE fixes
  • Internal changes for containerd v2 support

v0.5.3

  • Fixed bug preventing LVG status updates when missed/notready nodes are present in the cluster

v0.5.2

  • Removed support for sds-drbd module
  • Added hiding of csi-scsi-generic devices

v0.5.1

  • Technical release, module refactoring

v0.5.0

  • Added ability to wipe data in enterprise versions
  • Multiple documentation fixes

v0.4.6

  • Technical release. Removed “Preview” status from documentation

v0.4.5

  • Numerous documentation fixes
  • Added LVMVolumeGroupSet and LVMLogicalVolumeSnapshots
  • Fixed work with labels and finalizers in some internal objects
  • Added dm_snapshot loading when needed

v0.4.3

  • Fixed crash of BlockDevices migration script when finalizers are missing on resources

v0.4.2

  • Fix for supporting BlockDevice serial numbers up to 63 characters long

v0.4.1

  • Fixed potential issue with missing labels in LvmVolumeGroup->LVMVolumeGroup migration hook
  • Added controller that tracks labels on BlockDevice resources for quick updates of LVMVolumeGroup resources

v0.4.0

  • LvmVolumeGroups resources will be migrated to LVMVolumeGroups
  • Exact BlockDevices lists in LVMVolumeGroups will be migrated to selectors
  • Multiple fixes in controllers and documentation

v0.3.2

  • Fix in sds-health-watcher-controller which could incorrectly handle the status of some nodes

v0.3.1

  • Updated golang to current 1.22.6 to close known vulnerabilities

v0.3.0

  • Added thin provisioning configuration in mc for automatic dm_thin_pool module loading
  • Images moved to distroless
  • Added labels to BlockDevices entity (for future use in BlockDevicesSelectors)
  • Multiple bug fixes and documentation improvements

v0.2.5

  • Added metrics and their collection in Prometheus, health check ports moved to correct ones

v0.2.4

  • Added auto-expansion for thin pools LVM volume groups and LVM logical volumes

v0.2.3

  • Added internal cache for performance improvement
  • Added health and readiness checks to controller
  • Improved resource display in cli
  • Now LVM volume groups are deleted when corresponding k8s resource is deleted, not when annotation is added
  • Added LVM volume group size specification in percentages
  • Added AllocationLimit support in LVM volume group
  • Added support for contiguous volumes in sds-local-volume

v0.2.1

  • Added multipath devices support

v0.2.0

  • Added LVMLogicalVolumeWatcher CRDs
  • Added more test cases
  • Added AreSizesEqualWithinDelta function
  • Fixed resize for thinPools
  • Added tests to LvmLogicalVolumeWatcher controller
  • Fixed naming in LVMLogicalVolume
  • Added node affinity
  • Enhanced LVMLogicalVolume handling with logging, size display, and event processing
  • Statically linked nsenter, lsblk and lvm utils
  • Fixed serial discovery by switching to dynamic lsblk
  • Rewrote bin-copier script in Golang
  • Moved lsblk and its libraries inside the agent image
  • Added age field
  • Implemented stderr filtering for LVM commands
  • Added bench-tests for LVMLogicalVolume controller
  • Changed size type from string to quantity
  • Added parallel reconciliation to lvm_logical_volume_watcher and VG size validation to lvm_volume_group_watcher