The module lifecycle stage: Preview
The module has requirements for installation
v0.3.16
Release date: 2026-09-14
The module now exposes metrics for the controller and the CSI driver, installs the iSCSI stack itself where a node’s repositories cannot provide it, and lets a StorageClass ask for an ext4 superuser reserve.
Highlights
Changes in this release:
- The controller and the CSI driver serve operation metrics, scraped through the kube-rbac-proxy of their own pod; a
PodMonitorfor each ships with the module. - Where a node’s package manager cannot install
open-iscsiandmultipath-tools, the module installs them from its owniscsi-toolsimage instead of leaving the node without an iSCSI stack. - The
storage.deckhouse.io/ext4-reserved-percentannotation on aSCSIStorageClasssets the share of an ext4 filesystem kept for the superuser.
New features
This release adds:
- The controller and the CSI driver record what they serve. The CSI driver publishes
csi_scsi_generic_csi_operations_totalandcsi_scsi_generic_csi_operation_duration_seconds; both the controller and the driver are scraped over TLS through the kube-rbac-proxy of their pod, and aPodMonitorfor each is part of the module. - Three ports carry those metrics on the node, all settable in the module values:
controllerMetricsPort(8080) for the controller,csiControllerMetricsPort(4266) andcsiNodeMetricsPort(4267) for the CSI controller and the CSI node. The CSI pods are hostNetwork, so the last two are node-level ports. - When a node’s package manager cannot install
open-iscsiandmultipath-tools, the module falls back to its owniscsi-toolspackage image: the payload is unpacked under/var/lib/deckhouse/sds/csi-scsi-genericand the daemons come up asd8-csi-scsi-generic-iscsid.serviceandd8-csi-scsi-generic-multipathd.service. A node that already has a stack of its own keeps it untouched, and an existing/etc/iscsi/initiatorname.iscsiis never rewritten, so a node keeps the IQN the array knows it by. - The
storage.deckhouse.io/ext4-reserved-percentannotation on aSCSIStorageClasssets the percentage of a volume kept for the superuser: a whole number from 0 to 50, still 0 by default. It applies only to volumes created after the annotation was set, is ignored with a warning in the node log forfsType: xfs, and an invalid value puts the SCSIStorageClass into theFailedphase with the reason instatus.reasoninstead of failing volume creation later. Changing the annotation makes the controller recreate the StorageClass, because theparametersof an existing one are immutable in Kubernetes; existing volumes and PVCs are not affected.
Improvements
This release improves:
- The controller and the CSI driver log through one logger on a single
LOG_LEVELscale, so the same value means the same verbosity in every component of the module. - The default
logLevelis nowINFOinstead ofDEBUG, which is what a cluster that never set it explicitly will get.
Fixes
This release fixes:
- A SCSI device identified by an EUI identifier (a WWID with the
6prefix) no longer panics the controller in the block device filter reconciler.
Upgrade notes
Before upgrading, note the following:
- Nothing has to be done by hand. A cluster that relied on the previous default verbosity should set
logLevel: DEBUGin the module configuration explicitly, because the default is nowINFO. - The CSI pods are hostNetwork and now bind ports 4266 and 4267 on every node they run on. Both are registered in the Deckhouse port reference; change them in the module values only if something else on the node already holds them.
v0.3.15
- libiscsi updated to 0.0.6 based on upstream 1.20.3: fixed remotely triggerable memory handling errors during data-in parsing, added CHAP-SHA1 support, iscsi-ls no longer truncates JSON if the target publishes an inaccessible portal
- Fix: the iscsi-command service (0.0.10) reads stdout of iscsi-ls separately from stderr, so a diagnostic line next to a correct listing no longer breaks JSON parsing; the child process terminates on request cancellation or timeout
- Removed the unused libiscsi artifact (source code, build tree, and shared libraries) from the controller image — its CVE surface area is also removed from the image
- 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
- Base images updated to v2.1.4
- Internal build changes for the module
v0.3.14
- Bugfix: the controller is granted patch on events instead of list - a repeated event write is no longer denied by RBAC
- Optional resources are enabled based on the presence of the CRD in the API, not on the list of enabled modules
- Base images updated to v2.1.2, Go to 1.26.6 and lib-helm to 1.72.14
v0.3.13
- Bugfix: targets are re-detected again - due to the TTL being extended on each read, the target was detected once during the life of the controller, and the LUN presented after the start was never picked up. The re-detection interval is included in a separate parameter TARGET_RESCAN_INTERVAL with a default value of 5 minutes
- SCSIStorageClass, SCSITarget and SCSIDevice publish status.conditions and status.observedGeneration, added Ready column
- SCSIDevice: custom condition type and status.aggregatedStatus field replaced with standard metav1.Condition, status.phase field is now calculated from conditions, Attached, Mounted and Error conditions are published
- Controller errors are no longer suppressed by a fixed retry after 3 seconds, but are returned to controller-runtime - this enables exponential delay of retries and accounting for errors in metrics
- Update base images to v1.3.25, Go 1.26.5 and lib-helm to 1.72.13
v0.3.12
- Fixed launching module components - the hostPath /sys/fs/cgroup mount, removed in v0.3.11 as redundant, has been returned and added to the module controller, where it was not there. Mounting is needed not by the driver, but by the container launch environment - when mounting the host /sys, the sysfs substitution for privileged containers is replaced, and the cgroup is mounted before /sys, in the directory of the distroless image (an image without a package environment), where /sys/fs is missing and cannot be created due to readOnlyRootFilesystem
- Fixed mounting of initiatorname.iscsi - instead of hostPath of type File, the /etc/iscsi directory is mounted. Previously, on a node with unconfigured open-iscsi under the controller, it remained forever in ContainerCreating, and the only diagnostic was the kubelet event; now the controller starts and reports the absence of the initiator name in its log
- Removed unnecessary mounting of /etc/iscsi into the iscsi-command-service container - the service receives the initiator name via gRPC and does not access the file, and the file was not readable by an unprivileged user
- Updated base images v1.3.21, Go 1.26.5 and lib-helm to 1.72.12
v0.3.11
- Fixed SCSIDevice status update - a device in Bound state no longer loses the list of SCSI targets if background scanning did not detect them (this reset the device size to zero, put it in Degraded and broke volume deletion)
- Fixed a race when connecting a device - the module waits for the appearance of the symlink /dev/disk/by-id/scsi-
, which udev creates asynchronously, instead of trying to read it once - Removed redundant hostPath /sys/fs/cgroup mounts from the CSI controller and CSI node containers - the driver does not work with cgroups, and the host /sys is already mounted entirely
- Fixed the GHSA-hrxh-6v49-42gf vulnerability in google.golang.org/grpc, updated the dependency to 1.82.1
- Update base images v1.3.10, Go 1.26.5 and lib-helm to 1.72.10
- Internal changes in module assembly
v0.3.10
- Update base images, Go 1.26.5 and lib-helm to 1.72.9
- Internal changes in module assembly
v0.3.9
- Fixed the formation of the registry access secret (deckhouse-registry): now it only includes authorization data for the active image source
- Added Fiber Channel configuration examples to the documentation
- Updating container-base images to v1.1.8, Go 1.26.4 and lib-helm to 1.72.4
v0.3.8
- When forwarding labels from SCSIStorageClass to StorageClass, labels with specified ignored prefixes are now excluded
- Update base images and lib-helm to 1.72.0
v0.3.7
- Labels from SCSIStorageClass are now forwarded to the managed StorageClass Kubernetes
- Update base images, Go 1.25.10 and lib-helm 1.71.12
v0.3.6
- Internal changes in the structure and assembly of the module
v0.3.5
- Update base images, Go 1.25.10 and lib-helm 1.71.11
- Internal changes to the module assembly
v0.3.4
- Changes in CI: DistroPackagesProxy and env proxy in werf, improvements to CVE scans (role_name, checkout)
- Added user-authz cluster roles in templates
v0.3.3
- Installing packages in NodeGroupConfiguration no longer causes the script to crash on errors
v0.3.2
- Added missing mount points in csi-scsi-generic distroless images
- Update base images, Go and lib-helm
- Translation of resource documentation
v0.3.1
- CVE fixes
v0.3.0
- Update base images and golang version for CVE fixes
- Refactoring of image assembly for transfer to distroless
v0.2.10
- Update base images and golang version
- Updated hooks that work when a module is removed
- Disabled Capacity request from k8s (CSI does not support issuing Capacity)
- Edits of module manifests and documentation
v0.2.9
- Updated base images versions
v0.2.8
- Updated Go version to 1.24.9
- Updated lib-helm to deckhouse_lib_helm-1.64.1
v0.2.7
- Updated Go version to 1.24.8
- Updated lib-helm to deckhouse_lib_helm-1.64.1
v0.2.6
- CVE fixes
v0.2.5
- Updated Go version to 1.24.8
- Updated lib-helm to deckhouse_lib_helm-1.63.6
v0.2.4
- Added release notes
v0.2.3
- Changes for containerd v2 support
v0.2.2
- Added readonlyRootFilesystem for enhanced module security
v0.2.1
- CVE fixes
v0.2.0
- Module refactoring
- Added HA mode support
- Added hiding of used devices from sds-node-configurator module
- Fixed bugs related to multipathd
- Extended documentation
v0.1.2
- Support for automatic filesystem resize when volume size changes (and semi-automatic volume expansion requests)
v0.1.1
- Multiple improvements and fixes in FibreChannel operations
v0.1.0
- Initial release, basic functionality is working